static VersionCmpResult RunCmpCommand(const char *command, const char *v1, const char *v2, Attributes a, Promise *pp) { char expanded_command[CF_EXPANDSIZE]; SetNewScope("cf_pack_context"); NewScalar("cf_pack_context", "v1", v1, cf_str); NewScalar("cf_pack_context", "v2", v2, cf_str); ExpandScalar(command, expanded_command); DeleteScope("cf_pack_context"); FILE *pfp = a.packages.package_commands_useshell ? cf_popen_sh(expanded_command, "w") : cf_popen(expanded_command, "w"); if (pfp == NULL) { cfPS(cf_error, CF_FAIL, "cf_popen", pp, a, "Can not start package version comparison command: %s", expanded_command); return VERCMP_ERROR; } CfOut(cf_verbose, "", "Executing %s", expanded_command); int retcode = cf_pclose(pfp); if (retcode == -1) { cfPS(cf_error, CF_FAIL, "cf_pclose", pp, a, "Error during package version comparison command execution: %s", expanded_command); return VERCMP_ERROR; } return retcode == 0; }
void LoadSystemConstants() { NewScalar("const", "dollar", "$", cf_str); NewScalar("const", "n", "\n", cf_str); NewScalar("const", "r", "\r", cf_str); NewScalar("const", "t", "\t", cf_str); NewScalar("const", "endl", "\n", cf_str); /* NewScalar("const","0","\0",cf_str); - this cannot work */ }
void LoadSystemConstants() { NewScalar("const", "dollar", "$", cf_str); NewScalar("const", "n", "\n", cf_str); NewScalar("const", "r", "\r", cf_str); NewScalar("const", "t", "\t", cf_str); NewScalar("const", "endl", "\n", cf_str); /* NewScalar("const","0","\0",cf_str); - this cannot work */ #ifdef HAVE_NOVA Nova_EnterpriseDiscovery(); #endif }
void TestVariableScan() { int i; char *list_text1 = "$(administrator),a,b,c,d,e,f"; char *list_text2 = "1,2,3,4,@(one)"; Rlist *varlist1, *varlist2, *listoflists = NULL, *scalars = NULL; static char *varstrings[] = { "alpha $(one) beta $(two) gamma", "alpha $(five) beta $(none) gamma $(array[$(four)])", "alpha $(none) beta $(two) gamma", "alpha $(four) beta $(two) gamma $(array[$(diagnostic.three)])", NULL }; printf("%d. Test variable scanning\n", ++NR); SetNewScope("diagnostic"); varlist1 = SplitStringAsRList(list_text1, ','); varlist2 = SplitStringAsRList(list_text2, ','); NewList("diagnostic", "one", varlist1, cf_slist); NewScalar("diagnostic", "two", "secondary skills", cf_str); NewScalar("diagnostic", "administrator", "root", cf_str); NewList("diagnostic", "three", varlist2, cf_slist); NewList("diagnostic", "four", varlist2, cf_slist); NewList("diagnostic", "five", varlist2, cf_slist); for (i = 0; varstrings[i] != NULL; i++) { if (VERBOSE || DEBUG) { printf("-----------------------------------------------------------\n"); printf("Scanning: [%s]\n", varstrings[i]); MapIteratorsFromRval("diagnostic", &scalars, &listoflists, (Rval) { varstrings[i], CF_SCALAR }, NULL); printf("Cumulative scan produced:\n"); printf(" Scalar variables: "); ShowRlist(stdout, scalars); printf("\n"); printf(" Lists variables: "); ShowRlist(stdout, listoflists); printf("\n"); } } }
void VerifyProcesses(Attributes a, Promise *pp) { CfLock thislock; char lockname[CF_BUFSIZE]; if (a.restart_class) { snprintf(lockname, CF_BUFSIZE - 1, "proc-%s-%s", pp->promiser, a.restart_class); } else { snprintf(lockname, CF_BUFSIZE - 1, "proc-%s-norestart", pp->promiser); } thislock = AcquireLock(lockname, VUQNAME, CFSTARTTIME, a, pp, false); if (thislock.lock == NULL) { return; } DeleteScalar("this", "promiser"); NewScalar("this", "promiser", pp->promiser, cf_str); PromiseBanner(pp); VerifyProcessOp(PROCESSTABLE, a, pp); DeleteScalar("this", "promiser"); YieldCurrentLock(thislock); }
void VerifyEnvironmentsPromise(Promise *pp) { Attributes a = { {0} }; CfLock thislock; Promise *pexp; a = GetEnvironmentsAttributes(pp); if (EnvironmentsSanityChecks(a, pp)) { thislock = AcquireLock("virtual", VUQNAME, CFSTARTTIME, a, pp, false); if (thislock.lock == NULL) { return; } CF_OCCUR++; PromiseBanner(pp); NewScalar("this", "promiser", pp->promiser, cf_str); pexp = ExpandDeRefPromise("this", pp); VerifyEnvironments(a, pp); DeletePromise(pexp); } YieldCurrentLock(thislock); }
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 }
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 }
void ForceScalar(char *lval, char *rval) { Rval retval; if (THIS_AGENT_TYPE != cf_agent && THIS_AGENT_TYPE != cf_know) { return; } if (GetVariable("match", lval, &retval) != cf_notype) { DeleteVariable("match", lval); } NewScalar("match", lval, rval, cf_str); CfDebug("Setting local variable \"match.%s\" context; $(%s) = %s\n", lval, lval, rval); }
void VerifyServices(Attributes a, Promise *pp, const ReportContext *report_context) { CfLock thislock; // allow to start Cfengine windows executor without license #ifdef __MINGW32__ if ((LICENSES == 0) && (strcmp(WINSERVICE_NAME, pp->promiser) != 0)) { return; } #endif thislock = AcquireLock(pp->promiser, VUQNAME, CFSTARTTIME, a, pp, false); if (thislock.lock == NULL) { return; } NewScalar("this", "promiser", pp->promiser, cf_str); PromiseBanner(pp); if (strcmp(a.service.service_type, "windows") == 0) { VerifyWindowsService(a, pp); } else { DoVerifyServices(a, pp, report_context); } DeleteScalar("this", "promiser"); YieldCurrentLock(thislock); }
void SetPolicyServer(char *name) /* * If name contains a string, it's written to file, * if not, name is filled with the contents of file. */ { char file[CF_BUFSIZE]; FILE *fout, *fin; char fileContents[CF_MAXVARSIZE] = { 0 }; snprintf(file, CF_BUFSIZE - 1, "%s/policy_server.dat", CFWORKDIR); MapName(file); if ((fin = fopen(file, "r")) != NULL) { fscanf(fin, "%1023s", fileContents); fclose(fin); } // update file if different and we know what to put there if ((NULL_OR_EMPTY(name)) && (!NULL_OR_EMPTY(fileContents))) { snprintf(name, CF_MAXVARSIZE, "%s", fileContents); } else if ((!NULL_OR_EMPTY(name)) && (strcmp(name, fileContents) != 0)) { if ((fout = fopen(file, "w")) == NULL) { CfOut(cf_error, "fopen", "Unable to write policy server file! (%s)", file); return; } fprintf(fout, "%s", name); fclose(fout); } if (NULL_OR_EMPTY(name)) { // avoids "Scalar item in servers => { } in rvalue is out of bounds ..." // when NovaBase is checked with unprivileged (not bootstrapped) cf-promises NewScalar("sys", "policy_hub", "undefined", cf_str); } else { NewScalar("sys", "policy_hub", name, cf_str); } // Get the timestamp on policy update snprintf(file, CF_MAXVARSIZE, "%s/masterfiles/cf_promises_validated", CFWORKDIR); MapName(file); struct stat sb; if ((cfstat(file, &sb)) != 0) { return; } char timebuf[26]; cf_strtimestamp_local(sb.st_mtime, timebuf); NewScalar("sys", "last_policy_update", timebuf, cf_str); }
static void DoVerifyServices(Attributes a, Promise *pp, const ReportContext *report_context) { FnCall *default_bundle = NULL; Rlist *args = NULL; // Need to set up the default service pack to eliminate syntax if (GetConstraintValue("service_bundle", pp, CF_SCALAR) == NULL) { switch (a.service.service_policy) { case cfsrv_start: AppendRlist(&args, pp->promiser, CF_SCALAR); AppendRlist(&args, "start", CF_SCALAR); break; case cfsrv_restart: AppendRlist(&args, pp->promiser, CF_SCALAR); AppendRlist(&args, "restart", CF_SCALAR); break; case cfsrv_reload: AppendRlist(&args, pp->promiser, CF_SCALAR); AppendRlist(&args, "restart", CF_SCALAR); break; case cfsrv_stop: case cfsrv_disable: default: AppendRlist(&args, pp->promiser, CF_SCALAR); AppendRlist(&args, "stop", CF_SCALAR); break; } default_bundle = NewFnCall("default:standard_services", args); ConstraintAppendToPromise(pp, "service_bundle", (Rval) {default_bundle, CF_FNCALL}, "any", false); a.havebundle = true; } // Set $(this.service_policy) for flexible bundle adaptation switch (a.service.service_policy) { case cfsrv_start: NewScalar("this", "service_policy", "start", cf_str); break; case cfsrv_restart: NewScalar("this", "service_policy", "restart", cf_str); break; case cfsrv_reload: NewScalar("this", "service_policy", "reload", cf_str); break; case cfsrv_stop: case cfsrv_disable: default: NewScalar("this", "service_policy", "stop", cf_str); break; } if (default_bundle && GetBundle(PolicyFromPromise(pp), default_bundle->name, "agent") == NULL) { cfPS(cf_inform, CF_FAIL, "", pp, a, " !! Service %s could not be invoked successfully\n", pp->promiser); } if (!DONTDO) { VerifyMethod("service_bundle", a, pp, report_context); // Send list of classes to set privately? } }
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(); }
static void VerifyExec(Attributes a, Promise *pp) { CfLock thislock; char unsafeLine[CF_BUFSIZE], line[sizeof(unsafeLine) * 2], eventname[CF_BUFSIZE]; char comm[20]; char execstr[CF_EXPANDSIZE]; int outsourced, count = 0; mode_t maskval = 0; FILE *pfp; char cmdOutBuf[CF_BUFSIZE]; int cmdOutBufPos = 0; int lineOutLen; if (!IsExecutable(GetArg0(pp->promiser))) { cfPS(cf_error, CF_FAIL, "", pp, a, "%s promises to be executable but isn't\n", pp->promiser); if (strchr(pp->promiser, ' ')) { CfOut(cf_verbose, "", "Paths with spaces must be inside escaped quoutes (e.g. \\\"%s\\\")", pp->promiser); } return; } else { CfOut(cf_verbose, "", " -> Promiser string contains a valid executable (%s) - ok\n", GetArg0(pp->promiser)); } DeleteScalar("this", "promiser"); NewScalar("this", "promiser", pp->promiser, cf_str); if (a.args) { snprintf(execstr, CF_EXPANDSIZE - 1, "%s %s", pp->promiser, a.args); } else { strncpy(execstr, pp->promiser, CF_BUFSIZE); } thislock = AcquireLock(execstr, VUQNAME, CFSTARTTIME, a, pp, false); if (thislock.lock == NULL) { return; } PromiseBanner(pp); CfOut(cf_inform, "", " -> Executing \'%s\' ...(timeout=%d,owner=%ju,group=%ju)\n", execstr, a.contain.timeout, (uintmax_t)a.contain.owner, (uintmax_t)a.contain.group); BeginMeasure(); if (DONTDO && !a.contain.preview) { CfOut(cf_error, "", "-> Would execute script %s\n", execstr); } else if (a.transaction.action != cfa_fix) { cfPS(cf_error, CF_WARN, "", pp, a, " !! Command \"%s\" needs to be executed, but only warning was promised", execstr); } else { CommPrefix(execstr, comm); if (a.transaction.background) { #ifdef MINGW outsourced = true; #else CfOut(cf_verbose, "", " -> Backgrounding job %s\n", execstr); outsourced = fork(); #endif } else { outsourced = false; } if (outsourced || !a.transaction.background) // work done here: either by child or non-background parent { if (a.contain.timeout != CF_NOINT) { SetTimeOut(a.contain.timeout); } #ifndef MINGW CfOut(cf_verbose, "", " -> (Setting umask to %jo)\n", (uintmax_t)a.contain.umask); maskval = umask(a.contain.umask); if (a.contain.umask == 0) { CfOut(cf_verbose, "", " !! Programming %s running with umask 0! Use umask= to set\n", execstr); } #endif /* NOT MINGW */ if (a.contain.useshell) { pfp = cf_popen_shsetuid(execstr, "r", a.contain.owner, a.contain.group, a.contain.chdir, a.contain.chroot, a.transaction.background); } else { pfp = cf_popensetuid(execstr, "r", a.contain.owner, a.contain.group, a.contain.chdir, a.contain.chroot, a.transaction.background); } if (pfp == NULL) { cfPS(cf_error, CF_FAIL, "cf_popen", pp, a, "!! Couldn't open pipe to command %s\n", execstr); YieldCurrentLock(thislock); return; } while (!feof(pfp)) { if (ferror(pfp)) /* abortable */ { cfPS(cf_error, CF_TIMEX, "ferror", pp, a, "!! Command pipe %s\n", execstr); cf_pclose(pfp); YieldCurrentLock(thislock); return; } CfReadLine(unsafeLine, CF_BUFSIZE - 1, pfp); ReplaceStr(unsafeLine, line, sizeof(line), "%", "%%"); // escape format char if (strstr(line, "cfengine-die")) { break; } if (ferror(pfp)) /* abortable */ { cfPS(cf_error, CF_TIMEX, "ferror", pp, a, "!! Command pipe %s\n", execstr); cf_pclose(pfp); YieldCurrentLock(thislock); return; } if (a.contain.preview) { PreviewProtocolLine(line, execstr); } if (a.module) { ModuleProtocol(execstr, line, !a.contain.nooutput); } else if (!a.contain.nooutput && NonEmptyLine(line)) { lineOutLen = strlen(comm) + strlen(line) + 12; // if buffer is to small for this line, output it directly if (lineOutLen > sizeof(cmdOutBuf)) { CfOut(cf_cmdout, "", "Q: \"...%s\": %s\n", comm, line); } else { if (cmdOutBufPos + lineOutLen > sizeof(cmdOutBuf)) { CfOut(cf_cmdout, "", "%s", cmdOutBuf); cmdOutBufPos = 0; } sprintf(cmdOutBuf + cmdOutBufPos, "Q: \"...%s\": %s\n", comm, line); cmdOutBufPos += (lineOutLen - 1); } count++; } } #ifdef MINGW if (outsourced) // only get return value if we waited for command execution { cf_pclose(pfp); } else { cf_pclose_def(pfp, a, pp); } #else /* NOT MINGW */ cf_pclose_def(pfp, a, pp); #endif } if (count) { if (cmdOutBufPos) { CfOut(cf_cmdout, "", "%s", cmdOutBuf); } CfOut(cf_cmdout, "", "I: Last %d quoted lines were generated by promiser \"%s\"\n", count, execstr); } if (a.contain.timeout != CF_NOINT) { alarm(0); signal(SIGALRM, SIG_DFL); } CfOut(cf_inform, "", " -> Completed execution of %s\n", execstr); #ifndef MINGW umask(maskval); #endif YieldCurrentLock(thislock); snprintf(eventname, CF_BUFSIZE - 1, "Exec(%s)", execstr); #ifndef MINGW if (a.transaction.background && outsourced) { CfOut(cf_verbose, "", " -> Backgrounded command (%s) is done - exiting\n", execstr); exit(0); } #endif /* NOT MINGW */ } }
void VerifyReportPromise(Promise *pp) { Attributes a = { {0} }; CfLock thislock; char unique_name[CF_EXPANDSIZE]; a = GetReportsAttributes(pp); snprintf(unique_name, CF_EXPANDSIZE - 1, "%s_%zu", pp->promiser, pp->offset.line); thislock = AcquireLock(unique_name, VUQNAME, CFSTARTTIME, a, pp, false); // Handle return values before locks, as we always do this if (a.report.result) { // User-unwritable value last-result contains the useresult if (strlen(a.report.result) > 0) { snprintf(unique_name, CF_BUFSIZE, "last-result[%s]", a.report.result); } else { snprintf(unique_name, CF_BUFSIZE, "last-result"); } NewScalar(pp->bundle, unique_name, pp->promiser, DATA_TYPE_STRING); return; } // Now do regular human reports if (thislock.lock == NULL) { return; } PromiseBanner(pp); cfPS(OUTPUT_LEVEL_VERBOSE, CF_CHG, "", pp, a, "Report: %s", pp->promiser); if (a.report.to_file) { CfFOut(a.report.to_file, OUTPUT_LEVEL_ERROR, "", "%s", pp->promiser); } else { CfOut(OUTPUT_LEVEL_REPORTING, "", "R: %s", pp->promiser); } if (a.report.haveprintfile) { PrintFile(a, pp); } if (a.report.showstate) { /* Do nothing. Deprecated. */ } if (a.report.havelastseen) { /* Do nothing. Deprecated. */ } YieldCurrentLock(thislock); }
void CheckFileChanges(Policy **policy, GenericAgentConfig *config, const ReportContext *report_context) { if (EnterpriseExpiry()) { CfOut(cf_error, "", "!! This enterprise license is invalid."); } CfDebug("Checking file updates on %s\n", config->input_file); if (NewPromiseProposals(config->input_file, InputFiles(*policy))) { CfOut(cf_verbose, "", " -> New promises detected...\n"); if (CheckPromises(config->input_file, report_context)) { CfOut(cf_inform, "", "Rereading config files %s..\n", config->input_file); /* Free & reload -- lock this to avoid access errors during reload */ DeleteItemList(VNEGHEAP); DeleteAlphaList(&VHEAP); InitAlphaList(&VHEAP); DeleteAlphaList(&VHARDHEAP); InitAlphaList(&VHARDHEAP); DeleteAlphaList(&VADDCLASSES); InitAlphaList(&VADDCLASSES); DeleteItemList(IPADDRESSES); IPADDRESSES = NULL; DeleteItemList(SV.trustkeylist); DeleteItemList(SV.skipverify); DeleteItemList(SV.attackerlist); DeleteItemList(SV.nonattackerlist); DeleteItemList(SV.multiconnlist); DeleteAuthList(VADMIT); DeleteAuthList(VDENY); DeleteAuthList(VARADMIT); DeleteAuthList(VARDENY); DeleteAuthList(ROLES); //DeleteRlist(VINPUTLIST); This is just a pointer, cannot free it DeleteAllScope(); strcpy(VDOMAIN, "undefined.domain"); POLICY_SERVER[0] = '\0'; VADMIT = VADMITTOP = NULL; VDENY = VDENYTOP = NULL; VARADMIT = VARADMITTOP = NULL; VARDENY = VARDENYTOP = NULL; ROLES = ROLESTOP = NULL; VNEGHEAP = NULL; SV.trustkeylist = NULL; SV.skipverify = NULL; SV.attackerlist = NULL; SV.nonattackerlist = NULL; SV.multiconnlist = NULL; PolicyDestroy(*policy); *policy = NULL; ERRORCOUNT = 0; NewScope("sys"); SetPolicyServer(POLICY_SERVER); NewScalar("sys", "policy_hub", POLICY_SERVER, DATA_TYPE_STRING); if (EnterpriseExpiry()) { CfOut(cf_error, "", "Cfengine - autonomous configuration engine. This enterprise license is invalid.\n"); } NewScope("const"); NewScope("this"); NewScope("control_server"); NewScope("control_common"); NewScope("mon"); NewScope("remote_access"); GetNameInfo3(); GetInterfacesInfo(AGENT_TYPE_SERVER); Get3Environment(); BuiltinClasses(); OSClasses(); KeepHardClasses(); HardClass(CF_AGENTTYPES[THIS_AGENT_TYPE]); SetReferenceTime(true); *policy = ReadPromises(AGENT_TYPE_SERVER, config, report_context); KeepPromises(*policy, config, report_context); Summarize(); } else { CfOut(cf_inform, "", " !! File changes contain errors -- ignoring"); PROMISETIME = time(NULL); } } else { CfDebug(" -> No new promises found\n"); } }
void VerifyReportPromise(Promise *pp) { Attributes a = { {0} }; CfLock thislock; Rlist *rp; char unique_name[CF_EXPANDSIZE]; a = GetReportsAttributes(pp); snprintf(unique_name, CF_EXPANDSIZE - 1, "%s_%zu", pp->promiser, pp->offset.line); thislock = AcquireLock(unique_name, VUQNAME, CFSTARTTIME, a, pp, false); // Handle return values before locks, as we always do this if (a.report.result) { // User-unwritable value last-result contains the useresult if (strlen(a.report.result) > 0) { snprintf(unique_name, CF_BUFSIZE, "last-result[%s]", a.report.result); } else { snprintf(unique_name, CF_BUFSIZE, "last-result"); } NewScalar(pp->bundle, unique_name, pp->promiser, cf_str); return; } // Now do regular human reports if (thislock.lock == NULL) { return; } PromiseBanner(pp); cfPS(cf_verbose, CF_CHG, "", pp, a, "Report: %s", pp->promiser); if (a.report.to_file) { CfFOut(a.report.to_file, cf_error, "", "%s", pp->promiser); } else { CfOut(cf_reporting, "", "R: %s", pp->promiser); } if (a.report.haveprintfile) { PrintFile(a, pp); } if (a.report.showstate) { for (rp = a.report.showstate; rp != NULL; rp = rp->next) { ShowState(rp->item); } } if (a.report.havelastseen) { /* Do nothing. Deprecated. */ } YieldCurrentLock(thislock); }
void TexinfoManual(const char *source_dir, const char *output_file) { char filename[CF_BUFSIZE]; const SubTypeSyntax *st; Item *done = NULL; FILE *fout; int i; if ((fout = fopen(output_file, "w")) == NULL) { CfOut(OUTPUT_LEVEL_ERROR, "fopen", "Unable to open %s for writing\n", filename); return; } TexinfoHeader(fout); /* General background */ fprintf(fout, "@c *****************************************************\n"); fprintf(fout, "@c * CHAPTER \n"); fprintf(fout, "@c *****************************************************\n"); fprintf(fout, "@node Getting started\n@chapter CFEngine %s -- Getting started\n\n", Version()); IncludeManualFile(source_dir, fout, "reference_basics.texinfo"); /* Control promises */ fprintf(fout, "@c *****************************************************\n"); fprintf(fout, "@c * CHAPTER \n"); fprintf(fout, "@c *****************************************************\n"); fprintf(fout, "@node Control Promises\n@chapter Control promises\n\n"); IncludeManualFile(source_dir, fout, "reference_control_intro.texinfo"); fprintf(fout, "@menu\n"); for (i = 0; CF_ALL_BODIES[i].bundle_type != NULL; ++i) { fprintf(fout, "* control %s::\n", CF_ALL_BODIES[i].bundle_type); } fprintf(fout, "@end menu\n"); for (i = 0; CF_ALL_BODIES[i].bundle_type != NULL; i++) { fprintf(fout, "@node control %s\n@section @code{%s} control promises\n\n", CF_ALL_BODIES[i].bundle_type, CF_ALL_BODIES[i].bundle_type); snprintf(filename, CF_BUFSIZE - 1, "control/%s_example.texinfo", CF_ALL_BODIES[i].bundle_type); IncludeManualFile(source_dir, fout, filename); snprintf(filename, CF_BUFSIZE - 1, "control/%s_notes.texinfo", CF_ALL_BODIES[i].bundle_type); IncludeManualFile(source_dir, fout, filename); TexinfoBodyParts(source_dir, fout, CF_ALL_BODIES[i].bs, CF_ALL_BODIES[i].bundle_type); } /* Components */ for (i = 0; i < CF3_MODULES; i++) { st = (CF_ALL_SUBTYPES[i]); if ((st == CF_COMMON_SUBTYPES) || (st == CF_EXEC_SUBTYPES) || (st == CF_REMACCESS_SUBTYPES) || (st == CF_KNOWLEDGE_SUBTYPES) || (st == CF_MEASUREMENT_SUBTYPES)) { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Dealing with chapter / bundle type %s\n", st->bundle_type); fprintf(fout, "@c *****************************************************\n"); fprintf(fout, "@c * CHAPTER \n"); fprintf(fout, "@c *****************************************************\n"); if (strcmp(st->bundle_type, "*") == 0) { fprintf(fout, "@node Bundles for common\n@chapter Bundles of @code{common}\n\n"); } else { fprintf(fout, "@node Bundles for %s\n@chapter Bundles of @code{%s}\n\n", st->bundle_type, st->bundle_type); } } if (!IsItemIn(done, st->bundle_type)) /* Avoid multiple reading if several modules */ { char bundle_filename[CF_BUFSIZE]; if (strcmp(st->bundle_type, "*") == 0) { strcpy(bundle_filename, "common"); } else { strlcpy(bundle_filename, st->bundle_type, CF_BUFSIZE); } PrependItem(&done, st->bundle_type, NULL); snprintf(filename, CF_BUFSIZE - 1, "bundletypes/%s_example.texinfo", bundle_filename); IncludeManualFile(source_dir, fout, filename); snprintf(filename, CF_BUFSIZE - 1, "bundletypes/%s_notes.texinfo", bundle_filename); IncludeManualFile(source_dir, fout, filename); fprintf(fout, "@menu\n"); for (int k = 0; k < CF3_MODULES; ++k) { for (int j = 0; CF_ALL_SUBTYPES[k][j].bundle_type != NULL; ++j) { const char *constraint_type_name; if (strcmp(CF_ALL_SUBTYPES[k][j].subtype, "*") == 0) { constraint_type_name = "Miscellaneous"; } else { constraint_type_name = CF_ALL_SUBTYPES[k][j].subtype; } const char *bundle_type_name; if (strcmp(CF_ALL_SUBTYPES[k][j].bundle_type, "*") == 0) { bundle_type_name = "common"; } else { bundle_type_name = CF_ALL_SUBTYPES[k][j].bundle_type; } fprintf(fout, "* %s in %s promises: %s in %s promises\n", CF_ALL_SUBTYPES[k][j].subtype, bundle_type_name, constraint_type_name, bundle_type_name); } } fprintf(fout, "@end menu\n"); } TexinfoPromiseTypesFor(source_dir, fout, st); } /* Special functions */ CfOut(OUTPUT_LEVEL_VERBOSE, "", "Dealing with chapter / bundle type - special functions\n"); fprintf(fout, "@c *****************************************************\n"); fprintf(fout, "@c * CHAPTER \n"); fprintf(fout, "@c *****************************************************\n"); fprintf(fout, "@node Special functions\n@chapter Special functions\n\n"); fprintf(fout, "@menu\n"); fprintf(fout, "* Introduction to functions::\n"); for (i = 0; CF_FNCALL_TYPES[i].name != NULL; ++i) { fprintf(fout, "* Function %s::\n", CF_FNCALL_TYPES[i].name); } fprintf(fout, "@end menu\n"); fprintf(fout, "@node Introduction to functions\n@section Introduction to functions\n\n"); IncludeManualFile(source_dir, fout, "functions_intro.texinfo"); for (i = 0; CF_FNCALL_TYPES[i].name != NULL; i++) { fprintf(fout, "@node Function %s\n@section Function %s \n\n", CF_FNCALL_TYPES[i].name, CF_FNCALL_TYPES[i].name); TexinfoSpecialFunction(source_dir, fout, CF_FNCALL_TYPES[i]); } /* Special variables */ CfOut(OUTPUT_LEVEL_VERBOSE, "", "Dealing with chapter / bundle type - special variables\n"); fprintf(fout, "@c *****************************************************\n"); fprintf(fout, "@c * CHAPTER \n"); fprintf(fout, "@c *****************************************************\n"); fprintf(fout, "@node Special Variables\n@chapter Special Variables\n\n"); static const char *scopes[] = { "const", "edit", "match", "mon", "sys", "this", NULL, }; fprintf(fout, "@menu\n"); for (const char **s = scopes; *s != NULL; ++s) { fprintf(fout, "* Variable context %s::\n", *s); } fprintf(fout, "@end menu\n"); // scopes const and sys NewScope("edit"); NewScalar("edit", "filename", "x", DATA_TYPE_STRING); NewScope("match"); NewScalar("match", "0", "x", DATA_TYPE_STRING); for (const char **s = scopes; *s != NULL; ++s) { TexinfoVariables(source_dir, fout, (char *) *s); } // Log files CfOut(OUTPUT_LEVEL_VERBOSE, "", "Dealing with chapter / bundle type - Logs and records\n"); fprintf(fout, "@c *****************************************************\n"); fprintf(fout, "@c * CHAPTER \n"); fprintf(fout, "@c *****************************************************\n"); fprintf(fout, "@node Logs and records\n@chapter Logs and records\n\n"); IncludeManualFile(source_dir, fout, "reference_logs.texinfo"); TexinfoFooter(fout); fclose(fout); }
static void CheckControlPromises(char *scope,char *agent,struct Constraint *controllist) { struct Constraint *cp; struct BodySyntax *bp = NULL; struct Rlist *rp; int i = 0; struct Rval returnval; char rettype; void *retval; Debug("CheckControlPromises(%s)\n",agent); for (i = 0; CF_ALL_BODIES[i].bs != NULL; i++) { bp = CF_ALL_BODIES[i].bs; if (strcmp(agent,CF_ALL_BODIES[i].btype) == 0) { break; } } if (bp == NULL) { FatalError("Unknown agent"); } for (cp = controllist; cp != NULL; cp=cp->next) { if (IsExcluded(cp->classes)) { continue; } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_bundlesequence].lval) == 0) { returnval = ExpandPrivateRval(CONTEXTID,cp->rval,cp->type); } else { returnval = EvaluateFinalRval(CONTEXTID,cp->rval,cp->type,true,NULL); } DeleteVariable(scope,cp->lval); if (!AddVariableHash(scope,cp->lval,returnval.item,returnval.rtype,GetControlDatatype(cp->lval,bp),cp->audit->filename,cp->lineno)) { CfOut(cf_error,""," !! Rule from %s at/before line %d\n",cp->audit->filename,cp->lineno); } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_output_prefix].lval) == 0) { strncpy(VPREFIX,returnval.item,CF_MAXVARSIZE); } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_domain].lval) == 0) { strcpy(VDOMAIN,cp->rval); CfOut(cf_verbose,"","SET domain = %s\n",VDOMAIN); DeleteScalar("sys","domain"); DeleteScalar("sys","fqhost"); snprintf(VFQNAME,CF_MAXVARSIZE,"%s.%s",VUQNAME,VDOMAIN); NewScalar("sys","fqhost",VFQNAME,cf_str); NewScalar("sys","domain",VDOMAIN,cf_str); DeleteClass("undefined_domain"); NewClass(VDOMAIN); } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_ignore_missing_inputs].lval) == 0) { CfOut(cf_verbose,"","SET ignore_missing_inputs %s\n",cp->rval); IGNORE_MISSING_INPUTS = GetBoolean(cp->rval); } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_ignore_missing_bundles].lval) == 0) { CfOut(cf_verbose,"","SET ignore_missing_bundles %s\n",cp->rval); IGNORE_MISSING_BUNDLES = GetBoolean(cp->rval); } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_goalpatterns].lval) == 0) { GOALS = NULL; for (rp = (struct Rlist *)returnval.item; rp != NULL; rp=rp->next) { PrependRScalar(&GOALS,rp->item,CF_SCALAR); } CfOut(cf_verbose,"","SET goal_patterns list\n"); continue; } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_goalcategories].lval) == 0) { GOALCATEGORIES = NULL; for (rp = (struct Rlist *)returnval.item; rp != NULL; rp=rp->next) { PrependRScalar(&GOALCATEGORIES,rp->item,CF_SCALAR); } CfOut(cf_verbose,"","SET goal_categories list\n"); continue; } DeleteRvalItem(returnval.item,returnval.rtype); } }
static bool ScheduleRun(Policy **policy, ExecConfig *exec_config, const ReportContext *report_context) { Item *ip; CfOut(cf_verbose, "", "Sleeping...\n"); sleep(CFPULSETIME); /* 1 Minute resolution is enough */ // recheck license (in case of license updates or expiry) if (EnterpriseExpiry()) { CfOut(cf_error, "", "Cfengine - autonomous configuration engine. This enterprise license is invalid.\n"); exit(1); } /* * FIXME: this logic duplicates the one from cf-serverd.c. Unify ASAP. */ if (CheckNewPromises(report_context) == RELOAD_FULL) { /* Full reload */ CfOut(cf_inform, "", "Re-reading promise file %s..\n", VINPUTFILE); DeleteAlphaList(&VHEAP); InitAlphaList(&VHEAP); DeleteAlphaList(&VHARDHEAP); InitAlphaList(&VHARDHEAP); DeleteAlphaList(&VADDCLASSES); InitAlphaList(&VADDCLASSES); DeleteItemList(IPADDRESSES); IPADDRESSES = NULL; DeleteItemList(VNEGHEAP); DeleteAllScope(); strcpy(VDOMAIN, "undefinded.domain"); POLICY_SERVER[0] = '\0'; VNEGHEAP = NULL; VINPUTLIST = NULL; PolicyDestroy(*policy); *policy = NULL; ERRORCOUNT = 0; NewScope("sys"); SetPolicyServer(POLICY_SERVER); NewScalar("sys", "policy_hub", POLICY_SERVER, cf_str); NewScope("const"); NewScope("this"); NewScope("mon"); NewScope("control_server"); NewScope("control_common"); NewScope("remote_access"); GetNameInfo3(); GetInterfacesInfo(AGENT_TYPE_EXECUTOR); Get3Environment(); BuiltinClasses(); OSClasses(); HardClass(CF_AGENTTYPES[THIS_AGENT_TYPE]); SetReferenceTime(true); GenericAgentConfig config = { .bundlesequence = NULL }; *policy = ReadPromises(AGENT_TYPE_EXECUTOR, CF_EXECC, config, report_context); KeepPromises(*policy, exec_config); }
static bool ScheduleRun(Policy **policy, GenericAgentConfig *config, ExecConfig *exec_config, const ReportContext *report_context) { Item *ip; CfOut(OUTPUT_LEVEL_VERBOSE, "", "Sleeping...\n"); sleep(CFPULSETIME); /* 1 Minute resolution is enough */ // recheck license (in case of license updates or expiry) if (EnterpriseExpiry()) { CfOut(OUTPUT_LEVEL_ERROR, "", "Cfengine - autonomous configuration engine. This enterprise license is invalid.\n"); exit(1); } /* * FIXME: this logic duplicates the one from cf-serverd.c. Unify ASAP. */ if (CheckNewPromises(config->input_file, InputFiles(*policy), report_context) == RELOAD_FULL) { /* Full reload */ CfOut(OUTPUT_LEVEL_INFORM, "", "Re-reading promise file %s..\n", config->input_file); DeleteAlphaList(&VHEAP); InitAlphaList(&VHEAP); DeleteAlphaList(&VHARDHEAP); InitAlphaList(&VHARDHEAP); DeleteAlphaList(&VADDCLASSES); InitAlphaList(&VADDCLASSES); DeleteItemList(IPADDRESSES); IPADDRESSES = NULL; DeleteItemList(VNEGHEAP); DeleteAllScope(); strcpy(VDOMAIN, "undefinded.domain"); POLICY_SERVER[0] = '\0'; VNEGHEAP = NULL; PolicyDestroy(*policy); *policy = NULL; ERRORCOUNT = 0; NewScope("sys"); SetPolicyServer(POLICY_SERVER); NewScalar("sys", "policy_hub", POLICY_SERVER, DATA_TYPE_STRING); NewScope("const"); NewScope("this"); NewScope("mon"); NewScope("control_server"); NewScope("control_common"); NewScope("remote_access"); GetNameInfo3(); GetInterfacesInfo(AGENT_TYPE_EXECUTOR); Get3Environment(); BuiltinClasses(); OSClasses(); HardClass(CF_AGENTTYPES[THIS_AGENT_TYPE]); SetReferenceTime(true); GenericAgentConfigSetBundleSequence(config, NULL); *policy = GenericAgentLoadPolicy(AGENT_TYPE_EXECUTOR, config, report_context); KeepPromises(*policy, exec_config); } else { /* Environment reload */ DeleteAlphaList(&VHEAP); InitAlphaList(&VHEAP); DeleteAlphaList(&VADDCLASSES); InitAlphaList(&VADDCLASSES); DeleteAlphaList(&VHARDHEAP); InitAlphaList(&VHARDHEAP); DeleteItemList(IPADDRESSES); IPADDRESSES = NULL; DeleteScope("this"); DeleteScope("mon"); DeleteScope("sys"); NewScope("this"); NewScope("mon"); NewScope("sys"); GetInterfacesInfo(AGENT_TYPE_EXECUTOR); Get3Environment(); BuiltinClasses(); OSClasses(); SetReferenceTime(true); } for (ip = SCHEDULE; ip != NULL; ip = ip->next) { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Checking schedule %s...\n", ip->name); if (IsDefinedClass(ip->name, NULL)) { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Waking up the agent at %s ~ %s \n", cf_ctime(&CFSTARTTIME), ip->name); return true; } } CfOut(OUTPUT_LEVEL_VERBOSE, "", "Nothing to do at %s\n", cf_ctime(&CFSTARTTIME)); return false; }
static void DoVerifyServices(Attributes a, Promise *pp, const ReportContext *report_context) { FnCall *default_bundle = NULL; Rlist *args = NULL; // Need to set up the default service pack to eliminate syntax if (ConstraintGetRvalValue("service_bundle", pp, RVAL_TYPE_SCALAR) == NULL) { switch (a.service.service_policy) { case cfsrv_start: RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, "start", RVAL_TYPE_SCALAR); break; case cfsrv_restart: RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, "restart", RVAL_TYPE_SCALAR); break; case cfsrv_reload: RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, "restart", RVAL_TYPE_SCALAR); break; case cfsrv_stop: case cfsrv_disable: default: RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, "stop", RVAL_TYPE_SCALAR); break; } default_bundle = FnCallNew("default:standard_services", args); PromiseAppendConstraint(pp, "service_bundle", (Rval) {default_bundle, RVAL_TYPE_FNCALL }, "any", false); a.havebundle = true; } // Set $(this.service_policy) for flexible bundle adaptation switch (a.service.service_policy) { case cfsrv_start: NewScalar("this", "service_policy", "start", DATA_TYPE_STRING); break; case cfsrv_restart: NewScalar("this", "service_policy", "restart", DATA_TYPE_STRING); break; case cfsrv_reload: NewScalar("this", "service_policy", "reload", DATA_TYPE_STRING); break; case cfsrv_stop: case cfsrv_disable: default: NewScalar("this", "service_policy", "stop", DATA_TYPE_STRING); break; } const Bundle *bp = PolicyGetBundle(PolicyFromPromise(pp), NULL, "agent", default_bundle->name); if (!bp) { bp = PolicyGetBundle(PolicyFromPromise(pp), NULL, "common", default_bundle->name); } if (default_bundle && bp == NULL) { cfPS(OUTPUT_LEVEL_INFORM, CF_FAIL, "", pp, a, " !! Service %s could not be invoked successfully\n", pp->promiser); } if (!DONTDO) { VerifyMethod("service_bundle", a, pp, report_context); // Send list of classes to set privately? } }