Esempio n. 1
0
static void DeleteAllClasses(EvalContext *ctx, const Rlist *list)
{
    for (const Rlist *rp = list; rp != NULL; rp = rp->next)
    {
        if (CheckParseContext((char *) rp->item, CF_IDRANGE) != SYNTAX_TYPE_MATCH_OK)
        {
            return; // TODO: interesting course of action, but why is the check there in the first place?
        }

        if (EvalContextHeapContainsHard(ctx, (char *) rp->item))
        {
            Log(LOG_LEVEL_ERR, "You cannot cancel a reserved hard class '%s' in post-condition classes",
                  RlistScalarValue(rp));
        }

        const char *string = (char *) (rp->item);

        Log(LOG_LEVEL_VERBOSE, "Cancelling class '%s'", string);

        EvalContextHeapPersistentRemove(string);

        EvalContextHeapRemoveSoft(ctx, CanonifyName(string));

        EvalContextStackFrameAddNegated(ctx, CanonifyName(string));
    }
}
Esempio n. 2
0
static time_t ReadPolicyValidatedFileMTime(const GenericAgentConfig *config)
{
    char filename[CF_MAXVARSIZE];

    if (MINUSF)
    {
        snprintf(filename, CF_MAXVARSIZE, "%s/state/validated_%s", CFWORKDIR, CanonifyName(config->original_input_file));
        MapName(filename);
    }
    else
    {
        snprintf(filename, CF_MAXVARSIZE, "%s/masterfiles/cf_promises_validated", CFWORKDIR);
        MapName(filename);
    }

    struct stat sb;
    if (stat(filename, &sb) != -1)
    {
        return sb.st_mtime;
    }
    else
    {
        return 0;
    }
}
Esempio n. 3
0
void
AddNetworkClass(char *netmask)
{
    struct in_addr ip,nm;
    char *sp;
    char nmbuf[CF_MAXVARSIZE], ipbuf[CF_MAXVARSIZE];

    /*
     * Has to differentiate between cases such as:
     *      192.168.101.1/24 -> 192.168.101   and
     *      192.168.101.1/26 -> 192.168.101.0
     * We still have the, um... 'interesting' Class C default Network Class
     * set by GetNameInfo()
     */

    /* This is also a convenient method to ensure valid dotted quad */
    if ((nm.s_addr = inet_addr(netmask)) != -1 &&
            (ip.s_addr = inet_addr(g_vipaddress)) != -1) {

        /* Will not work with IPv6 */
        ip.s_addr &= nm.s_addr;
        strcpy(ipbuf,inet_ntoa(ip));

        strcpy(nmbuf, inet_ntoa(nm));

        while( (sp = strrchr(nmbuf, '.')) && strcmp(sp, ".0") == 0 ) {
            *sp = 0;
            *strrchr(ipbuf, '.') = 0;
        }
        AddClassToHeap(CanonifyName(ipbuf));
    }
}
Esempio n. 4
0
void AddMultipleClasses(char *classlist)

{ char *sp, currentitem[CF_MAXVARSIZE],local[CF_MAXVARSIZE];
 
if ((classlist == NULL) || strlen(classlist) == 0)
   {
   return;
   }

memset(local,0,CF_MAXVARSIZE);
strncpy(local,classlist,CF_MAXVARSIZE-1);

Debug("AddMultipleClasses(%s)\n",local);

for (sp = local; *sp != '\0'; sp++)
   {
   memset(currentitem,0,CF_MAXVARSIZE);

   sscanf(sp,"%250[^.:,]",currentitem);

   sp += strlen(currentitem);
      
   if (IsHardClass(currentitem))
      {
      FatalError("cfengine: You cannot use -D to define a reserved class!");
      }

   AddClassToHeap(CanonifyName(currentitem));
   }
}
Esempio n. 5
0
int ArchiveToRepository(const char *file, Attributes attr, Promise *pp, const ReportContext *report_context)
 /* Returns true if the file was backup up and false if not */
{
    char destination[CF_BUFSIZE];
    struct stat sb, dsb;

    if (!GetRepositoryPath(file, attr, destination))
    {
        return false;
    }

    if (attr.copy.backup == cfa_nobackup)
    {
        return true;
    }

    if (IsItemIn(VREPOSLIST, file))
    {
        CfOut(OUTPUT_LEVEL_INFORM, "",
              "The file %s has already been moved to the repository once. Multiple update will cause loss of backup.",
              file);
        return true;
    }

    ThreadLock(cft_getaddr);
    PrependItemList(&VREPOSLIST, file);
    ThreadUnlock(cft_getaddr);

    CfDebug("Repository(%s)\n", file);
    
    JoinPath(destination, CanonifyName(file));

    if (!MakeParentDirectory(destination, attr.move_obstructions, report_context))
    {
    }

    if (cfstat(file, &sb) == -1)
    {
        CfDebug("File %s promised to archive to the repository but it disappeared!\n", file);
        return true;
    }

    cfstat(destination, &dsb);

    CheckForFileHoles(&sb, pp);

    if (pp && CopyRegularFileDisk(file, destination, pp->makeholes))
    {
        CfOut(OUTPUT_LEVEL_INFORM, "", "Moved %s to repository location %s\n", file, destination);
        return true;
    }
    else
    {
        CfOut(OUTPUT_LEVEL_INFORM, "", "Failed to move %s to repository location %s\n", file, destination);
        return false;
    }
}
Esempio n. 6
0
int ArchiveToRepository(const char *file, Attributes attr)
 /* Returns true if the file was backup up and false if not */
{
    char destination[CF_BUFSIZE];
    struct stat sb, dsb;

    if (!GetRepositoryPath(file, attr, destination))
    {
        return false;
    }

    if (attr.copy.backup == BACKUP_OPTION_NO_BACKUP)
    {
        return true;
    }

    if (IsItemIn(VREPOSLIST, file))
    {
        Log(LOG_LEVEL_INFO,
            "The file '%s' has already been moved to the repository once. Multiple update will cause loss of backup.",
              file);
        return true;
    }

    ThreadLock(cft_getaddr);
    PrependItemList(&VREPOSLIST, file);
    ThreadUnlock(cft_getaddr);
    
    JoinPath(destination, CanonifyName(file));

    if (!MakeParentDirectory(destination, attr.move_obstructions))
    {
    }

    if (stat(file, &sb) == -1)
    {
        Log(LOG_LEVEL_DEBUG, "File '%s' promised to archive to the repository but it disappeared!", file);
        return true;
    }

    stat(destination, &dsb);

    if (CopyRegularFileDisk(file, destination))
    {
        Log(LOG_LEVEL_INFO, "Moved '%s' to repository location '%s'", file, destination);
        return true;
    }
    else
    {
        Log(LOG_LEVEL_INFO, "Failed to move '%s' to repository location '%s'", file, destination);
        return false;
    }
}
Esempio n. 7
0
/* 
 * Whatever the manuals might say, you cannot get IPV6 interface
 * configuration from the ioctls. This seems to be implemented in a non
 * standard way across OSes BSDi has done getifaddrs(), solaris 8 has a
 * new ioctl, Stevens book shows the suggestion which has not been
 * implemented...
 */
void
GetV6InterfaceInfo(void)
{
    FILE *pp;
    char buffer[CF_BUFSIZE];

    Verbose("Trying to locate my IPv6 address\n");

    switch (g_vsystemhardclass) {
    case cfnt:
        /* NT cannot do this */
        break;
    default:
        if ((pp = cfpopen("/sbin/ifconfig -a", "r")) == NULL) {
            Verbose("Could not find interface info\n");
            return;
        }

        while (!feof(pp)) {
            fgets(buffer, CF_BUFSIZE, pp);

            if (StrStr(buffer, "inet6")) {
                struct Item *ip,*list = NULL;
                char *sp;

                list = SplitStringAsItemList(buffer, ' ');

                for (ip = list; ip != NULL; ip=ip->next) {
                    for (sp = ip->name; *sp != '\0'; sp++) {

                        /* Remove CIDR mask */
                        if (*sp == '/')  {
                            *sp = '\0';
                        }
                    }

                    if (IsIPV6Address(ip->name) &&
                            (strcmp(ip->name, "::1") != 0)) {

                        Verbose("Found IPv6 address %s\n", ip->name);
                        AppendItem(&g_ipaddresses, ip->name, "");
                        AddClassToHeap(CanonifyName(ip->name));

                    }
                }
                DeleteItemList(list);
            }
        }
        fclose(pp);
        break;
    }
}
Esempio n. 8
0
int VM_version(void)

{ FILE *fp;
  char *sp,buffer[CF_BUFSIZE],classbuf[CF_BUFSIZE],version[CF_BUFSIZE];
  struct stat statbuf;
  int major,minor,bug;
  int len = 0;
  int sufficient = 0;

/* VMware Server ESX >= 3 has version info in /proc */
if ((fp = fopen("/proc/vmware/version","r")) != NULL)
   {
        ReadLine(buffer,CF_BUFSIZE,fp);
        Chop(buffer);
        if (sscanf(buffer,"VMware ESX Server %d.%d.%d",&major,&minor,&bug) > 0)
           {
           snprintf(classbuf,CF_BUFSIZE,"VMware ESX Server %d",major);
           AddClassToHeap(CanonifyName(classbuf));
           snprintf(classbuf,CF_BUFSIZE,"VMware ESX Server %d.%d",major,minor);
           AddClassToHeap(CanonifyName(classbuf));
           snprintf(classbuf,CF_BUFSIZE,"VMware ESX Server %d.%d.%d",major,minor,bug);
           AddClassToHeap(CanonifyName(classbuf));
           sufficient = 1;
           }
        else if (sscanf(buffer,"VMware ESX Server %s",version) > 0)
           {
           snprintf(classbuf,CF_BUFSIZE,"VMware ESX Server %s",version);
           AddClassToHeap(CanonifyName(classbuf));
           sufficient = 1;
           }
        fclose(fp);
   }

/* Fall back to checking for other files */
if (sufficient < 1 && ((fp = fopen("/etc/vmware-release","r")) != NULL) ||
                       (fp = fopen("/etc/issue","r")) != NULL)
   {
        ReadLine(buffer,CF_BUFSIZE,fp);
        Chop(buffer);
        AddClassToHeap(CanonifyName(buffer));

        /* Strip off the release code name e.g. "(Dali)" */
        if ((sp = strchr(buffer,'(')) != NULL)
           {
           *sp = 0;
           Chop(buffer);
           AddClassToHeap(CanonifyName(buffer));
           }
        sufficient = 1;
        fclose(fp);
   }

return sufficient < 1 ? 1 : 0;
}
Esempio n. 9
0
static void AddAllClasses(EvalContext *ctx, const char *ns, const Rlist *list, bool persist, ContextStatePolicy policy, ContextScope context_scope)
{
    for (const Rlist *rp = list; rp != NULL; rp = rp->next)
    {
        char *classname = xstrdup(rp->item);

        CanonifyNameInPlace(classname);

        if (EvalContextHeapContainsHard(ctx, classname))
        {
            Log(LOG_LEVEL_ERR, "You cannot use reserved hard class '%s' as post-condition class", classname);
            // TODO: ok.. but should we take any action? continue; maybe?
        }

        if (persist > 0)
        {
            if (context_scope != CONTEXT_SCOPE_NAMESPACE)
            {
                Log(LOG_LEVEL_INFO, "Automatically promoting context scope for '%s' to namespace visibility, due to persistence", classname);
            }

            Log(LOG_LEVEL_VERBOSE, "Defining persistent promise result class '%s'", classname);
            EvalContextHeapPersistentSave(CanonifyName(rp->item), ns, persist, policy);
            EvalContextHeapAddSoft(ctx, classname, ns);
        }
        else
        {
            Log(LOG_LEVEL_VERBOSE, "Defining promise result class '%s'", classname);

            switch (context_scope)
            {
            case CONTEXT_SCOPE_BUNDLE:
                EvalContextStackFrameAddSoft(ctx, classname);
                break;

            default:
            case CONTEXT_SCOPE_NAMESPACE:
                EvalContextHeapAddSoft(ctx, classname, ns);
                break;
            }
        }
    }
}
Esempio n. 10
0
/**
 * @brief Writes a file with a contained timestamp to mark a policy file as validated
 * @return True if successful.
 */
static bool WritePolicyValidatedFile(const GenericAgentConfig *config)
{
    char filename[CF_MAXVARSIZE];

    if (MINUSF)
    {
        snprintf(filename, CF_MAXVARSIZE, "%s/state/validated_%s", CFWORKDIR, CanonifyName(config->original_input_file));
        MapName(filename);
    }
    else
    {
        snprintf(filename, CF_MAXVARSIZE, "%s/masterfiles/cf_promises_validated", CFWORKDIR);
        MapName(filename);
    }

    if (!MakeParentDirectory(filename, true))
    {
        Log(LOG_LEVEL_ERR, "While writing policy validated marker file '%s', could not create directory (MakeParentDirectory: %s)", filename, GetErrorStr());
        return false;
    }

    int fd = creat(filename, 0600);
    if (fd == -1)
    {
        Log(LOG_LEVEL_ERR, "While writing policy validated marker file '%s', could not create file (creat: %s)", filename, GetErrorStr());
        return false;
    }

    FILE *fp = fdopen(fd, "w");
    time_t now = time(NULL);

    char timebuf[26];

    fprintf(fp, "%s", cf_strtimestamp_local(now, timebuf));
    fclose(fp);

    return true;
}
Esempio n. 11
0
File: unix.c Progetto: rdparker/core
static void Unix_GetMacAddress(enum cfagenttype ag, int fd, struct ifreq *ifr, struct ifreq *ifp, Rlist **interfaces,
                               Rlist **hardware)
{
    char name[CF_MAXVARSIZE];

    if (ag != cf_know)
    {
        snprintf(name, CF_MAXVARSIZE, "hardware_mac[%s]", ifp->ifr_name);
    }
    else
    {
        snprintf(name, CF_MAXVARSIZE, "hardware_mac[interface_name]");
    }

# ifdef SIOCGIFHWADDR
    char hw_mac[CF_MAXVARSIZE];

    
    ioctl(fd, SIOCGIFHWADDR, ifr);
    snprintf(hw_mac, CF_MAXVARSIZE - 1, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
             (unsigned char) ifr->ifr_hwaddr.sa_data[0],
             (unsigned char) ifr->ifr_hwaddr.sa_data[1],
             (unsigned char) ifr->ifr_hwaddr.sa_data[2],
             (unsigned char) ifr->ifr_hwaddr.sa_data[3],
             (unsigned char) ifr->ifr_hwaddr.sa_data[4], (unsigned char) ifr->ifr_hwaddr.sa_data[5]);

    NewScalar("sys", name, hw_mac, cf_str);
    AppendRlist(hardware, hw_mac, CF_SCALAR);
    AppendRlist(interfaces, ifp->ifr_name, CF_SCALAR);

    snprintf(name, CF_MAXVARSIZE, "mac_%s", CanonifyName(hw_mac));
    NewClass(name);
# else
    NewScalar("sys", name, "mac_unknown", cf_str);
    NewClass("mac_unknown");
# endif
}
Esempio n. 12
0
static void GetMacAddress(AgentType ag, int fd, struct ifreq *ifr, struct ifreq *ifp, Rlist **interfaces,
                          Rlist **hardware)
{
    char name[CF_MAXVARSIZE];

    if ((ag != AGENT_TYPE_KNOW) && (ag != AGENT_TYPE_GENDOC))
    {
        snprintf(name, CF_MAXVARSIZE, "hardware_mac[%s]", ifp->ifr_name);
    }
    else
    {
        snprintf(name, CF_MAXVARSIZE, "hardware_mac[interface_name]");
    }

# if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ_IFR_HWADDR)
    char hw_mac[CF_MAXVARSIZE];

    
    ioctl(fd, SIOCGIFHWADDR, ifr);
    snprintf(hw_mac, CF_MAXVARSIZE - 1, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
             (unsigned char) ifr->ifr_hwaddr.sa_data[0],
             (unsigned char) ifr->ifr_hwaddr.sa_data[1],
             (unsigned char) ifr->ifr_hwaddr.sa_data[2],
             (unsigned char) ifr->ifr_hwaddr.sa_data[3],
             (unsigned char) ifr->ifr_hwaddr.sa_data[4], (unsigned char) ifr->ifr_hwaddr.sa_data[5]);

    NewScalar("sys", name, hw_mac, DATA_TYPE_STRING);
    RlistAppend(hardware, hw_mac, RVAL_TYPE_SCALAR);
    RlistAppend(interfaces, ifp->ifr_name, RVAL_TYPE_SCALAR);

    snprintf(name, CF_MAXVARSIZE, "mac_%s", CanonifyName(hw_mac));
    HardClass(name);
# else
    NewScalar("sys", name, "mac_unknown", DATA_TYPE_STRING);
    HardClass("mac_unknown");
# endif
}
Esempio n. 13
0
void CheckOptsAndInit(int argc,char **argv)

{ extern char *optarg;
  int optindex = 0;
  char ld_library_path[CF_BUFSIZE];
  int c,seed;
  unsigned char s[16];

ld_library_path[0] = '\0';

Banner("Check options");

NOSPLAY = false; 

sprintf(VPREFIX, "cfexecd"); 
openlog(VPREFIX,LOG_PID|LOG_NOWAIT|LOG_ODELAY,LOG_DAEMON);

while ((c=getopt_long(argc,argv,"L:d:vhpqFV1g",CFDOPTIONS,&optindex)) != EOF)
  {
  switch ((char) c)
      {
      case 'd': 

                switch ((optarg==NULL)?3:*optarg)
                   {
                   case '1': D1 = true;
                             break;
                   case '2': D2 = true;
                             break;
                   default:  DEBUG = true;
                             break;
                   }
                
                NO_FORK = true;
                VERBOSE = true;
                printf("cfexecd Debug mode: running in foreground\n");
                break;

      case 'v': VERBOSE = true;
         break;

      case 'V': printf("GNU %s-%s daemon\n%s\n",PACKAGE,VERSION,COPYRIGHT);
          printf("This program is covered by the GNU Public License and may be\n");
          printf("copied free of charge. No warrenty is implied.\n\n");
          exit(0);
          break;
          
      case 'q': NOSPLAY = true;
          break;
          
      case 'p': PARSEONLY = true;
          break;
          
      case 'g': NO_FORK = true;
         break;
         
      case 'L': 
          snprintf(ld_library_path,CF_BUFSIZE-1,"LD_LIBRARY_PATH=%s",optarg);
          if (putenv(strdup(ld_library_path)) != 0)
             {
             }
          
          break;
          
      case 'F':
      case '1': ONCE = true;
          NO_FORK = true;
          break;
          
      case 'h':  Syntax();
          exit(1);
          break;  /* never reached.... */
          
      default:  Syntax();
          exit(1);
          
      }
  }
 
LOGGING = true;                    /* Do output to syslog */

 /* XXX Initialize workdir for non privileged users */

strcpy(CFWORKDIR,WORKDIR);

#ifndef NT
if (getuid() > 0)
   {
   char *homedir;
   if ((homedir = getenv("HOME")) != NULL)
      {
      strcpy(CFWORKDIR,homedir);
      strcat(CFWORKDIR,"/.cfagent");
      }
   }
#endif

snprintf(VBUFF,CF_BUFSIZE,"%s/inputs/update.conf",CFWORKDIR);
MakeDirectoriesFor(VBUFF,'y');
snprintf(VBUFF,CF_BUFSIZE,"%s/bin/cfagent -D from_cfexecd",CFWORKDIR);
MakeDirectoriesFor(VBUFF,'y');
snprintf(VBUFF,CF_BUFSIZE,"%s/outputs/spooled_reports",CFWORKDIR);
MakeDirectoriesFor(VBUFF,'y');

snprintf(VBUFF,CF_BUFSIZE,"%s/inputs",CFWORKDIR);
chmod(VBUFF,0700); 
snprintf(VBUFF,CF_BUFSIZE,"%s/outputs",CFWORKDIR);
chmod(VBUFF,0700);

strncpy(VLOCKDIR,CFWORKDIR,CF_BUFSIZE-1);
strncpy(VLOGDIR,CFWORKDIR,CF_BUFSIZE-1);

VCANONICALFILE = strdup(CanonifyName(VINPUTFILE));

GetCfStuff();

MAILTO[0] = '\0';
MAILFROM[0] = '\0';
VIPADDRESS[0] = '\0';
VMAILSERVER[0] = '\0';

OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
CheckWorkDirectories();
RandomSeed();

RAND_bytes(s,16);
s[15] = '\0';
seed = ElfHash(s);
srand48((long)seed);  
}
Esempio n. 14
0
void
GetInterfaceInfo(void)
{
    int fd, len, i, j;
    struct ifreq ifbuf[512], ifr, *ifp;
    struct ifconf list;
    struct sockaddr_in *sin;
    struct hostent *hp;
    char *sp;
    char ip[CF_MAXVARSIZE];
    char name[CF_MAXVARSIZE];

    Debug("GetInterfaceInfo()\n");

    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        CfLog(cferror, "Couldn't open socket", "socket");
        exit(1);
    }

    list.ifc_len = sizeof(ifbuf);
    list.ifc_req = ifbuf;

#ifdef SIOCGIFCONF
    if (ioctl(fd, SIOCGIFCONF, &list) == -1 ||
            (list.ifc_len < (sizeof(struct ifreq))))
#else
    if (ioctl(fd, OSIOCGIFCONF, &list) == -1 ||
            (list.ifc_len < (sizeof(struct ifreq))))
#endif
    {
        CfLog(cferror, "Couldn't get interfaces", "ioctl");
        exit(1);
    }

    for (j = 0, len = 0, ifp = list.ifc_req; len < list.ifc_len;
            len+=SIZEOF_IFREQ(*ifp), j++, ifp=&ifbuf[j]) {
        if (ifp->ifr_addr.sa_family == 0) {
            continue;
        }

        Verbose("Interface %d: %s\n", j+1, ifp->ifr_name);
        if(g_underscore_classes) {
            snprintf(g_vbuff, CF_BUFSIZE, "_net_iface_%s",
                    CanonifyName(ifp->ifr_name));
        } else {
            snprintf(g_vbuff, CF_BUFSIZE, "net_iface_%s",
                    CanonifyName(ifp->ifr_name));
        }
        AddClassToHeap(g_vbuff);

        if (ifp->ifr_addr.sa_family == AF_INET) {
            strncpy(ifr.ifr_name, ifp->ifr_name, sizeof(ifp->ifr_name));

            if (ioctl(fd,SIOCGIFFLAGS,&ifr) == -1) {
                CfLog(cferror, "No such network device", "ioctl");
                close(fd);
                return;
            }

            /* 
             * Used to check if interface was "up" if ((ifr.ifr_flags &
             * IFF_UP) && !(ifr.ifr_flags & IFF_LOOPBACK)) Now check
             * whether it is configured ...
             */
            if ((ifr.ifr_flags & IFF_BROADCAST) &&
                    !(ifr.ifr_flags & IFF_LOOPBACK)) {
                sin=(struct sockaddr_in *)&ifp->ifr_addr;

                snprintf(name, CF_MAXVARSIZE-1, "ipv4[%s]",
                        CanonifyName(ifp->ifr_name));
                AddMacroValue(g_contextid, name, 
                        inet_ntoa(sin->sin_addr));

                if ((hp = gethostbyaddr((char *)&(sin->sin_addr.s_addr),
                            sizeof(sin->sin_addr.s_addr), AF_INET)) == NULL) {
                    Debug("Host information for %s not found\n",
                            inet_ntoa(sin->sin_addr));
                } else {

                    if (hp->h_name != NULL) {
                        Debug("Adding hostip %s..\n",
                                inet_ntoa(sin->sin_addr));
                        AddClassToHeap(CanonifyName(inet_ntoa(sin->sin_addr)));
                        Debug("Adding hostname %s..\n", hp->h_name);
                        AddClassToHeap(CanonifyName(hp->h_name));

                        for (i=0; hp->h_aliases[i] != NULL; i++) {
                            Debug("Adding alias %s..\n", hp->h_aliases[i]);
                            AddClassToHeap(CanonifyName(hp->h_aliases[i]));
                        }

                        /* Old style compat */
                        strcpy(ip,inet_ntoa(sin->sin_addr));
                        AppendItem(&g_ipaddresses, ip, "");

                        for (sp = ip+strlen(ip)-1; *sp != '.'; sp--) { }
                        *sp = '\0';
                        AddClassToHeap(CanonifyName(ip));

                        /* New style */
                        strcpy(ip, "ipv4_");
                        strcat(ip, inet_ntoa(sin->sin_addr));
                        AddClassToHeap(CanonifyName(ip));

                        for (sp = ip+strlen(ip)-1; (sp > ip); sp--) {
                            if (*sp == '.') {
                                *sp = '\0';
                                AddClassToHeap(CanonifyName(ip));
                            }
                        }
                    }
                }
            }
        }

        ifp = (struct ifreq *)((char *)ifp + SIZEOF_IFREQ(*ifp));
    }

    close(fd);
}
Esempio n. 15
0
void GenericAgentDiscoverContext(EvalContext *ctx, GenericAgentConfig *config)
{
    GenericAgentSetDefaultDigest(&CF_DEFAULT_DIGEST, &CF_DEFAULT_DIGEST_LEN);

    GenericAgentInitialize(ctx, config);

    time_t t = SetReferenceTime();
    UpdateTimeClasses(ctx, t);
    SanitizeEnvironment();

    THIS_AGENT_TYPE = config->agent_type;
    EvalContextClassPutHard(ctx, CF_AGENTTYPES[config->agent_type], "cfe_internal,source=agent");

    DetectEnvironment(ctx);

    EvalContextHeapPersistentLoadAll(ctx);
    LoadSystemConstants(ctx);

    if (config->agent_type == AGENT_TYPE_AGENT && config->agent_specific.agent.bootstrap_policy_server)
    {
        if (!RemoveAllExistingPolicyInInputs(GetInputDir()))
        {
            Log(LOG_LEVEL_ERR, "Error removing existing input files prior to bootstrap");
            exit(EXIT_FAILURE);
        }

        if (!WriteBuiltinFailsafePolicy(GetInputDir()))
        {
            Log(LOG_LEVEL_ERR, "Error writing builtin failsafe to inputs prior to bootstrap");
            exit(EXIT_FAILURE);
        }

        bool am_policy_server = false;
        {
            const char *canonified_bootstrap_policy_server = CanonifyName(config->agent_specific.agent.bootstrap_policy_server);
            am_policy_server = NULL != EvalContextClassGet(ctx, NULL, canonified_bootstrap_policy_server);
            {
                char policy_server_ipv4_class[CF_BUFSIZE];
                snprintf(policy_server_ipv4_class, CF_MAXVARSIZE, "ipv4_%s", canonified_bootstrap_policy_server);
                am_policy_server |= NULL != EvalContextClassGet(ctx, NULL, policy_server_ipv4_class);
            }

            if (am_policy_server)
            {
                Log(LOG_LEVEL_INFO, "Assuming role as policy server, with policy distribution point at %s", GetMasterDir());
                EvalContextClassPutHard(ctx, "am_policy_hub", "source=bootstrap");

                if (!MasterfileExists(GetMasterDir()))
                {
                    Log(LOG_LEVEL_ERR, "In order to bootstrap as a policy server, the file '%s/promises.cf' must exist.", GetMasterDir());
                    exit(EXIT_FAILURE);
                }
            }
            else
            {
                Log(LOG_LEVEL_INFO, "Not assuming role as policy server");
            }

            WriteAmPolicyHubFile(CFWORKDIR, am_policy_server);
        }

        WritePolicyServerFile(GetWorkDir(), config->agent_specific.agent.bootstrap_policy_server);
        SetPolicyServer(ctx, config->agent_specific.agent.bootstrap_policy_server);
        /* FIXME: Why it is called here? Can't we move both invocations to before if? */
        UpdateLastPolicyUpdateTime(ctx);
        Log(LOG_LEVEL_INFO, "Bootstrapping to '%s'", POLICY_SERVER);
    }
    else
    {
        char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());
        if (existing_policy_server)
        {
            Log(LOG_LEVEL_VERBOSE, "This agent is bootstrapped to '%s'", existing_policy_server);
            SetPolicyServer(ctx, existing_policy_server);
            free(existing_policy_server);
            UpdateLastPolicyUpdateTime(ctx);
        }
        else
        {
            Log(LOG_LEVEL_VERBOSE, "This agent is not bootstrapped");
            return;
        }

        if (GetAmPolicyHub(GetWorkDir()))
        {
            EvalContextClassPutHard(ctx, "am_policy_hub", "source=bootstrap,deprecated,alias=policy_server");
            Log(LOG_LEVEL_VERBOSE, "Additional class defined: am_policy_hub");
            EvalContextClassPutHard(ctx, "policy_server", "inventory,attribute_name=CFEngine roles,source=bootstrap");
            Log(LOG_LEVEL_VERBOSE, "Additional class defined: policy_server");
        }
    }
}
Esempio n. 16
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; 
}
Esempio n. 17
0
File: link.c Progetto: kbarber/cfng
/* should return true if 'to' found */
int
LinkFiles(char *from,char *to_tmp,
        struct Item *inclusions,struct Item *exclusions,struct Item *copy,
        short nofile,struct Link *ptr)
{
    struct stat buf,savebuf;
    char to[CF_BUFSIZE], linkbuf[CF_BUFSIZE];
    char saved[CF_BUFSIZE],absto[CF_BUFSIZE],*lastnode;
    struct UidList fakeuid;
    struct Image ip;
    char stamp[CF_BUFSIZE];
    time_t STAMPNOW;
    STAMPNOW = time((time_t *)NULL);

    memset(to,0,CF_BUFSIZE);
    memset(&ip,0, sizeof(ip));

    /* links without a directory reference */
    if ((*to_tmp != '/') && (*to_tmp != '.')) {
        strcpy(to,"./");
    }

    if (strlen(to_tmp)+3 > CF_BUFSIZE) {
        printf("%s: CF_BUFSIZE boundaries exceeded in LinkFiles(%s->%s)\n",
                g_vprefix,from,to_tmp);
        return false;
    }

    strcat(to,to_tmp);

    Debug2("Linkfiles(%s,%s)\n",from,to);

    for (lastnode = from+strlen(from); *lastnode != '/'; lastnode--) { }

    lastnode++;

    if (IgnoredOrExcluded(links,lastnode,inclusions,exclusions)) {
        Verbose("%s: Skipping non-included pattern %s\n",g_vprefix,from);
        return true;
    }

    if (IsWildItemIn(g_vcopylinks,lastnode) || IsWildItemIn(copy,lastnode)) {
        fakeuid.uid = CF_SAME_OWNER;
        fakeuid.next = NULL;
        ip.plus = CF_SAMEMODE;
        ip.minus = CF_SAMEMODE;
        ip.uid = &fakeuid;
        ip.gid = (struct GidList *) &fakeuid;
        ip.action = "do";
        ip.recurse = 0;
        ip.type = 't';
        ip.defines = ptr->defines;
        ip.elsedef = ptr->elsedef;
        ip.backup = true;
        ip.exclusions = NULL;
        ip.inclusions = NULL;
        ip.symlink = NULL;
        ip.classes = NULL;
        ip.plus_flags = 0;
        ip.size = CF_NOSIZE;
        ip.linktype = 's';
        ip.minus_flags = 0;
        ip.server = strdup("localhost");
        Verbose("%s: Link item %s marked for copying instead\n", 
                g_vprefix, from);
        MakeDirectoriesFor(to,'n');
        CheckImage(to,from,&ip);
        free(ip.server);
        return true;
    }

    /* relative path, must still check if exists */
    if (*to != '/') {
        Debug("Relative link destination detected: %s\n",to);
        strcpy(absto,AbsLinkPath(from,to));
        Debug("Absolute path to relative link = %s, from %s\n",absto,from);
    } else {
        strcpy(absto,to);
    }

    if (!nofile) {
        if (stat(absto,&buf) == -1) {
            /* no error warning, since the higher level routine uses this */
            return(false);
        }
    }

    Debug2("Trying to link %s -> %s (%s)\n",from,to,absto);

    if (lstat(from,&buf) == 0) {
        if (! S_ISLNK(buf.st_mode) && ! g_enforcelinks) {
            snprintf(g_output,CF_BUFSIZE*2,"Error linking %s -> %s\n",from,to);
            CfLog(cfsilent,g_output,"");

            snprintf(g_output, CF_BUFSIZE*2,
                    "Cannot make link: %s exists and is not a link! "
                    "(uid %d)\n", from, buf.st_uid);

            CfLog(cfsilent,g_output,"");
            return(true);
        }

        if (S_ISREG(buf.st_mode) && g_enforcelinks) {
            snprintf(g_output, CF_BUFSIZE*2, "Moving %s to %s%s\n",
                    from, from, CF_SAVED);
            CfLog(cfsilent,g_output,"");

            if (g_dontdo) {
                return true;
            }

            saved[0] = '\0';
            strcpy(saved,from);

            sprintf(stamp, "_%d_%s",
                    g_cfstarttime, CanonifyName(ctime(&STAMPNOW)));
            strcat(saved,stamp);

            strcat(saved,CF_SAVED);

            if (rename(from,saved) == -1) {
                snprintf(g_output, CF_BUFSIZE*2,
                        "Can't rename %s to %s\n", from,saved);
                CfLog(cferror,g_output,"rename");
                return(true);
            }

            if (Repository(saved,g_vrepository)) {
                unlink(saved);
            }
        }

        if (S_ISDIR(buf.st_mode) && g_enforcelinks) {
            snprintf(g_output,CF_BUFSIZE*2,"Moving directory %s to %s%s.dir\n",
                    from,from,CF_SAVED);
            CfLog(cfsilent,g_output,"");

            if (g_dontdo) {
                return true;
            }

            saved[0] = '\0';
            strcpy(saved,from);

            sprintf(stamp, "_%d_%s",
                    g_cfstarttime, CanonifyName(ctime(&STAMPNOW)));
            strcat(saved,stamp);

            strcat(saved,CF_SAVED);
            strcat(saved,".dir");

            if (stat(saved,&savebuf) != -1) {

                snprintf(g_output,CF_BUFSIZE*2,
                        "Couldn't save directory %s, "
                        "since %s exists already\n",
                        from,saved);

                CfLog(cferror,g_output,"");

                snprintf(g_output,CF_BUFSIZE*2,
                        "Unable to force link to "
                        "existing directory %s\n",from);

                CfLog(cferror,g_output,"");
                return true;
            }

            if (rename(from,saved) == -1) {
                snprintf(g_output, CF_BUFSIZE*2, 
                        "Can't rename %s to %s\n", from,saved);
                CfLog(cferror,g_output,"rename");
                return(true);
            }
        }
    }

    memset(linkbuf,0,CF_BUFSIZE);

    if (readlink(from,linkbuf,CF_BUFSIZE-1) == -1) {
        /* link doesn't exist */
        if (! MakeDirectoriesFor(from,'n')) {

            snprintf(g_output,CF_BUFSIZE*2,
                    "Couldn't build directory tree up to %s!\n",from);

            CfLog(cfsilent,g_output,"");

            snprintf(g_output,CF_BUFSIZE*2,
                    "One element was a plain file, not a directory!\n");

            CfLog(cfsilent,g_output,"");
            return(true);
        }
    } else {
        int off1 = 0, off2 = 0;

        DeleteSlash(linkbuf);

        /* Ignore ./ at beginning */
        if (strncmp(linkbuf,"./",2) == 0) {
            off1 = 2;
        }

        if (strncmp(to,"./",2) == 0) {
            off2 = 2;
        }

        if (strcmp(linkbuf+off1,to+off2) != 0) {
            if (g_enforcelinks) {
                snprintf(g_output,CF_BUFSIZE*2,"Removing link %s\n",from);
                CfLog(cfinform,g_output,"");

                if (!g_dontdo) {
                    if (unlink(from) == -1) {
                        perror("unlink");
                        return true;
                    }

                    return DoLink(from,to,ptr->defines);
                }
            } else {

                snprintf(g_output,CF_BUFSIZE*2,
                        "Old link %s points somewhere else. Doing nothing!\n",
                        from);

                CfLog(cfsilent,g_output,"");

                snprintf(g_output, CF_BUFSIZE*2,
                        "(Link points to %s not %s)\n\n",
                        linkbuf,to);

                CfLog(cfsilent,g_output,"");
                return(true);
            }
        } else {
            snprintf(g_output, CF_BUFSIZE*2,
                    "Link (%s->%s) exists.\n", from, to_tmp);
            CfLog(cfverbose,g_output,"");

            if (!nofile) {

                /* Check whether link points somewhere */
                KillOldLink(from,ptr->defines);

                return true;
            }

            AddMultipleClasses(ptr->elsedef);
            return(true);
        }
    }

    return DoLink(from,to,ptr->defines);
}
Esempio n. 18
0
void GetInterfacesInfo(AgentType ag)
{
    int fd, len, i, j, first_address = false, ipdefault = false;
    struct ifreq ifbuf[CF_IFREQ], ifr, *ifp;
    struct ifconf list;
    struct sockaddr_in *sin;
    struct hostent *hp;
    char *sp, workbuf[CF_BUFSIZE];
    char ip[CF_MAXVARSIZE];
    char name[CF_MAXVARSIZE];
    char last_name[CF_BUFSIZE];
    Rlist *interfaces = NULL, *hardware = NULL, *ips = NULL;

    CfDebug("GetInterfacesInfo()\n");

    // Long-running processes may call this many times
    DeleteItemList(IPADDRESSES);
    IPADDRESSES = NULL;

    memset(ifbuf, 0, sizeof(ifbuf));

    InitIgnoreInterfaces();
    
    last_name[0] = '\0';

    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        CfOut(OUTPUT_LEVEL_ERROR, "socket", "Couldn't open socket");
        exit(1);
    }

    list.ifc_len = sizeof(ifbuf);
    list.ifc_req = ifbuf;

# ifdef SIOCGIFCONF
    if (ioctl(fd, SIOCGIFCONF, &list) == -1 || (list.ifc_len < (sizeof(struct ifreq))))
# else
    if ((ioctl(fd, OSIOCGIFCONF, &list) == -1) || (list.ifc_len < (sizeof(struct ifreq))))
# endif
    {
        CfOut(OUTPUT_LEVEL_ERROR, "ioctl", "Couldn't get interfaces - old kernel? Try setting CF_IFREQ to 1024");
        exit(1);
    }

    last_name[0] = '\0';

    for (j = 0, len = 0, ifp = list.ifc_req; len < list.ifc_len;
         len += SIZEOF_IFREQ(*ifp), j++, ifp = (struct ifreq *) ((char *) ifp + SIZEOF_IFREQ(*ifp)))
    {

        if (ifp->ifr_addr.sa_family == 0)
        {
            continue;
        }

        if ((ifp->ifr_name == NULL) || (strlen(ifp->ifr_name) == 0))
        {
            continue;
        }

        /* Skip virtual network interfaces for Linux, which seems to be a problem */

        if (IgnoreInterface(ifp->ifr_name))
        {
            continue;
        }
        
        if (strstr(ifp->ifr_name, ":"))
        {
#ifdef __linux__
            CfOut(OUTPUT_LEVEL_VERBOSE, "", "Skipping apparent virtual interface %d: %s\n", j + 1, ifp->ifr_name);
            continue;
#endif
        }
        else
        {
            CfOut(OUTPUT_LEVEL_VERBOSE, "", "Interface %d: %s\n", j + 1, ifp->ifr_name);
        }

        // Ignore the loopback

        if (strcmp(ifp->ifr_name, "lo") == 0)
        {
            continue;
        }

        if (strncmp(last_name, ifp->ifr_name, sizeof(ifp->ifr_name)) == 0)
        {
            first_address = false;
        }
        else
        {
            strncpy(last_name, ifp->ifr_name, sizeof(ifp->ifr_name));

            if (!first_address)
            {
                NewScalar("sys", "interface", last_name, DATA_TYPE_STRING);
                first_address = true;
            }
        }

        snprintf(workbuf, CF_BUFSIZE, "net_iface_%s", CanonifyName(ifp->ifr_name));

        HardClass(workbuf);

        if (ifp->ifr_addr.sa_family == AF_INET)
        {
            strncpy(ifr.ifr_name, ifp->ifr_name, sizeof(ifp->ifr_name));

            if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1)
            {
                CfOut(OUTPUT_LEVEL_ERROR, "ioctl", "No such network device");
                continue;
            }

            if ((ifr.ifr_flags & IFF_UP) && (!(ifr.ifr_flags & IFF_LOOPBACK)))
            {
                sin = (struct sockaddr_in *) &ifp->ifr_addr;

                if (IgnoreJailInterface(j + 1, sin))
                {
                    CfOut(OUTPUT_LEVEL_VERBOSE, "", "Ignoring interface %d", j + 1);
                    continue;
                }

                CfDebug("Adding hostip %s..\n", inet_ntoa(sin->sin_addr));
                HardClass(inet_ntoa(sin->sin_addr));

                if ((hp =
                     gethostbyaddr((char *) &(sin->sin_addr.s_addr), sizeof(sin->sin_addr.s_addr), AF_INET)) == NULL)
                {
                    CfDebug("No hostinformation for %s found\n", inet_ntoa(sin->sin_addr));
                }
                else
                {
                    if (hp->h_name != NULL)
                    {
                        CfDebug("Adding hostname %s..\n", hp->h_name);
                        HardClass(hp->h_name);

                        if (hp->h_aliases != NULL)
                        {
                            for (i = 0; hp->h_aliases[i] != NULL; i++)
                            {
                                CfOut(OUTPUT_LEVEL_VERBOSE, "", "Adding alias %s..\n", hp->h_aliases[i]);
                                HardClass(hp->h_aliases[i]);
                            }
                        }
                    }
                }

                if (strcmp(inet_ntoa(sin->sin_addr), "0.0.0.0") == 0)
                {
                    // Maybe we need to do something windows specific here?
                    CfOut(OUTPUT_LEVEL_VERBOSE, "", " !! Cannot discover hardware IP, using DNS value");
                    strcpy(ip, "ipv4_");
                    strcat(ip, VIPADDRESS);
                    AppendItem(&IPADDRESSES, VIPADDRESS, "");
                    RlistAppend(&ips, VIPADDRESS, RVAL_TYPE_SCALAR);

                    for (sp = ip + strlen(ip) - 1; (sp > ip); sp--)
                    {
                        if (*sp == '.')
                        {
                            *sp = '\0';
                            HardClass(ip);
                        }
                    }

                    strcpy(ip, VIPADDRESS);
                    i = 3;

                    for (sp = ip + strlen(ip) - 1; (sp > ip); sp--)
                    {
                        if (*sp == '.')
                        {
                            *sp = '\0';
                            snprintf(name, CF_MAXVARSIZE - 1, "ipv4_%d[%s]", i--, CanonifyName(VIPADDRESS));
                            NewScalar("sys", name, ip, DATA_TYPE_STRING);
                        }
                    }
                    continue;
                }

                strncpy(ip, "ipv4_", CF_MAXVARSIZE);
                strncat(ip, inet_ntoa(sin->sin_addr), CF_MAXVARSIZE - 6);
                HardClass(ip);

                if (!ipdefault)
                {
                    ipdefault = true;
                    NewScalar("sys", "ipv4", inet_ntoa(sin->sin_addr), DATA_TYPE_STRING);

                    strcpy(VIPADDRESS, inet_ntoa(sin->sin_addr));
                }

                AppendItem(&IPADDRESSES, inet_ntoa(sin->sin_addr), "");
                RlistAppend(&ips, inet_ntoa(sin->sin_addr), RVAL_TYPE_SCALAR);

                for (sp = ip + strlen(ip) - 1; (sp > ip); sp--)
                {
                    if (*sp == '.')
                    {
                        *sp = '\0';
                        HardClass(ip);
                    }
                }

                // Set the IPv4 on interface array

                strcpy(ip, inet_ntoa(sin->sin_addr));

                if ((ag != AGENT_TYPE_KNOW) && (ag != AGENT_TYPE_GENDOC))
                {
                    snprintf(name, CF_MAXVARSIZE - 1, "ipv4[%s]", CanonifyName(ifp->ifr_name));
                }
                else
                {
                    snprintf(name, CF_MAXVARSIZE - 1, "ipv4[interface_name]");
                }

                NewScalar("sys", name, ip, DATA_TYPE_STRING);

                i = 3;

                for (sp = ip + strlen(ip) - 1; (sp > ip); sp--)
                {
                    if (*sp == '.')
                    {
                        *sp = '\0';

                        if ((ag != AGENT_TYPE_KNOW) && (ag != AGENT_TYPE_GENDOC))
                        {
                            snprintf(name, CF_MAXVARSIZE - 1, "ipv4_%d[%s]", i--, CanonifyName(ifp->ifr_name));
                        }
                        else
                        {
                            snprintf(name, CF_MAXVARSIZE - 1, "ipv4_%d[interface_name]", i--);
                        }

                        NewScalar("sys", name, ip, DATA_TYPE_STRING);
                    }
                }
            }

            // Set the hardware/mac address array
            GetMacAddress(ag, fd, &ifr, ifp, &interfaces, &hardware);
        }
    }

    close(fd);

    NewList("sys", "interfaces", interfaces, DATA_TYPE_STRING_LIST);
    NewList("sys", "hardware_addresses", hardware, DATA_TYPE_STRING_LIST);
    NewList("sys", "ip_addresses", ips, DATA_TYPE_STRING_LIST);

    RlistDestroy(interfaces);
    RlistDestroy(hardware);
    RlistDestroy(ips);

    FindV6InterfacesInfo();
}
Esempio n. 19
0
void KeepClassContextPromise(EvalContext *ctx, Promise *pp, ARG_UNUSED const ReportContext *report_context)
{
    Attributes a;

    a = GetClassContextAttributes(ctx, pp);

    if (!FullTextMatch("[a-zA-Z0-9_]+", pp->promiser))
    {
        CfOut(OUTPUT_LEVEL_VERBOSE, "", "Class identifier \"%s\" contains illegal characters - canonifying", pp->promiser);
        snprintf(pp->promiser, strlen(pp->promiser) + 1, "%s", CanonifyName(pp->promiser));
    }

    if (a.context.nconstraints == 0)
    {
        cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_FAIL, "", pp, a, "No constraints for class promise %s", pp->promiser);
        return;
    }

    if (a.context.nconstraints > 1)
    {
        cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_FAIL, "", pp, a, "Irreconcilable constraints in classes for %s", pp->promiser);
        return;
    }

// If this is a common bundle ...

    if (strcmp(PromiseGetBundle(pp)->type, "common") == 0)
    {
        if (EvalClassExpression(ctx, a.context.expression, pp))
        {
            CfOut(OUTPUT_LEVEL_VERBOSE, "", " ?> defining additional global class %s\n", pp->promiser);

            if (!ValidClassName(pp->promiser))
            {
                cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_FAIL, "", pp, a,
                     " !! Attempted to name a class \"%s\", which is an illegal class identifier", pp->promiser);
            }
            else
            {
                if (a.context.persistent > 0)
                {
                    CfOut(OUTPUT_LEVEL_VERBOSE, "", " ?> defining explicit persistent class %s (%d mins)\n", pp->promiser,
                          a.context.persistent);
                    EvalContextHeapPersistentSave(pp->promiser, PromiseGetNamespace(pp), a.context.persistent, CONTEXT_STATE_POLICY_RESET);
                    EvalContextHeapAddSoft(ctx, pp->promiser, PromiseGetNamespace(pp));
                }
                else
                {
                    CfOut(OUTPUT_LEVEL_VERBOSE, "", " ?> defining explicit global class %s\n", pp->promiser);
                    EvalContextHeapAddSoft(ctx, pp->promiser, PromiseGetNamespace(pp));
                }
            }
        }

        /* These are global and loaded once */
        /* *(pp->donep) = true; */

        return;
    }

// If this is some other kind of bundle (else here??)

    if (strcmp(PromiseGetBundle(pp)->type, CF_AGENTTYPES[THIS_AGENT_TYPE]) == 0 || FullTextMatch("edit_.*", PromiseGetBundle(pp)->type))
    {
        if (EvalClassExpression(ctx, a.context.expression, pp))
        {
            if (!ValidClassName(pp->promiser))
            {
                cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_FAIL, "", pp, a,
                     " !! Attempted to name a class \"%s\", which is an illegal class identifier", pp->promiser);
            }
            else
            {
                if (a.context.persistent > 0)
                {
                    CfOut(OUTPUT_LEVEL_VERBOSE, "", " ?> defining explicit persistent class %s (%d mins)\n", pp->promiser,
                          a.context.persistent);
                    CfOut(OUTPUT_LEVEL_VERBOSE, "",
                          " ?> Warning: persistent classes are global in scope even in agent bundles\n");
                    EvalContextHeapPersistentSave(pp->promiser, PromiseGetNamespace(pp), a.context.persistent, CONTEXT_STATE_POLICY_RESET);
                    EvalContextHeapAddSoft(ctx, pp->promiser, PromiseGetNamespace(pp));
                }
                else
                {
                    CfOut(OUTPUT_LEVEL_VERBOSE, "", " ?> defining explicit local bundle class %s\n", pp->promiser);
                    EvalContextStackFrameAddSoft(ctx, pp->promiser);
                }
            }
        }

        // Private to bundle, can be reloaded

        *(pp->donep) = false;
        return;
    }
}
Esempio n. 20
0
void LocalExec(const ExecConfig *config)
{
    FILE *pp;
    char line[CF_BUFSIZE], line_escaped[sizeof(line) * 2], filename[CF_BUFSIZE], *sp;
    char cmd[CF_BUFSIZE], esc_command[CF_BUFSIZE];
    int print, count = 0;
    void *thread_name;
    time_t starttime = time(NULL);
    char starttime_str[64];
    FILE *fp;
    char canonified_fq_name[CF_BUFSIZE];

    thread_name = ThreadUniqueName();

    cf_strtimestamp_local(starttime, starttime_str);

    CfOut(cf_verbose, "", "------------------------------------------------------------------\n\n");
    CfOut(cf_verbose, "", "  LocalExec(%sscheduled) at %s\n", config->scheduled_run ? "" : "not ", starttime_str);
    CfOut(cf_verbose, "", "------------------------------------------------------------------\n");

/* Need to make sure we have LD_LIBRARY_PATH here or children will die  */

    if (strlen(config->exec_command) > 0)
    {
        strncpy(cmd, config->exec_command, CF_BUFSIZE - 1);

        if (!strstr(cmd, "-Dfrom_cfexecd"))
        {
            strcat(cmd, " -Dfrom_cfexecd");
        }
    }
    else
    {
        ConstructFailsafeCommand(config->scheduled_run, cmd);
    }

    strncpy(esc_command, MapName(cmd), CF_BUFSIZE - 1);

    snprintf(line, CF_BUFSIZE - 1, "_%jd_%s", (intmax_t) starttime, CanonifyName(cf_ctime(&starttime)));

    strlcpy(canonified_fq_name, config->fq_name, CF_BUFSIZE);
    CanonifyNameInPlace(canonified_fq_name);

    snprintf(filename, CF_BUFSIZE - 1, "%s/outputs/cf_%s_%s_%p", CFWORKDIR, canonified_fq_name, line, thread_name);
    MapName(filename);

/* What if no more processes? Could sacrifice and exec() - but we need a sentinel */

    if ((fp = fopen(filename, "w")) == NULL)
    {
        CfOut(cf_error, "fopen", "!! Couldn't open \"%s\" - aborting exec\n", filename);
        return;
    }

#if !defined(__MINGW32__)
/*
 * Don't inherit this file descriptor on fork/exec
 */

    if (fileno(fp) != -1)
    {
        fcntl(fileno(fp), F_SETFD, FD_CLOEXEC);
    }
#endif

    CfOut(cf_verbose, "", " -> Command => %s\n", cmd);

    if ((pp = cf_popen_sh(esc_command, "r")) == NULL)
    {
        CfOut(cf_error, "cf_popen", "!! Couldn't open pipe to command \"%s\"\n", cmd);
        fclose(fp);
        return;
    }

    CfOut(cf_verbose, "", " -> Command is executing...%s\n", esc_command);

    while (!feof(pp))
    {
        if(!IsReadReady(fileno(pp), (config->agent_expireafter * SECONDS_PER_MINUTE)))
        {
            char errmsg[CF_MAXVARSIZE];
            snprintf(errmsg, sizeof(errmsg), "cf-execd: !! Timeout waiting for output from agent (agent_expireafter=%d) - terminating it",
                     config->agent_expireafter);

            CfOut(cf_error, "", "%s", errmsg);
            fprintf(fp, "%s\n", errmsg);
            count++;

            pid_t pid_agent;

            if(PipeToPid(&pid_agent, pp))
            {
                ProcessSignalTerminate(pid_agent);
            }
            else
            {
                CfOut(cf_error, "", "!! Could not get PID of agent");
            }

            break;
        }

        {
            ssize_t num_read = CfReadLine(line, CF_BUFSIZE, pp);
            if (num_read == -1)
            {
                FatalError("Cannot continue on CfReadLine error");
            }
            else if (num_read == 0)
            {
                break;
            }
        }

        if(!CfReadLine(line, CF_BUFSIZE, pp))
        {
            break;
        }

        if (ferror(pp))
        {
            fflush(pp);
            break;
        }

        print = false;

        for (sp = line; *sp != '\0'; sp++)
        {
            if (!isspace((int) *sp))
            {
                print = true;
                break;
            }
        }

        if (print)
        {
            // we must escape print format chars (%) from output

            ReplaceStr(line, line_escaped, sizeof(line_escaped), "%", "%%");

            fprintf(fp, "%s\n", line_escaped);
            count++;

            /* If we can't send mail, log to syslog */

            if (strlen(config->mail_to_address) == 0)
            {
                strncat(line_escaped, "\n", sizeof(line_escaped) - 1 - strlen(line_escaped));
                if ((strchr(line_escaped, '\n')) == NULL)
                {
                    line_escaped[sizeof(line_escaped) - 2] = '\n';
                }

                CfOut(cf_inform, "", "%s", line_escaped);
            }

            line[0] = '\0';
            line_escaped[0] = '\0';
        }
    }

    cf_pclose(pp);
    CfDebug("Closing fp\n");
    fclose(fp);

    CfOut(cf_verbose, "", " -> Command is complete\n");

    if (count)
    {
        CfOut(cf_verbose, "", " -> Mailing result\n");
        MailResult(config, filename);
    }
    else
    {
        CfOut(cf_verbose, "", " -> No output\n");
        unlink(filename);
    }
}
Esempio n. 21
0
static bool IsReadReady(int fd, int timeout_sec)
{
    fd_set  rset;
    FD_ZERO(&rset);
    FD_SET(fd, &rset);

    struct timeval tv = {
        .tv_sec = timeout_sec,
        .tv_usec = 0,
    };

    int ret = select(fd + 1, &rset, NULL, NULL, &tv);

    if(ret < 0)
    {
        Log(LOG_LEVEL_ERR, "IsReadReady: Failed checking for data. (select: %s)", GetErrorStr());
        return false;
    }

    if(FD_ISSET(fd, &rset))
    {
        return true;
    }

    if(ret == 0)  // timeout
    {
        return false;
    }

    // can we get here?
    Log(LOG_LEVEL_ERR, "IsReadReady: Unknown outcome (ret > 0 but our only fd is not set). (select: %s)", GetErrorStr());

    return false;
}
#if defined(__hpux) && defined(__GNUC__)
#pragma GCC diagnostic warning "-Wstrict-aliasing"
#endif

#endif  /* __MINGW32__ */

void LocalExec(const ExecConfig *config)
{
    time_t starttime = time(NULL);

    void *thread_name = ThreadUniqueName();

    {
        char starttime_str[64];
        cf_strtimestamp_local(starttime, starttime_str);

        if (LEGACY_OUTPUT)
        {
            Log(LOG_LEVEL_VERBOSE, "------------------------------------------------------------------");
            Log(LOG_LEVEL_VERBOSE, "  LocalExec(%sscheduled) at %s", config->scheduled_run ? "" : "not ", starttime_str);
            Log(LOG_LEVEL_VERBOSE, "------------------------------------------------------------------");
        }
        else
        {
            Log(LOG_LEVEL_VERBOSE, "LocalExec(%sscheduled) at %s", config->scheduled_run ? "" : "not ", starttime_str);
        }
    }

/* Need to make sure we have LD_LIBRARY_PATH here or children will die  */

    char cmd[CF_BUFSIZE];
    if (strlen(config->exec_command) > 0)
    {
        strncpy(cmd, config->exec_command, CF_BUFSIZE - 1);

        if (!strstr(cmd, "-Dfrom_cfexecd"))
        {
            strcat(cmd, " -Dfrom_cfexecd");
        }
    }
    else
    {
        ConstructFailsafeCommand(config->scheduled_run, cmd);
    }

    char esc_command[CF_BUFSIZE];
    strncpy(esc_command, MapName(cmd), CF_BUFSIZE - 1);

    char line[CF_BUFSIZE];
    snprintf(line, CF_BUFSIZE - 1, "_%jd_%s", (intmax_t) starttime, CanonifyName(ctime(&starttime)));

    char filename[CF_BUFSIZE];
    {
        char canonified_fq_name[CF_BUFSIZE];

        strlcpy(canonified_fq_name, config->fq_name, CF_BUFSIZE);
        CanonifyNameInPlace(canonified_fq_name);


        snprintf(filename, CF_BUFSIZE - 1, "%s/outputs/cf_%s_%s_%p", CFWORKDIR, canonified_fq_name, line, thread_name);
        MapName(filename);
    }


/* What if no more processes? Could sacrifice and exec() - but we need a sentinel */

    FILE *fp = fopen(filename, "w");
    if (!fp)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open '%s' - aborting exec. (fopen: %s)", filename, GetErrorStr());
        return;
    }

#if !defined(__MINGW32__)
/*
 * Don't inherit this file descriptor on fork/exec
 */

    if (fileno(fp) != -1)
    {
        fcntl(fileno(fp), F_SETFD, FD_CLOEXEC);
    }
#endif

    Log(LOG_LEVEL_VERBOSE, "Command => %s", cmd);

    FILE *pp = cf_popen_sh(esc_command, "r");
    if (!pp)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open pipe to command '%s'. (cf_popen: %s)", cmd, GetErrorStr());
        fclose(fp);
        return;
    }

    Log(LOG_LEVEL_VERBOSE, "Command is executing...%s", esc_command);

    int count = 0;
    for (;;)
    {
        if(!IsReadReady(fileno(pp), (config->agent_expireafter * SECONDS_PER_MINUTE)))
        {
            char errmsg[CF_MAXVARSIZE];
            snprintf(errmsg, sizeof(errmsg), "cf-execd: !! Timeout waiting for output from agent (agent_expireafter=%d) - terminating it",
                     config->agent_expireafter);

            Log(LOG_LEVEL_ERR, "%s", errmsg);
            fprintf(fp, "%s\n", errmsg);
            count++;

            pid_t pid_agent;

            if(PipeToPid(&pid_agent, pp))
            {
                ProcessSignalTerminate(pid_agent);
            }
            else
            {
                Log(LOG_LEVEL_ERR, "Could not get PID of agent");
            }

            break;
        }

        ssize_t res = CfReadLine(line, CF_BUFSIZE, pp);

        if (res == 0)
        {
            break;
        }

        if (res == -1)
        {
            Log(LOG_LEVEL_ERR, "Unable to read output from command '%s'. (cfread: %s)", cmd, GetErrorStr());
            cf_pclose(pp);
            return;
        }

        bool print = false;

        for (const char *sp = line; *sp != '\0'; sp++)
        {
            if (!isspace((int) *sp))
            {
                print = true;
                break;
            }
        }

        if (print)
        {
            char line_escaped[sizeof(line) * 2];

            // we must escape print format chars (%) from output

            ReplaceStr(line, line_escaped, sizeof(line_escaped), "%", "%%");

            fprintf(fp, "%s\n", line_escaped);
            count++;

            /* If we can't send mail, log to syslog */

            if (strlen(config->mail_to_address) == 0)
            {
                strncat(line_escaped, "\n", sizeof(line_escaped) - 1 - strlen(line_escaped));
                if ((strchr(line_escaped, '\n')) == NULL)
                {
                    line_escaped[sizeof(line_escaped) - 2] = '\n';
                }

                Log(LOG_LEVEL_INFO, "%s", line_escaped);
            }

            line[0] = '\0';
            line_escaped[0] = '\0';
        }
    }

    cf_pclose(pp);
    Log(LOG_LEVEL_DEBUG, "Closing fp");
    fclose(fp);

    Log(LOG_LEVEL_VERBOSE, "Command is complete");

    if (count)
    {
        Log(LOG_LEVEL_VERBOSE, "Mailing result");
        MailResult(config, filename);
    }
    else
    {
        Log(LOG_LEVEL_VERBOSE, "No output");
        unlink(filename);
    }
}
Esempio n. 22
0
void GenericAgentDiscoverContext(EvalContext *ctx, GenericAgentConfig *config)
{
    GenericAgentInitialize(ctx, config);

    SetReferenceTime(ctx, true);
    SetStartTime();
    SanitizeEnvironment();

    THIS_AGENT_TYPE = config->agent_type;
    EvalContextHeapAddHard(ctx, CF_AGENTTYPES[config->agent_type]);

    GenericAgentSetDefaultDigest(&CF_DEFAULT_DIGEST, &CF_DEFAULT_DIGEST_LEN);

    GetNameInfo3(ctx, config->agent_type);
    GetInterfacesInfo(ctx);

    Get3Environment(ctx, config->agent_type);
    BuiltinClasses(ctx);
    OSClasses(ctx);

    EvalContextHeapPersistentLoadAll(ctx);
    LoadSystemConstants(ctx);

    if (config->agent_type == AGENT_TYPE_AGENT && config->agent_specific.agent.bootstrap_policy_server)
    {
        if (!RemoveAllExistingPolicyInInputs(GetWorkDir()))
        {
            Log(LOG_LEVEL_ERR, "Error removing existing input files prior to bootstrap");
            exit(EXIT_FAILURE);
        }

        if (!WriteBuiltinFailsafePolicy(GetWorkDir()))
        {
            Log(LOG_LEVEL_ERR, "Error writing builtin failsafe to inputs prior to bootstrap");
            exit(EXIT_FAILURE);
        }

        bool am_policy_server = false;
        {
            const char *canonified_bootstrap_policy_server = CanonifyName(config->agent_specific.agent.bootstrap_policy_server);
            am_policy_server = IsDefinedClass(ctx, canonified_bootstrap_policy_server, NULL);
            {
                char policy_server_ipv4_class[CF_BUFSIZE];
                snprintf(policy_server_ipv4_class, CF_MAXVARSIZE, "ipv4_%s", canonified_bootstrap_policy_server);
                am_policy_server |= IsDefinedClass(ctx, policy_server_ipv4_class, NULL);
            }

            if (am_policy_server)
            {
                Log(LOG_LEVEL_INFO, "Assuming role as policy server, with policy distribution point at %s/masterfiles", GetWorkDir());
                EvalContextHeapAddHard(ctx, "am_policy_hub");

                if (!MasterfileExists(GetWorkDir()))
                {
                    Log(LOG_LEVEL_ERR, "In order to bootstrap as a policy server, the file '%s/masterfiles/promises.cf' must exist.", GetWorkDir());
                    exit(EXIT_FAILURE);
                }
            }
            else
            {
                Log(LOG_LEVEL_INFO, "Not assuming role as policy server");
            }

            WriteAmPolicyHubFile(CFWORKDIR, am_policy_server);
        }

        WritePolicyServerFile(GetWorkDir(), config->agent_specific.agent.bootstrap_policy_server);
        SetPolicyServer(ctx, config->agent_specific.agent.bootstrap_policy_server);
        Log(LOG_LEVEL_INFO, "Bootstrapping to '%s'", POLICY_SERVER);
    }
    else
    {
        char *existing_policy_server = ReadPolicyServerFile(GetWorkDir());
        if (existing_policy_server)
        {
            Log(LOG_LEVEL_VERBOSE, "This agent is bootstrapped to '%s'", existing_policy_server);
        }
        else
        {
            Log(LOG_LEVEL_VERBOSE, "This agent is not bootstrapped");
        }
        SetPolicyServer(ctx, existing_policy_server);

        if (GetAmPolicyHub(GetWorkDir()))
        {
            EvalContextHeapAddHard(ctx, "am_policy_hub");  // DEPRECATED: use policy_server instead
            Log(LOG_LEVEL_VERBOSE, "Additional class defined: am_policy_hub");
            EvalContextHeapAddHard(ctx, "policy_server");
            Log(LOG_LEVEL_VERBOSE, "Additional class defined: policy_server");
        }
    }
}
Esempio n. 23
0
int NewPromiseProposals()

{ struct Rlist *rp,*sl;
  struct stat sb;
  int result = false;
  char filename[CF_MAXVARSIZE];

if (MINUSF)
   {
   snprintf(filename,CF_MAXVARSIZE,"%s/state/validated_%s",CFWORKDIR,CanonifyName(VINPUTFILE));
   MapName(filename);   
   }
else
   {
   snprintf(filename,CF_MAXVARSIZE,"%s/masterfiles/cf_promises_validated",CFWORKDIR);
   MapName(filename);
   }
  
if (stat(filename,&sb) != -1)
   {
   PROMISETIME = sb.st_mtime;
   }
else
   {
   PROMISETIME = 0;
   }


// sanity check

if(PROMISETIME > time(NULL))
   {
   CfOut(cf_inform, "", "!! Clock seems to have jumped back in time - mtime of %s is newer than current time - touching it", filename);
   
   if(utime(filename,NULL) == -1)
      {
      CfOut(cf_error, "utime", "!! Could not touch %s", filename);
      }

   PROMISETIME = 0;
   return true;
   }

if (cfstat(InputLocation(VINPUTFILE),&sb) == -1)
   {
   CfOut(cf_verbose,"stat","There is no readable input file at %s",VINPUTFILE);
   return true;
   }

if (sb.st_mtime > PROMISETIME)
   {
   CfOut(cf_verbose,""," -> Promises seem to change");
   return true;
   }

// Check the directories first for speed and because non-input/data files should trigger an update

snprintf(filename,CF_MAXVARSIZE,"%s/inputs",CFWORKDIR);
MapName(filename);

if (IsNewerFileTree(filename,PROMISETIME))
   {
   CfOut(cf_verbose,""," -> Quick search detected file changes");
   return true;
   }

// Check files in case there are any abs paths

if (VINPUTLIST != NULL)
   {
   for (rp = VINPUTLIST; rp != NULL; rp=rp->next)
      {
      if (rp->type != CF_SCALAR)
         {
         CfOut(cf_error,"","Non file object %s in list\n",(char *)rp->item);
         }
      else
         {
         struct Rval returnval = EvaluateFinalRval("sys",rp->item,rp->type,true,NULL);

         switch (returnval.rtype)
            {
            case CF_SCALAR:

                if (cfstat(InputLocation((char *)returnval.item),&sb) == -1)
                   {
                   CfOut(cf_error,"stat","Unreadable promise proposals at %s",(char *)returnval.item);
                   result = true;
                   break;
                   }

                if (sb.st_mtime > PROMISETIME)
                   {
                   result = true;
                   }

                break;

            case CF_LIST:

                for (sl = (struct Rlist *)returnval.item; sl != NULL; sl=sl->next)
                   {
                   if (cfstat(InputLocation((char *)sl->item),&sb) == -1)
                      {
                      CfOut(cf_error,"stat","Unreadable promise proposals at %s",(char *)sl->item);
                      result = true;
                      break;
                      }

                   if (sb.st_mtime > PROMISETIME)
                      {
                      result = true;
                      break;
                      }
                   }

                break;
            }

         DeleteRvalItem(returnval.item,returnval.rtype);

         if (result)
            {
            break;
            }
         }
      }
   }

// did policy server change (used in $(sys.policy_hub))?
snprintf(filename,CF_MAXVARSIZE,"%s/policy_server.dat",CFWORKDIR);
MapName(filename);

if ((cfstat(filename,&sb) != -1) && (sb.st_mtime > PROMISETIME))
   {
   result = true;
   }

return result | ALWAYS_VALIDATE;
}
Esempio n. 24
0
void MonNetworkGatherData(double *cf_this)
{
    FILE *pp;
    char local[CF_BUFSIZE], remote[CF_BUFSIZE], comm[CF_BUFSIZE];
    Item *in[ATTR], *out[ATTR];
    char *sp;
    int i;
    enum cf_netstat_type { cfn_new, cfn_old } type = cfn_new;
    enum cf_packet_type { cfn_udp4, cfn_udp6, cfn_tcp4, cfn_tcp6} packet = cfn_tcp4;

    for (i = 0; i < ATTR; i++)
    {
        in[i] = out[i] = NULL;
    }

    DeleteItemList(ALL_INCOMING);
    ALL_INCOMING = NULL;

    sscanf(VNETSTAT[VSYSTEMHARDCLASS], "%s", comm);

    strcat(comm, " -an");

    if ((pp = cf_popen(comm, "r", true)) == NULL)
    {
        /* FIXME: no logging */
        return;
    }

    size_t vbuff_size = CF_BUFSIZE;
    char *vbuff = xmalloc(vbuff_size);

    for (;;)
    {
        memset(local, 0, CF_BUFSIZE);
        memset(remote, 0, CF_BUFSIZE);

        size_t res = CfReadLine(&vbuff, &vbuff_size, pp);
        if (res == -1)
        {
            if (!feof(pp))
            {
                /* FIXME: no logging */
                cf_pclose(pp);
                free(vbuff);
                return;
            }
            else
            {
                break;
            }
        }

        if (strstr(vbuff, "UNIX"))
        {
            break;
        }

        if (!((strstr(vbuff, ":")) || (strstr(vbuff, "."))))
        {
            continue;
        }

        /* Different formats here ... ugh.. pick a model */

        // If this is old style, we look for chapter headings, e.g. "TCP: IPv4"

        if ((strncmp(vbuff,"UDP:",4) == 0) && (strstr(vbuff+4,"6")))
        {
            packet = cfn_udp6;
            type = cfn_old;
            continue;
        }
        else if ((strncmp(vbuff,"TCP:",4) == 0) && (strstr(vbuff+4,"6")))
        {
            packet = cfn_tcp6;
            type = cfn_old;
            continue;
        }
        else if ((strncmp(vbuff,"UDP:",4) == 0) && (strstr(vbuff+4,"4")))
        {
            packet = cfn_udp4;
            type = cfn_old;
            continue;
        }
        else if ((strncmp(vbuff,"TCP:",4) == 0) && (strstr(vbuff+4,"4")))
        {
            packet = cfn_tcp4;
            type = cfn_old;
            continue;
        }

        // Line by line state in modern/linux output

        if (strncmp(vbuff,"udp6",4) == 0)
        {
            packet = cfn_udp6;
            type = cfn_new;
        }
        else if (strncmp(vbuff,"tcp6",4) == 0)
        {
            packet = cfn_tcp6;
            type = cfn_new;
        }
        else if (strncmp(vbuff,"udp",3) == 0)
        {
            packet = cfn_udp4;
            type = cfn_new;
        }
        else if (strncmp(vbuff,"tcp",3) == 0)
        {
            packet = cfn_tcp4;
            type = cfn_new;
        }

        // End extract type
        
        switch (type)
        {
        case cfn_new:  sscanf(vbuff, "%*s %*s %*s %s %s", local, remote);  /* linux-like */
            break;
            
        case cfn_old:
            sscanf(vbuff, "%s %s", local, remote);
            break;
        }

        if (strlen(local) == 0)
        {
            continue;
        }

        // Extract the port number from the end of the string

        for (sp = local + strlen(local); (*sp != '.') && (*sp != ':')  && (sp > local); sp--)
        {
        }

        *sp = '\0'; // Separate address from port number
        sp++;

        char *localport = sp;
        
        if (strstr(vbuff, "LISTEN"))
        {
            // General bucket

            IdempPrependItem(&ALL_INCOMING, sp, NULL);

            // Categories the incoming ports by packet types

            switch (packet)
            {
            case cfn_udp4:
                IdempPrependItem(&MON_UDP4, sp, local);
                break;
            case cfn_udp6:
                IdempPrependItem(&MON_UDP6, sp, local);
                break;
            case cfn_tcp4:
                IdempPrependItem(&MON_TCP4, localport, local);
                break;
            case cfn_tcp6:
                IdempPrependItem(&MON_TCP6, localport, local);
                break;
            default:
                break;
            }
        }


        // Now look at outgoing
        
        for (sp = remote + strlen(remote) - 1; (sp >= remote) && (isdigit((int) *sp)); sp--)
        {
        }

        sp++;
        char *remoteport = sp;

        // Now look for the specific vital signs to count frequencies
            
        for (i = 0; i < ATTR; i++)
        {
            if (strcmp(localport, ECGSOCKS[i].portnr) == 0)
            {
                cf_this[ECGSOCKS[i].in]++;
                AppendItem(&in[i], vbuff, "");

            }

            if (strcmp(remoteport, ECGSOCKS[i].portnr) == 0)
            {
                cf_this[ECGSOCKS[i].out]++;
                AppendItem(&out[i], vbuff, "");

            }
        }
    }

    cf_pclose(pp);

/* Now save the state for ShowState() 
   the state is not smaller than the last or at least 40 minutes
   older. This mirrors the persistence of the maxima classes */

    for (i = 0; i < ATTR; i++)
    {
        struct stat statbuf;
        time_t now = time(NULL);

        Log(LOG_LEVEL_DEBUG, "save incoming '%s'", ECGSOCKS[i].name);
        snprintf(vbuff, CF_MAXVARSIZE, "%s/state/cf_incoming.%s", CFWORKDIR, ECGSOCKS[i].name);
        if (stat(vbuff, &statbuf) != -1)
        {
            if (ItemListSize(in[i]) < statbuf.st_size &&
                now < statbuf.st_mtime + 40 * 60)
            {
                Log(LOG_LEVEL_VERBOSE, "New state '%s' is smaller, retaining old for 40 mins longer", ECGSOCKS[i].name);
                DeleteItemList(in[i]);
                continue;
            }
        }

        SetNetworkEntropyClasses(CanonifyName(ECGSOCKS[i].name), "in", in[i]);
        RawSaveItemList(in[i], vbuff);
        DeleteItemList(in[i]);
        Log(LOG_LEVEL_DEBUG, "Saved in netstat data in '%s'", vbuff);
    }

    for (i = 0; i < ATTR; i++)
    {
        struct stat statbuf;
        time_t now = time(NULL);

        Log(LOG_LEVEL_DEBUG, "save outgoing '%s'", ECGSOCKS[i].name);
        snprintf(vbuff, CF_MAXVARSIZE, "%s/state/cf_outgoing.%s", CFWORKDIR, ECGSOCKS[i].name);

        if (stat(vbuff, &statbuf) != -1)
        {
            if (ItemListSize(out[i]) < statbuf.st_size &&
                now < statbuf.st_mtime + 40 * 60)
            {
                Log(LOG_LEVEL_VERBOSE, "New state '%s' is smaller, retaining old for 40 mins longer", ECGSOCKS[i].name);
                DeleteItemList(out[i]);
                continue;
            }
        }

        SetNetworkEntropyClasses(CanonifyName(ECGSOCKS[i].name), "out", out[i]);
        RawSaveItemList(out[i], vbuff);
        Log(LOG_LEVEL_DEBUG, "Saved out netstat data in '%s'", vbuff);
        DeleteItemList(out[i]);
    }

    free(vbuff);
}
Esempio n. 25
0
void CheckAutoBootstrap()
{
    struct stat sb;
    char name[CF_BUFSIZE];
    int repaired = false, have_policy = false, am_appliance = false;

    CfOut(cf_cmdout, "", "** CFEngine BOOTSTRAP probe initiated");

    PrintVersionBanner("CFEngine");
    printf("\n");

    printf(" -> This host is: %s\n", VSYSNAME.nodename);
    printf(" -> Operating System Type is %s\n", VSYSNAME.sysname);
    printf(" -> Operating System Release is %s\n", VSYSNAME.release);
    printf(" -> Architecture = %s\n", VSYSNAME.machine);
    printf(" -> Internal soft-class is %s\n", CLASSTEXT[VSYSTEMHARDCLASS]);

    if (!BootstrapAllowed())
    {
        FatalError(" !! Not enough privileges to bootstrap CFEngine");
    }

    snprintf(name, CF_BUFSIZE - 1, "%s/inputs/failsafe.cf", CFWORKDIR);
    MapName(name);

    if (cfstat(name, &sb) == -1)
    {
        CreateFailSafe(name);
        repaired = true;
    }

    snprintf(name, CF_BUFSIZE - 1, "%s/inputs/promises.cf", CFWORKDIR);
    MapName(name);

    if (cfstat(name, &sb) == -1)
    {
        CfOut(cf_cmdout, "", " -> No previous policy has been cached on this host");
    }
    else
    {
        CfOut(cf_cmdout, "", " -> An existing policy was cached on this host in %s/inputs", CFWORKDIR);
        have_policy = true;
    }

    if (strlen(POLICY_SERVER) > 0)
    {
        CfOut(cf_cmdout, "", " -> Assuming the policy distribution point at: %s:/var/cfengine/masterfiles\n",
              POLICY_SERVER);
    }
    else
    {
        if (have_policy)
        {
            CfOut(cf_cmdout, "",
                  " -> No policy distribution host was discovered - it might be contained in the existing policy, otherwise this will function autonomously\n");
        }
        else if (repaired)
        {
            CfOut(cf_cmdout, "", " -> No policy distribution host was defined - use --policy-server to set one\n");
        }
    }

    printf(" -> Attempting to initiate promised autonomous services...\n\n");

    am_appliance = IsDefinedClass(CanonifyName(POLICY_SERVER), NULL);
    snprintf(name, CF_MAXVARSIZE, "ipv4_%s", CanonifyName(POLICY_SERVER));
    am_appliance |= IsDefinedClass(name, NULL);

    if (strlen(POLICY_SERVER) == 0)
    {
        am_appliance = false;
    }

    snprintf(name, sizeof(name), "%s/state/am_policy_hub", CFWORKDIR);
    MapName(name);

    if (am_appliance)
    {
        HardClass("am_policy_hub");
        printf
        (" ** This host recognizes itself as a CFEngine Policy Hub, with policy distribution and knowledge base.\n");
        printf
        (" -> The system is now converging. Full initialisation and self-analysis could take up to 30 minutes\n\n");
        creat(name, 0600);
    }
    else
    {
        unlink(name);
    }
}
Esempio n. 26
0
PromiseResult VerifyClassPromise(EvalContext *ctx, const Promise *pp, ARG_UNUSED void *param)
{
    assert(param == NULL);

    Attributes a = GetClassContextAttributes(ctx, pp);

    if (!StringMatchFull("[a-zA-Z0-9_]+", pp->promiser))
    {
        Log(LOG_LEVEL_VERBOSE, "Class identifier '%s' contains illegal characters - canonifying", pp->promiser);
        xsnprintf(pp->promiser, strlen(pp->promiser) + 1, "%s", CanonifyName(pp->promiser));
    }

    if (a.context.nconstraints == 0)
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "No constraints for class promise '%s'", pp->promiser);
        return PROMISE_RESULT_FAIL;
    }

    if (a.context.nconstraints > 1)
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Irreconcilable constraints in classes for '%s'", pp->promiser);
        return PROMISE_RESULT_FAIL;
    }

    if (EvalClassExpression(ctx, a.context.expression, pp))
    {
        if (!ValidClassName(pp->promiser))
        {
            cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a,
                 "Attempted to name a class '%s', which is an illegal class identifier", pp->promiser);
            return PROMISE_RESULT_FAIL;
        }
        else
        {
            char *tags = NULL;
            {
                Buffer *tag_buffer = BufferNew();
                BufferAppendString(tag_buffer, "classes promise,attribute_name=label,source=promise");

                for (const Rlist *rp = PromiseGetConstraintAsList(ctx, "meta", pp); rp; rp = rp->next)
                {
                    BufferAppendChar(tag_buffer, ',');
                    BufferAppendString(tag_buffer, RlistScalarValue(rp));
                }

                tags = BufferClose(tag_buffer);
            }

            if (/* Persistent classes are always global: */
                a.context.persistent > 0 ||
                /* Namespace-scope is global: */
                a.context.scope == CONTEXT_SCOPE_NAMESPACE ||
                /* If there is no explicit scope, common bundles define global
                 * classes, other bundles define local classes: */
                (a.context.scope == CONTEXT_SCOPE_NONE &&
                 0 == strcmp(PromiseGetBundle(pp)->type, "common")))
            {
                Log(LOG_LEVEL_VERBOSE, "C:     +  Global class: %s ", pp->promiser);
                EvalContextClassPutSoft(ctx, pp->promiser, CONTEXT_SCOPE_NAMESPACE, tags);
            }
            else
            {
                Log(LOG_LEVEL_VERBOSE, "C:     +  Private class: %s ", pp->promiser);
                EvalContextClassPutSoft(ctx, pp->promiser, CONTEXT_SCOPE_BUNDLE, tags);
            }

            if (a.context.persistent > 0)
            {
                Log(LOG_LEVEL_VERBOSE, "C:     +  Persistent class: '%s'. (%d minutes)", pp->promiser, a.context.persistent);
                EvalContextHeapPersistentSave(ctx, pp->promiser, a.context.persistent,
                                              CONTEXT_STATE_POLICY_RESET, tags);
            }

            free(tags);

            return PROMISE_RESULT_NOOP;
        }
    }

    return PROMISE_RESULT_NOOP;
}
Esempio n. 27
0
void
GetNameInfo(void)
{
    int i, found = false;
    char *sp, *sp2;
    time_t tloc;
    struct hostent *hp;
    struct sockaddr_in cin;
#ifdef AIX
    char real_version[_SYS_NMLN];
#endif
#ifdef IRIX
    char real_version[256]; /* see <sys/syssgi.h> */
#endif
#ifdef HAVE_SYSINFO
#ifdef SI_ARCHITECTURE
    long sz;
#endif
#endif

    Debug("GetNameInfo()\n");

    g_vfqname[0] = g_vuqname[0] = '\0';

    if (uname(&g_vsysname) == -1) {
        perror("uname ");
        FatalError("Uname couldn't get kernel name info!!\n");
    }

#ifdef AIX
    snprintf(real_version, _SYS_NMLN, "%.80s.%.80s",
            g_vsysname.version, g_vsysname.release);
    strncpy(g_vsysname.release, real_version, _SYS_NMLN);
#elif defined IRIX
/* This gets us something like `6.5.19m' rather than just `6.5'.  */
    syssgi (SGI_RELEASE_NAME, 256, real_version);
#endif

    for (sp = g_vsysname.sysname; *sp != '\0'; sp++) {
        *sp = ToLower(*sp);
    }

    for (sp = g_vsysname.machine; *sp != '\0'; sp++) {
        *sp = ToLower(*sp);
    }

    for (i = 0; g_classattributes[i][0] != '\0'; i++) {

        if (WildMatch(g_classattributes[i][0],
                    ToLowerStr(g_vsysname.sysname))) {

            if (WildMatch(g_classattributes[i][1], 
                        g_vsysname.machine)) {

                if (WildMatch(g_classattributes[i][2], 
                            g_vsysname.release)) {

                    if (g_underscore_classes) {
                        snprintf(g_vbuff, CF_BUFSIZE, "_%s", g_classtext[i]);
                        AddClassToHeap(g_vbuff);
                    } else {
                        AddClassToHeap(g_classtext[i]);
                    }
                    found = true;
                    g_vsystemhardclass = (enum classes) i;
                    break;
                }
            } else {
                Debug2("Cfengine: I recognize %s but not %s\n",
                        g_vsysname.sysname, g_vsysname.machine);
                    continue;
            }
        }
   }

    if ((sp = malloc(strlen(g_vsysname.nodename)+1)) == NULL) {
        FatalError("malloc failure in initialize()");
    }

    strcpy(sp, g_vsysname.nodename);
    SetDomainName(sp);

    /* Truncate fully qualified name */
    for (sp2=sp; *sp2 != '\0'; sp2++) {
        if (*sp2 == '.') {
            *sp2 = '\0';
            Debug("Truncating fully qualified hostname %s to %s\n",
                    g_vsysname.nodename,sp);
            break;
        }
    }

    g_vdefaultbinserver.name = sp;

    AddClassToHeap(CanonifyName(sp));


    if ((tloc = time((time_t *)NULL)) == -1) {
        printf("Couldn't read system clock\n");
    }

    if (g_verbose || g_debug || g_d2 || g_d3) {
        if (g_underscore_classes) {
            snprintf(g_vbuff, CF_BUFSIZE, "_%s", g_classtext[i]);
        } else {
            snprintf(g_vbuff, CF_BUFSIZE, "%s", g_classtext[i]);
        }

        if (g_iscfengine) {
            printf ("cfng: configuration agent (cfagent) - \n%s\n%s\n\n",
                    VERSION, g_copyright);
        } else {
            printf ("cfng: configuration server (cfservd) - \n%s\n%s\n\n",
                    VERSION, g_copyright);
        }

        printf ("------------------------------------------------------------------------\n\n");
        printf ("Host name is: %s\n", g_vsysname.nodename);
        printf ("Operating System Type is %s\n", g_vsysname.sysname);
        printf ("Operating System Release is %s\n", g_vsysname.release);
        printf ("Architecture = %s\n\n\n", g_vsysname.machine);
        printf ("Using internal soft-class %s for host %s\n\n",
                g_vbuff, g_classtext[g_vsystemhardclass]);
        printf ("The time is now %s\n\n", ctime(&tloc));
        printf ("------------------------------------------------------------------------\n\n");

    }

    sprintf(g_vbuff, "%d_bit", sizeof(long)*8);
    AddClassToHeap(g_vbuff);
    Verbose("Additional hard class defined as: %s\n", CanonifyName(g_vbuff));

    snprintf(g_vbuff, CF_BUFSIZE, "%s_%s", g_vsysname.sysname,
            g_vsysname.release);
    AddClassToHeap(CanonifyName(g_vbuff));

#ifdef IRIX
    /* 
     * Get something like `irix64_6_5_19m' defined as well as
     * `irix64_6_5'.  Just copying the latter into g_vsysname.release
     * wouldn't be backwards-compatible.
     */
    snprintf(g_vbuff, CF_BUFSIZE, "%s_%s", g_vsysname.sysname, real_version);
    AddClassToHeap(CanonifyName(g_vbuff));
#endif

    AddClassToHeap(CanonifyName(g_vsysname.machine));

    Verbose("Additional hard class defined as: %s\n",CanonifyName(g_vbuff));

    snprintf(g_vbuff, CF_BUFSIZE,"%s_%s", g_vsysname.sysname,
            g_vsysname.machine);
    AddClassToHeap(CanonifyName(g_vbuff));

    Verbose("Additional hard class defined as: %s\n",CanonifyName(g_vbuff));

    snprintf(g_vbuff, CF_BUFSIZE, "%s_%s_%s",
            g_vsysname.sysname, g_vsysname.machine, g_vsysname.release);

    AddClassToHeap(CanonifyName(g_vbuff));

    Verbose("Additional hard class defined as: %s\n", CanonifyName(g_vbuff));

#ifdef HAVE_SYSINFO
#ifdef SI_ARCHITECTURE
    sz = sysinfo(SI_ARCHITECTURE, g_vbuff, CF_BUFSIZE);
    if (sz == -1) {
        Verbose("cfagent internal: sysinfo returned -1\n");
    } else {
        AddClassToHeap(CanonifyName(g_vbuff));
        Verbose("Additional hard class defined as: %s\n", g_vbuff);
    }
#endif
#endif

    snprintf(g_vbuff, CF_BUFSIZE, "%s_%s_%s_%s",
            g_vsysname.sysname, g_vsysname.machine, g_vsysname.release,
            g_vsysname.version);

    if (strlen(g_vbuff) < CF_MAXVARSIZE-2) {
        g_varch = strdup(CanonifyName(g_vbuff));
    } else {

        Verbose("cfagent internal: $(arch) overflows CF_MAXVARSIZE! Truncating\n");
        g_varch = strdup(CanonifyName(g_vsysname.sysname));
    }

    snprintf(g_vbuff, CF_BUFSIZE, "%s_%s",
            g_vsysname.sysname, g_vsysname.machine);

    g_varch2 = strdup(CanonifyName(g_vbuff));

    AddClassToHeap(g_varch);

    Verbose("Additional hard class defined as: %s\n", g_varch);

    if (! found) {

        CfLog(cferror,"Cfengine: I don't understand "
                "what architecture this is!","");

    }

    strcpy(g_vbuff, "compiled_on_");
    strcat(g_vbuff, CanonifyName(AUTOCONF_SYSNAME));

    AddClassToHeap(CanonifyName(g_vbuff));

    Verbose("\nGNU autoconf class from compile time: %s\n\n", g_vbuff);

    /* Get IP address from nameserver */
    if ((hp = gethostbyname(g_vsysname.nodename)) == NULL) {
        return;
    } else {
        memset(&cin, 0, sizeof(cin));
        cin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
        Verbose("Address given by nameserver: %s\n", inet_ntoa(cin.sin_addr));
        strcpy(g_vipaddress, inet_ntoa(cin.sin_addr));

        for (i=0; hp->h_aliases[i] != NULL; i++) {
            Debug("Adding alias %s..\n", hp->h_aliases[i]);
            AddClassToHeap(CanonifyName(hp->h_aliases[i]));
        }
    }
}
Esempio n. 28
0
File: link.c Progetto: kbarber/cfng
/* should return true if 'to' found */
int
HardLinkFiles(char *from, char *to,
    struct Item *inclusions, struct Item *exclusions, struct Item *copy,
    short nofile, struct Link *ptr)
{

    struct stat frombuf,tobuf;
    char saved[CF_BUFSIZE], *lastnode;
    struct UidList fakeuid;
    struct Image ip;
    char stamp[CF_BUFSIZE];
    time_t STAMPNOW;
    STAMPNOW = time((time_t *)NULL);

    for (lastnode = from+strlen(from); *lastnode != '/'; lastnode--) { }

    lastnode++;

    if (inclusions != NULL && !IsWildItemIn(inclusions,lastnode)) {
        Verbose("%s: Skipping non-included pattern %s\n",g_vprefix,from);
        return true;
    }

    if (IsWildItemIn(g_vexcludelink,lastnode) ||
            IsWildItemIn(exclusions,lastnode)) {

        Verbose("%s: Skipping excluded pattern %s\n",g_vprefix,from);
        return true;
    }

    if (IsWildItemIn(g_vcopylinks,lastnode) || IsWildItemIn(copy,lastnode)) {
        fakeuid.uid = CF_SAME_OWNER;
        fakeuid.next = NULL;
        ip.plus = CF_SAMEMODE;
        ip.minus = CF_SAMEMODE;
        ip.uid = &fakeuid;
        ip.gid = (struct GidList *) &fakeuid;
        ip.action = "do";
        ip.recurse = 0;
        ip.type = 't';
        ip.backup = true;
        ip.plus_flags = 0;
        ip.minus_flags = 0;
        ip.exclusions = NULL;
        ip.symlink = NULL;
        Verbose("%s: Link item %s marked for copying instead\n",
                g_vprefix, from);
        CheckImage(to,from,&ip);
        return true;
    }

    if (stat(to,&tobuf) == -1) {
        /* no error warning, since the higher level routine uses this */
        return(false);
    }

    if (! S_ISREG(tobuf.st_mode)) {

        snprintf(g_output, CF_BUFSIZE*2,
                "%s: will only hard link regular files "
                "and %s is not regular\n", g_vprefix, to);

        CfLog(cfsilent,g_output,"");
        return true;
    }

    Debug2("Trying to (hard) link %s -> %s\n",from,to);

    if (stat(from,&frombuf) == -1) {
        DoHardLink(from,to,ptr->defines);
        return true;
    }

    /* 
     * Both files exist, but are they the same file? POSIX says the
     * files could be on different devices, but unix doesn't allow this
     * behaviour so the tests below are theoretical...
     */

    if (frombuf.st_ino != tobuf.st_ino && frombuf.st_dev != frombuf.st_dev) {
        Verbose("If this is POSIX, unable to determine if %s is "
                "hard link is correct\n", from);
        Verbose("since it points to a different filesystem!\n");

        if (frombuf.st_mode == tobuf.st_mode &&
                frombuf.st_size == tobuf.st_size) {

            snprintf(g_output,CF_BUFSIZE*2,
                    "Hard link (%s->%s) on different device APPEARS okay\n",
                    from,to);

            CfLog(cfverbose,g_output,"");
            AddMultipleClasses(ptr->elsedef);
            return true;
        }
    }

    if (frombuf.st_ino == tobuf.st_ino && frombuf.st_dev == frombuf.st_dev) {

        snprintf(g_output,CF_BUFSIZE*2,
                "Hard link (%s->%s) exists and is okay.\n",from,to);

        CfLog(cfverbose,g_output,"");
        AddMultipleClasses(ptr->elsedef);
        return true;
    }

    snprintf(g_output,CF_BUFSIZE*2,
            "%s does not appear to be a hard link to %s\n",from,to);

    CfLog(cfinform,g_output,"");

    if (g_enforcelinks) {
        snprintf(g_output, CF_BUFSIZE*2, 
                "Moving %s to %s.%s\n", from, from, CF_SAVED);
        CfLog(cfinform,g_output,"");

        if (g_dontdo) {
            return true;
        }

        saved[0] = '\0';
        strcpy(saved,from);

        sprintf(stamp, "_%d_%s", g_cfstarttime, 
                CanonifyName(ctime(&STAMPNOW)));
        strcat(saved,stamp);

        strcat(saved,CF_SAVED);

        if (rename(from,saved) == -1) {
            perror("rename");
            return(true);
        }

        DoHardLink(from,to,ptr->defines);
    }

    return(true);
}
Esempio n. 29
0
void VerifyClassPromise(EvalContext *ctx, Promise *pp, ARG_UNUSED void *param)
{
    assert(param == NULL);

    Attributes a;

    a = GetClassContextAttributes(ctx, pp);

    if (!FullTextMatch("[a-zA-Z0-9_]+", pp->promiser))
    {
        Log(LOG_LEVEL_VERBOSE, "Class identifier '%s' contains illegal characters - canonifying", pp->promiser);
        snprintf(pp->promiser, strlen(pp->promiser) + 1, "%s", CanonifyName(pp->promiser));
    }

    if (a.context.nconstraints == 0)
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "No constraints for class promise '%s'", pp->promiser);
        return;
    }

    if (a.context.nconstraints > 1)
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Irreconcilable constraints in classes for '%s'", pp->promiser);
        return;
    }

    bool global_class;
    if (a.context.persistent > 0) /* Persistent classes are always global */
    {
        global_class = true;
    }
    else if (a.context.scope == CONTEXT_SCOPE_NONE)
    {
        /* If there is no explicit scope, common bundles define global classes, other bundles define local classes */
        if (strcmp(PromiseGetBundle(pp)->type, "common") == 0)
        {
            global_class = true;
        }
        else
        {
            global_class = false;
        }
    }
    else if (a.context.scope == CONTEXT_SCOPE_NAMESPACE)
    {
        global_class = true;
    }
    else if (a.context.scope == CONTEXT_SCOPE_BUNDLE)
    {
        global_class = false;
    }

    if (EvalClassExpression(ctx, a.context.expression, pp))
    {
        if (!ValidClassName(pp->promiser))
        {
            cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a,
                 "Attempted to name a class '%s', which is an illegal class identifier", pp->promiser);
        }
        else
        {
            if (global_class)
            {
                Log(LOG_LEVEL_VERBOSE, "Adding global class '%s'", pp->promiser);
                EvalContextHeapAddSoft(ctx, pp->promiser, PromiseGetNamespace(pp));
            }
            else
            {
                Log(LOG_LEVEL_VERBOSE, "Adding local bundle class '%s'", pp->promiser);
                EvalContextStackFrameAddSoft(ctx, pp->promiser);
            }

            if (a.context.persistent > 0)
            {
                Log(LOG_LEVEL_VERBOSE, "Adding persistent class '%s'. (%d minutes)", pp->promiser,
                      a.context.persistent);
                EvalContextHeapPersistentSave(pp->promiser, PromiseGetNamespace(pp), a.context.persistent, CONTEXT_STATE_POLICY_RESET);
            }
        }
    }
}
Esempio n. 30
0
void IDClasses()

{ struct stat statbuf;
  char *sp;
  int i = 0;

AddClassToHeap("any");      /* This is a reserved word / wildcard */
 
snprintf(VBUFF,CF_BUFSIZE,"cfengine_%s",CanonifyName(VERSION));
AddClassToHeap(VBUFF);
 
for (sp = VBUFF+strlen(VBUFF); i < 2; sp--)
   {
   if (*sp == '_')
      {
      i++;
      *sp = '\0';
      AddClassToHeap(VBUFF);
      }
   }

#ifdef LINUX

/* {Mandrake,Fedora} has a symlink at /etc/redhat-release pointing to
 * /etc/{mandrake,fedora}-release, so we else-if around that
 */

if (stat("/etc/mandrake-release",&statbuf) != -1)
   {
   Verbose("This appears to be a mandrake system.\n");
   AddClassToHeap("Mandrake");
   linux_mandrake_version();
   }

else if (stat("/etc/fedora-release",&statbuf) != -1)
   {
   Verbose("This appears to be a fedora system.\n");
   AddClassToHeap("redhat");
   AddClassToHeap("fedora");
   linux_fedora_version();
   }

else if (stat("/etc/redhat-release",&statbuf) != -1)
   {
   Verbose("This appears to be a redhat system.\n");
   AddClassToHeap("redhat");
   linux_redhat_version();
   }

if (stat("/etc/generic-release",&statbuf) != -1)
   {
   Verbose("\nThis appears to be a sun cobalt system.\n");
   AddClassToHeap("SunCobalt");
   }

if (stat("/etc/SuSE-release",&statbuf) != -1)
   {
   Verbose("\nThis appears to be a SuSE system.\n");
   AddClassToHeap("SuSE");
   linux_suse_version();
   }

#define SLACKWARE_ANCIENT_VERSION_FILENAME "/etc/slackware-release"
#define SLACKWARE_VERSION_FILENAME "/etc/slackware-version"
if (stat(SLACKWARE_VERSION_FILENAME,&statbuf) != -1)
   {
   Verbose("\nThis appears to be a slackware system.\n");
   AddClassToHeap("slackware");
   linux_slackware_version(SLACKWARE_VERSION_FILENAME);
   }
else if (stat(SLACKWARE_ANCIENT_VERSION_FILENAME,&statbuf) != -1)
   {
   Verbose("\nThis appears to be an ancient slackware system.\n");
   AddClassToHeap("slackware");
   linux_slackware_version(SLACKWARE_ANCIENT_VERSION_FILENAME);
   }


if (stat("/etc/generic-release",&statbuf) != -1)
   {
   Verbose("\nThis appears to be a sun cobalt system.\n");
   AddClassToHeap("SunCobalt");
   }
 
if (stat("/etc/debian_version",&statbuf) != -1)
   {
   Verbose("\nThis appears to be a debian system.\n");
   AddClassToHeap("debian");
   debian_version();
   }

if (stat("/etc/UnitedLinux-release",&statbuf) != -1)
   {
   Verbose("\nThis appears to be a UnitedLinux system.\n");
   AddClassToHeap("UnitedLinux");
   }

if (stat("/etc/gentoo-release",&statbuf) != -1)
   {
   Verbose("\nThis appears to be a gentoo system.\n");
   AddClassToHeap("gentoo");
   }

lsb_version();

#endif

if (stat("/proc/vmware/version",&statbuf) != -1 ||
    stat("/etc/vmware-release",&statbuf) != -1)
   {
   Verbose("\nThis appears to be a VMware Server ESX system.\n");
   AddClassToHeap("VMware");
   VM_version();
   }
else if (stat("/etc/vmware",&statbuf) != -1)
   {
   if (S_ISDIR(statbuf.st_mode))
      {
      Verbose("\nThis appears to be a VMware xSX system.\n");
      AddClassToHeap("VMware");
      VM_version();
      }
   }

if (stat("/proc/xen/capabilities",&statbuf) != -1)
   {
   Verbose("\nThis appears to be a xen pv system.\n");
   AddClassToHeap("xen");
   Xen_domain();
   }
#ifdef XEN_CPUID_SUPPORT
else if (Xen_hv_check())
   {
   Verbose("\nThis appears to be a xen hv system.\n");
   AddClassToHeap("xen");
   AddClassToHeap("xen_domu_hv");
   }
#endif

}