"Warning: Could not get group entry for '%s'\n",group);
}
}
/* else we were passed the GID */
else{
gid=(gid_t)atoi(group);
}
/* set effective group ID if other than current EGID */
if(gid!=getegid()){
if(setgid(gid)==-1){
fprintf(stderr,"Warning: Could not set effective GID=%d\n",
(int)gid);
result=PW_ERROR;
}
}
}
/* set effective user ID */
if(NULL!=user){
/* see if this is a user name */
if(strspn(user,"0123456789")<strlen(user)){
pw=(structpasswd*)getpwnam(user);
if(NULL!=pw){
uid=(uid_t)(pw->pw_uid);
}
else{
fprintf(stderr,
"Warning: Could not get passwd entry for '%s'\n",user);
}
}
/* else we were passed the UID */
else{
uid=(uid_t)atoi(user);
}
#ifdef HAVE_INITGROUPS
if(uid!=geteuid()){
/* initialize supplementary groups */
if(initgroups(user,gid)==-1){
if(EPERM==errno){
fprintf(stderr,"Warning: Unable to change supplementary "
"groups using initgroups() -- I hope you know what "
"you're doing\n");
}
else{
fprintf(stderr,"Warning: Possibly root user failed "
"dropping privileges with initgroups()\n");
returnPW_ERROR;
}
}
}
#endif
if(setuid(uid)==-1){
fprintf(stderr,"Warning: Could not set effective UID=%d\n",
(int)uid);
result=PW_ERROR;
}
}
returnresult;
}
intdaemon_init(void){
pid_tpid=-1;
intpidno=0;
intlockfile=0;
intval=0;
charbuf[256];
structflocklock;
char*homedir=NULL;
#ifdef RLIMIT_CORE
structrlimitlimit;
#endif
/* change working directory. scuttle home if we're dumping core */
homedir=getenv("HOME");
#ifdef DAEMON_DUMPS_CORE
if(NULL!=homedir){
chdir(homedir);
}
else{
#endif
chdir("/");
#ifdef DAEMON_DUMPS_CORE
}
#endif
umask(S_IWGRP|S_IWOTH);
/* close existing stdin, stdout, stderr */
close(0);
close(1);
close(2);
/* THIS HAS TO BE DONE TO AVOID PROBLEMS WITH STDERR BEING REDIRECTED TO SERVICE MESSAGE PIPE! */
/* re-open stdin, stdout, stderr with known values */
open("/dev/null",O_RDONLY);
open("/dev/null",O_WRONLY);
open("/dev/null",O_WRONLY);
#ifdef USE_LOCKFILE
lockfile=open(lock_file,
O_RDWR|O_CREAT,S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH);
if(lockfile<0){
logit(NSLOG_RUNTIME_ERROR,TRUE,"Failed to obtain lock on file %s: %s\n",lock_file,strerror(errno));
logit(NSLOG_PROCESS_INFO|NSLOG_RUNTIME_ERROR,TRUE,"Bailing out due to errors encountered while attempting to daemonize... (PID=%d)",(int)getpid());
exit(1);
}
/* see if we can read the contents of the lockfile */
if((val=read(lockfile,buf,(size_t)10))<0){
logit(NSLOG_RUNTIME_ERROR,TRUE,"Lockfile exists but cannot be read");
exit(1);
}
/* we read something - check the PID */
if(val>0){
if((val=sscanf(buf,"%d",&pidno))<1){
logit(NSLOG_RUNTIME_ERROR,TRUE,"Lockfile '%s' does not contain a valid PID (%s)",lock_file,buf);
exit(1);
}
}
/* check for SIGHUP */
if(val==1&&(pid=(pid_t)pidno)==getpid()){
close(lockfile);
returnOK;
}
#endif
/* exit on errors... */
if((pid=fork())<0){
return(PW_ERROR);
}
/* parent process goes away.. */
elseif((int)pid!=0){
exit(0);
}
/* child continues... */
/* child becomes session leader... */
setsid();
#ifdef USE_LOCKFILE
/* place a file lock on the lock file */
lock.l_type=F_WRLCK;
lock.l_start=0;
lock.l_whence=SEEK_SET;
lock.l_len=0;
if(fcntl(lockfile,F_SETLK,&lock)<0){
if(EACCES==errno||EAGAIN==errno){
fcntl(lockfile,F_GETLK,&lock);
logit(NSLOG_RUNTIME_ERROR,TRUE,"Lockfile '%s' looks like its already held by another instance of Nagios (PID %d). Bailing out...",lock_file,(int)lock.l_pid);