Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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; 
}
Пример #4
0
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);
   }
}
Пример #5
0
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);
    }
}
Пример #6
0
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
   }
}
Пример #7
0
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; 
}