int LoadProcessTable(struct Item **procdata,char *psopts) { FILE *pp; char pscomm[CF_MAXLINKSIZE], imgbackup; snprintf(pscomm, CF_MAXLINKSIZE, "%s %s", g_vpscomm[g_vsystemhardclass], psopts); Verbose("%s: Running process command %s\n",g_vprefix,pscomm); if ((pp = cfpopen(pscomm,"r")) == NULL) { snprintf(g_output,CF_BUFSIZE*2, "Couldn't open the process list with command %s\n",pscomm); CfLog(cferror,g_output,"popen"); return false; } while (!feof(pp)) { memset(g_vbuff,0,CF_BUFSIZE); ReadLine(g_vbuff,CF_BUFSIZE,pp); AppendItem(procdata,g_vbuff,""); } cfpclose(pp); snprintf(g_vbuff,CF_MAXVARSIZE,"%s/state/cfng_procs",WORKDIR); imgbackup = g_imagebackup; g_imagebackup = 'n'; SaveItemList(*procdata,g_vbuff,"none"); g_imagebackup = imgbackup; return true; }
static void * lsb_release(const char *command, const char *key) { char * info = NULL; FILE * fp; snprintf(VBUFF, CF_BUFSIZE, "%s %s", command, key); if ((fp = cfpopen(VBUFF, "r")) == NULL) { return NULL; } if (ReadLine(VBUFF, CF_BUFSIZE, fp)) { char * buffer = VBUFF; strsep(&buffer, ":"); while((*buffer != '\0') && isspace(*buffer)) { buffer++; } info = buffer; while((*buffer != '\0') && !isspace(*buffer)) { *buffer = tolower(*buffer++); } *buffer = '\0'; info = strdup(info); } cfpclose(fp); return info; }
void *LocalExec(void *scheduled_run) { FILE *pp; char line[CF_BUFSIZE],filename[CF_BUFSIZE],*sp; char cmd[CF_BUFSIZE]; int print, tid; time_t starttime = time(NULL); FILE *fp; #ifdef HAVE_PTHREAD_SIGMASK sigset_t sigmask; sigemptyset(&sigmask); pthread_sigmask(SIG_BLOCK,&sigmask,NULL); #endif #ifdef HAVE_PTHREAD tid = (int)pthread_self(); #endif Verbose("------------------------------------------------------------------\n\n"); Verbose(" LocalExec(%sscheduled) at %s\n", scheduled_run ? "" : "not ", ctime(&starttime)); Verbose("------------------------------------------------------------------\n"); /* Need to make sure we have LD_LIBRARY_PATH here or children will die */ snprintf(cmd,CF_BUFSIZE-1,"%s/bin/cfagent%s -Dfrom_cfexecd%s", CFWORKDIR, NOSPLAY ? " -q" : "", scheduled_run ? ":scheduled_run" : ""); timestamp(starttime, line, CF_BUFSIZE); snprintf(filename,CF_BUFSIZE-1,"%s/outputs/cf_%s_%s_%u",CFWORKDIR,CanonifyName(VFQNAME),line,time(NULL)); /* What if no more processes? Could sacrifice and exec() - but we need a sentinel */ if ((fp = fopen(filename,"w")) == NULL) { snprintf(OUTPUT,CF_BUFSIZE,"Couldn't open %s\n",filename); CfLog(cfinform,OUTPUT,"fopen"); return NULL; } if ((pp = cfpopen(cmd,"r")) == NULL) { snprintf(OUTPUT,CF_BUFSIZE,"Couldn't open pipe to command %s\n",cmd); CfLog(cfinform,OUTPUT,"cfpopen"); fclose(fp); return NULL; } while (!feof(pp) && ReadLine(line,CF_BUFSIZE,pp)) { if (ferror(pp)) { fflush(pp); break; } print = false; for (sp = line; *sp != '\0'; sp++) { if (! isspace((int)*sp)) { print = true; break; } } if (print) { fprintf(fp,"%s\n",line); /* If we can't send mail, log to syslog */ if (strlen(MAILTO) == 0) { strncat(line,"\n",CF_BUFSIZE-1-strlen(line)); if ((strchr(line,'\n')) == NULL) { line[CF_BUFSIZE-2] = '\n'; } CfLog(cfinform,line,""); } line[0] = '\0'; } } cfpclose(pp); Debug("Closing fp\n"); fclose(fp); MailResult(filename,MAILTO); return NULL; }
void GetCfStuff() { FILE *pp; char cfcom[CF_BUFSIZE]; static char line[CF_BUFSIZE]; /* Do not init variables here, in case we can use previous values. */ snprintf(cfcom,CF_BUFSIZE-1,"%s/bin/cfagent -Q smtpserver,sysadm,fqhost,host,domain,ipaddress,EmailMaxLines,EmailFrom,EmailTo -D from_cfexecd",CFWORKDIR); if ((pp=cfpopen(cfcom,"r")) == NULL) { CfLog(cfinform,"Couldn't start cfengine!","cfpopen"); line[0] = '\0'; return; } while (!feof(pp)) { char name[CF_BUFSIZE],content[CF_BUFSIZE]; line[0] = '\0'; fgets(line,CF_BUFSIZE,pp); Chop(line); sscanf(line,"%[^=]=%[^\n]",name,content); if (strcmp(name,"sysadm") == 0) { strncpy(MAILTO,content,CF_MAXVARSIZE-1); Debug("%s\n",line); continue; } if (strcmp(name,"smtpserver") == 0) { Debug("%s/%s\n",name,content); strncpy(VMAILSERVER,content,CF_MAXVARSIZE-1); continue; } if (strcmp(name,"fqhost") == 0) { Debug("%s/%s\n",name,content); strncpy(VFQNAME,content,CF_MAXVARSIZE-1); continue; } if (strcmp(name,"host") == 0) { Debug("%s/%s\n",name,content); strncpy(VUQNAME,content,CF_MAXVARSIZE-1); continue; } if (strcmp(name,"domain") == 0) { Debug("%s/%s\n",name,content); strncpy(VDOMAIN,content,CF_MAXVARSIZE-1); continue; } if (strcmp(name,"ipaddress") == 0) { Debug("%s/%s\n",name,content); strncpy(VIPADDRESS,content,17); continue; } if (strcmp(name,"EmailMaxLines") == 0) { Debug("%s/%s\n",name,content); MAXLINES = 100; if (strcmp(content,"inf") == 0) { MAXLINES = -2; Debug("EmailMaxLines set to infinity\n"); } else { sscanf(content,"%d",&MAXLINES); } continue; } if (strcmp(name,"EmailFrom") == 0) { Debug("%s/%s\n",name,content); if (strstr(content,"$") == NULL && strlen(content) > 0) { strncpy(MAILFROM,content,CF_MAXVARSIZE-1); continue; } } if (strcmp(name,"EmailTo") == 0) { Debug("%s/%s\n",name,content); if (strstr(content,"$") == NULL && strlen(content) > 0) { strncpy(MAILTO,content,CF_MAXVARSIZE-1); continue; } } } cfpclose(pp); Debug("Got(to:%s,serv:%s,fqhost:%s,host:%s,domain:%s,ip:%s,max:%d,from:%s)\n",MAILTO,VMAILSERVER,VFQNAME,VUQNAME,VDOMAIN,VIPADDRESS,MAXLINES,MAILFROM); /* Now get schedule */ snprintf(cfcom,CF_BUFSIZE-1,"%s/bin/cfagent -z -D from_cfexecd",CFWORKDIR); if ((pp=cfpopen(cfcom,"r")) == NULL) { CfLog(cfinform,"Couldn't start cfengine!","cfpopen"); line[0] = '\0'; return; } DeleteItemList(SCHEDULE); SCHEDULE = NULL; while (!feof(pp)) { line[0] = '\0'; VBUFF[0] = '\0'; fgets(line,CF_BUFSIZE,pp); sscanf(line,"[%[^]]",VBUFF); if (strlen(VBUFF)==0) { continue; } if (!IsItemIn(SCHEDULE,VBUFF)) { AppendItem(&SCHEDULE,VBUFF,NULL); } } cfpclose(pp); if (SCHEDULE == NULL) { Verbose("No schedule defined in cfagent.conf, defaulting to Min00_05\n"); AppendItem(&SCHEDULE,"Min00_05",NULL); } }
void DoProcessCheck(struct Process *pp,struct Item *procdata) { char line[CF_BUFSIZE]; int matches=0,dosignals=true; mode_t maskval; struct stat statbuf; struct Item *killlist = NULL; matches = FindMatches(pp,procdata,&killlist); if (matches > 0) { Verbose("Defining classes %s\n",pp->defines); AddMultipleClasses(pp->defines); } else { Verbose("Defining classes %s\n",pp->elsedef); AddMultipleClasses(pp->elsedef); } if (pp->matches >= 0) { if (pp->action == 'm') { dosignals = false; } switch (pp->comp) { case '=': if (matches != (int)pp->matches) { snprintf(g_output,CF_BUFSIZE*2, "%d processes matched %s (should be %d)\n", matches,pp->expr,pp->matches); CfLog(cferror,g_output,""); if (pp->action == 'm') { dosignals = true; } } break; case '>': if (matches < (int)pp->matches) { snprintf(g_output,CF_BUFSIZE*2, "%d processes matched %s (should be >=%d)\n", matches,pp->expr,pp->matches); CfLog(cferror,g_output,""); if (pp->action == 'm') { dosignals = true; } } break; case '<': if (matches > (int)pp->matches) { snprintf(g_output,CF_BUFSIZE*2, "%d processes matched %s (should be <=%d)\n", matches,pp->expr,pp->matches); CfLog(cferror,g_output,""); if (pp->action == 'm') { dosignals = true; } } } } if (dosignals) { DoSignals(pp,killlist); } DeleteItemList(killlist); if ((pp->action == 'm') && !dosignals && (matches != 0)) { Verbose("%s: Process matches found for %s - no restart necessary\n", g_vprefix,pp->expr); return; } if (strlen(pp->restart) != 0) { char argz[256]; Verbose("Existing restart sequence found (%s)\n",pp->restart); if ((matches != 0) && (pp->signal != cfkill) && (pp->signal != cfterm)) { Verbose("%s: Process matches found for %s - " "no restart necessary\n", g_vprefix,pp->expr); return; } sscanf(pp->restart,"%255s",argz); if ((stat(argz,&statbuf) != -1) && (statbuf.st_mode & 0111 == 0)) { snprintf(g_output, CF_BUFSIZE, "Restart sequence %s could not be executed " "(mode=%o), while searching (%s)", pp->restart, statbuf.st_mode & 7777, pp->expr); CfLog(cferror,g_output,""); return; } snprintf(g_output, CF_BUFSIZE*2, "Executing shell command: %s\n", pp->restart); CfLog(cfinform,g_output,""); if (g_dontdo) { return; } Verbose ("(Setting umask to %o)\n",pp->umask); maskval = umask(pp->umask); if (pp->umask == 0) { snprintf(g_output,CF_BUFSIZE*2, "Programming %s running with umask 0! Use umask= to set\n", pp->restart); CfLog(cfsilent,g_output,""); } if (pp->useshell == 'y') { if ((PIPE = cfpopen_shsetuid(pp->restart,"r", pp->uid,pp->gid,pp->chdir,pp->chroot)) == NULL) { snprintf(g_output,CF_BUFSIZE*2, "Process restart execution failed on %s\n",pp->restart); CfLog(cferror,g_output,"popen"); return; } } else { if ((PIPE = cfpopensetuid(pp->restart,"r",pp->uid,pp->gid, pp->chdir,pp->chroot)) == NULL) { snprintf(g_output,CF_BUFSIZE*2, "Process restart execution failed on %s\n",pp->restart); CfLog(cferror,g_output,"popen"); return; } } DEADLOCK = false; while (!feof(PIPE)) { /* dumb shell */ if (pp->useshell == 'd') { fgets(line,1,PIPE); break; } ReadLine(line,CF_BUFSIZE,PIPE); if (feof(PIPE) || ferror(PIPE)) { break; } if (strstr(line,"cfengine-die")) { break; } /* patch for ERESTARTSYSTEM bug in popen */ if (strstr(line,"cfd: start") || DEADLOCK) { break; } snprintf(g_output,CF_BUFSIZE*2,"Restart: %s",line); CfLog(cfinform,g_output,""); } if (pp->useshell == 'y') { pclose(PIPE); } else { cfpclose(PIPE); } snprintf(g_output,CF_BUFSIZE*2,"(Done with %s)\n",pp->restart); CfLog(cfinform,g_output,""); umask(maskval); } }
void SetDefaultRoute() { int sk, defaultokay = 1; struct sockaddr_in sindst,singw; char oldroute[INET_ADDRSTRLEN]; char routefmt[CF_MAXVARSIZE]; /* These OSes have these structs defined but use the route command */ # if defined DARWIN || defined FREEBSD || defined OPENBSD || defined SOLARIS # undef HAVE_RTENTRY # undef HAVE_ORTENTRY # endif # ifdef HAVE_ORTENTRY struct ortentry route; # else # if HAVE_RTENTRY struct rtentry route; # endif # endif FILE *pp; Verbose("Looking for a default route...\n"); if (!IsPrivileged()) { snprintf(OUTPUT,CF_BUFSIZE*2,"Only root can set a default route."); CfLog(cfinform,OUTPUT,""); return; } if (VDEFAULTROUTE == NULL) { Verbose("cfengine: No default route is defined. Ignoring the routing tables.\n"); return; } if ((pp = cfpopen(VNETSTAT[VSYSTEMHARDCLASS],"r")) == NULL) { snprintf(OUTPUT,CF_BUFSIZE*2,"Failed to open pipe from %s\n",VNETSTAT[VSYSTEMHARDCLASS]); CfLog(cferror,OUTPUT,"popen"); return; } while (!feof(pp)) { ReadLine(VBUFF,CF_BUFSIZE,pp); Debug("LINE: %s = %s?\n",VBUFF,VDEFAULTROUTE->name); if ((strncmp(VBUFF,"default",7) == 0)||(strncmp(VBUFF,"0.0.0.0",7) == 0)) { /* extract the default route */ /* format: default|0.0.0.0 <whitespace> route <whitespace> etc */ if ((sscanf(VBUFF, "%*[default0. ]%s%*[ ]", &oldroute)) == 1) { if ((strncmp(VDEFAULTROUTE->name, oldroute, INET_ADDRSTRLEN)) == 0) { Verbose("cfengine: default route is already set to %s\n",VDEFAULTROUTE->name); defaultokay = 1; break; } else { Verbose("cfengine: default route is set to %s, but should be %s.\n",oldroute,VDEFAULTROUTE->name); defaultokay = 2; break; } } } else { Debug("No default route is yet registered\n"); defaultokay = 0; } } cfpclose(pp); if (defaultokay == 1) { Verbose("Default route is set and agrees with conditional policy\n"); return; } if (defaultokay == 0) { AddMultipleClasses("no_default_route"); } if (IsExcluded(VDEFAULTROUTE->classes)) { Verbose("cfengine: No default route is applicable. Ignoring the routing tables.\n"); return; } CfLog(cferror,"The default route is incorrect, trying to correct\n",""); if ( strcmp(VROUTE[VSYSTEMHARDCLASS], "-") != 0 ) { Debug ("Using route shell commands to set default route\n"); if (defaultokay == 2) { if (! DONTDO) { /* get the route command and the format for the delete argument */ snprintf(routefmt,CF_MAXVARSIZE,"%s %s",VROUTE[VSYSTEMHARDCLASS],VROUTEDELFMT[VSYSTEMHARDCLASS]); snprintf(VBUFF,CF_MAXVARSIZE,routefmt,"default",VDEFAULTROUTE->name); if (ShellCommandReturnsZero(VBUFF,false)) { CfLog(cfinform,"Removing old default route",""); CfLog(cfinform,VBUFF,""); } else { CfLog(cferror,"Error removing route",""); } } } if (! DONTDO) { snprintf(routefmt,CF_MAXVARSIZE,"%s %s",VROUTE[VSYSTEMHARDCLASS],VROUTEADDFMT[VSYSTEMHARDCLASS]); snprintf(VBUFF,CF_MAXVARSIZE,routefmt,"default",VDEFAULTROUTE->name); if (ShellCommandReturnsZero(VBUFF,false)) { CfLog(cfinform,"Setting default route",""); CfLog(cfinform,VBUFF,""); } else { CfLog(cferror,"Error setting route",""); } } return; } else { #if defined HAVE_RTENTRY || defined HAVE_ORTENTRY Debug ("Using route ioctl to set default route\n"); if ((sk = socket(AF_INET,SOCK_RAW,0)) == -1) { CfLog(cferror,"System class: ", CLASSTEXT[VSYSTEMHARDCLASS]); CfLog(cferror,"","Error in SetDefaultRoute():"); perror("cfengine: socket"); } else { sindst.sin_family = AF_INET; singw.sin_family = AF_INET; sindst.sin_addr.s_addr = INADDR_ANY; singw.sin_addr.s_addr = inet_addr(VDEFAULTROUTE->name); route.rt_dst = *(struct sockaddr *)&sindst; /* This disgusting method is necessary */ route.rt_gateway = *(struct sockaddr *)&singw; route.rt_flags = RTF_GATEWAY; if (! DONTDO) { if (ioctl(sk,SIOCADDRT, (caddr_t) &route) == -1) /* Get the device status flags */ { CfLog(cferror,"Error setting route:",""); perror("cfengine: ioctl SIOCADDRT:"); } else { CfLog(cferror,"Setting default route.\n",""); snprintf(OUTPUT,CF_BUFSIZE*2,"I'm setting it to %s\n",VDEFAULTROUTE->name); CfLog(cferror,OUTPUT,""); } } } #else /* Socket routing - don't really know how to do this yet */ Verbose("Sorry don't know how to do routing on this platform\n"); #endif } }
int CheckForModule(char *actiontxt,char *args) { struct stat statbuf; char line[CF_BUFSIZE],command[CF_EXPANDSIZE],name[CF_MAXVARSIZE],content[CF_BUFSIZE],ebuff[CF_EXPANDSIZE],*sp; FILE *pp; int print; if (NOMODULES) { return false; } if (*actiontxt == '/') { snprintf(OUTPUT,CF_BUFSIZE,"Absolute module path (%s) should be named relative to the authorized module directory",actiontxt); CfLog(cferror,OUTPUT,""); } if (GetMacroValue(CONTEXTID,"moduledirectory")) { ExpandVarstring("$(moduledirectory)",ebuff,NULL); } else { snprintf(ebuff,CF_BUFSIZE,"%s/modules",VLOCKDIR); } AddSlash(ebuff); strcat(ebuff,actiontxt); if (stat(ebuff,&statbuf) == -1) { snprintf(OUTPUT,CF_BUFSIZE*2,"(Plug-in %s not found)",ebuff); Banner(OUTPUT); return false; } if ((statbuf.st_uid != 0) && (statbuf.st_uid != getuid())) { snprintf(OUTPUT,CF_BUFSIZE*2,"Module %s was not owned by uid=%d executing cfagent\n",ebuff,getuid()); CfLog(cferror,OUTPUT,""); return false; } snprintf(OUTPUT,CF_BUFSIZE*2,"Plug-in `%s\'",actiontxt); Banner(OUTPUT); strcat(ebuff," "); if (BufferOverflow(ebuff,args)) { snprintf(OUTPUT,CF_BUFSIZE*2,"Culprit: class list for module (shouldn't happen)\n" ); CfLog(cferror,OUTPUT,""); return false; } strcat(ebuff,args); ExpandVarstring(ebuff,command,NULL); Verbose("Exec module [%s]\n",command); if ((pp = cfpopen(command,"r")) == NULL) { snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't open pipe from %s\n",actiontxt); CfLog(cferror,OUTPUT,"cfpopen"); return false; } while (!feof(pp)) { if (ferror(pp)) /* abortable */ { snprintf(OUTPUT,CF_BUFSIZE*2,"Shell command pipe %s\n",actiontxt); CfLog(cferror,OUTPUT,"ferror"); break; } ReadLine(line,CF_BUFSIZE,pp); if (strlen(line) > CF_BUFSIZE - 80) { snprintf(OUTPUT,CF_BUFSIZE*2,"Line from module %s is too long to be sensible\n",actiontxt); CfLog(cferror,OUTPUT,""); break; } if (ferror(pp)) /* abortable */ { snprintf(OUTPUT,CF_BUFSIZE*2,"Shell command pipe %s\n",actiontxt); CfLog(cferror,OUTPUT,"ferror"); break; } print = false; for (sp = line; *sp != '\0'; sp++) { if (! isspace((int)*sp)) { print = true; break; } } switch (*line) { case '+': Verbose("Activated classes: %s\n",line+1); CheckClass(line+1,command); AddMultipleClasses(line+1); break; case '-': Verbose("Deactivated classes: %s\n",line+1); CheckClass(line+1,command); NegateCompoundClass(line+1,&VNEGHEAP); break; case '=': content[0] = '\0'; sscanf(line+1,"%[^=]=%[^\n]",name,content); Verbose("Defined Macro: %s, Value: %s\n",name,content); AddMacroValue(CONTEXTID,name,content); break; default: if (print) { snprintf(OUTPUT,CF_BUFSIZE,"%s: %s\n",actiontxt,line); CfLog(cferror,OUTPUT,""); } } } cfpclose(pp); return true; }