int main(int argc, char *argv[]) { EvalContext *ctx = EvalContextNew(); GenericAgentConfig *config = CheckOpts(ctx, argc, argv); GenericAgentConfigApply(ctx, config); GenericAgentDiscoverContext(ctx, config); Policy *policy = NULL; if (GenericAgentCheckPolicy(ctx, config, false)) { policy = GenericAgentLoadPolicy(ctx, config); } else if (config->tty_interactive) { exit(EXIT_FAILURE); } else { CfOut(OUTPUT_LEVEL_ERROR, "", "CFEngine was not able to get confirmation of promises from cf-promises, so going to failsafe\n"); EvalContextHeapAddHard(ctx, "failsafe_fallback"); GenericAgentConfigSetInputFile(config, "failsafe.cf"); policy = GenericAgentLoadPolicy(ctx, config); } WarnAboutDeprecatedFeatures(ctx); CheckForPolicyHub(ctx); ThisAgentInit(); ExecConfig *exec_config = ExecConfigNewDefault(!ONCE, VFQNAME, VIPADDRESS); ExecConfigUpdate(ctx, policy, exec_config); SetFacility(exec_config->log_facility); #ifdef __MINGW32__ if (WINSERVICE) { NovaWin_StartExecService(); } else #endif /* __MINGW32__ */ { StartServer(ctx, policy, config, exec_config); } ExecConfigDestroy(exec_config); GenericAgentConfigDestroy(config); return 0; }
int main(int argc, char *argv[]) { EvalContext *ctx = EvalContextNew(); GenericAgentConfig *config = CheckOpts(ctx, argc, argv); GenericAgentConfigApply(ctx, config); GenericAgentDiscoverContext(ctx, config); Policy *policy = NULL; if (GenericAgentCheckPolicy(config, false)) { policy = GenericAgentLoadPolicy(ctx, config); } else if (config->tty_interactive) { exit(EXIT_FAILURE); } else { Log(LOG_LEVEL_ERR, "CFEngine was not able to get confirmation of promises from cf-promises, so going to failsafe"); EvalContextClassPut(ctx, NULL, "failsafe_fallback", false, CONTEXT_SCOPE_NAMESPACE, "goal=update,source=agent"); GenericAgentConfigSetInputFile(config, GetWorkDir(), "failsafe.cf"); policy = GenericAgentLoadPolicy(ctx, config); } ThisAgentInit(); ExecConfig *exec_config = ExecConfigNewDefault(!ONCE, VFQNAME, VIPADDRESS); ExecConfigUpdate(ctx, policy, exec_config); SetFacility(exec_config->log_facility); #ifdef __MINGW32__ if (WINSERVICE) { NovaWin_StartExecService(); } else #endif /* __MINGW32__ */ { StartServer(ctx, policy, config, exec_config); } ExecConfigDestroy(exec_config); GenericAgentConfigDestroy(config); return 0; }
int main(int argc, char *argv[]) { EvalContext *ctx = EvalContextNew(); GenericAgentConfig *config = CheckOpts(argc, argv); GenericAgentConfigApply(ctx, config); GenericAgentDiscoverContext(ctx, config); Policy *policy = NULL; if (GenericAgentCheckPolicy(config, false)) { policy = GenericAgentLoadPolicy(ctx, config); } else if (config->tty_interactive) { exit(EXIT_FAILURE); } else { Log(LOG_LEVEL_ERR, "CFEngine was not able to get confirmation of promises from cf-promises, so going to failsafe"); EvalContextHeapAddHard(ctx, "failsafe_fallback"); GenericAgentConfigSetInputFile(config, GetWorkDir(), "failsafe.cf"); policy = GenericAgentLoadPolicy(ctx, config); } ThisAgentInit(); KeepPromises(ctx, policy, config); Summarize(); Log(LOG_LEVEL_NOTICE, "Server is starting..."); StartServer(ctx, &policy, config); Log(LOG_LEVEL_NOTICE, "Cleaning up and exiting..."); GenericAgentConfigDestroy(config); PolicyDestroy(policy); EvalContextDestroy(ctx); return 0; }
int main(int argc, char *argv[]) { EvalContext *ctx = EvalContextNew(); GenericAgentConfig *config = CheckOpts(ctx, argc, argv); GenericAgentConfigApply(ctx, config); GenericAgentDiscoverContext(ctx, config); Policy *policy = GenericAgentLoadPolicy(ctx, config); if (!policy) { Log(LOG_LEVEL_ERR, "Input files contain errors."); exit(EXIT_FAILURE); } if (SHOWREPORTS) { ShowPromises(policy->bundles, policy->bodies); } switch (config->agent_specific.common.policy_output_format) { case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF: { Policy *output_policy = ParserParseFile(config->input_file, config->agent_specific.common.parser_warnings, config->agent_specific.common.parser_warnings_error); Writer *writer = FileWriter(stdout); PolicyToString(policy, writer); WriterClose(writer); PolicyDestroy(output_policy); } break; case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON: { Policy *output_policy = ParserParseFile(config->input_file, config->agent_specific.common.parser_warnings, config->agent_specific.common.parser_warnings_error); JsonElement *json_policy = PolicyToJson(output_policy); Writer *writer = FileWriter(stdout); JsonWrite(writer, json_policy, 2); WriterClose(writer); JsonDestroy(json_policy); PolicyDestroy(output_policy); } break; case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_NONE: break; } GenericAgentConfigDestroy(config); EvalContextDestroy(ctx); }
int main(int argc, char *argv[]) { int ret = 0; GenericAgentConfig *config = CheckOpts(argc, argv); #ifdef HAVE_AVAHI_CLIENT_CLIENT_H #ifdef HAVE_AVAHI_COMMON_ADDRESS_H if (NULL_OR_EMPTY(POLICY_SERVER) && BOOTSTRAP) { int ret = AutomaticBootstrap(); if (ret < 0) { return 1; } } #endif #endif ReportContext *report_context = OpenReports(config->agent_type); GenericAgentDiscoverContext(config, report_context); Policy *policy = GenericAgentLoadPolicy(config, report_context, ALWAYS_VALIDATE); CheckLicenses(); ThisAgentInit(); BeginAudit(); KeepPromises(policy, config, report_context); CloseReports("agent", report_context); // only note class usage when default policy is run if (!config->input_file) { NoteClassUsage(VHEAP, true); NoteClassUsage(VHARDHEAP, true); } #ifdef HAVE_NOVA Nova_NoteVarUsageDB(); Nova_TrackExecution(config->input_file); #endif PurgeLocks(); if (BOOTSTRAP && !VerifyBootstrap()) { ret = 1; } EndAudit(CFA_BACKGROUND); GenericAgentConfigDestroy(config); return ret; }
int main(int argc, char *argv[]) { EvalContext *ctx = EvalContextNew(); GenericAgentConfig *config = CheckOpts(argc, argv); GenericAgentConfigApply(ctx, config); GenericAgentDiscoverContext(ctx, config); Policy *policy = GenericAgentLoadPolicy(ctx, config); ThisAgentInit(ctx); KeepPromises(ctx, policy); MonitorStartServer(ctx, policy); GenericAgentConfigDestroy(config); EvalContextDestroy(ctx); return 0; }
int main(int argc, char *argv[]) { GenericAgentConfig *config = CheckOpts(argc, argv); ReportContext *report_context = OpenReports(config->agent_type); GenericAgentDiscoverContext(config, report_context); Policy *policy = GenericAgentLoadPolicy(config, report_context, false); CheckLicenses(); ThisAgentInit(); KeepPromises(policy, config, report_context); Summarize(); StartServer(policy, config, report_context); ReportContextDestroy(report_context); GenericAgentConfigDestroy(config); return 0; }
int main(int argc, char *argv[]) { EvalContext *ctx = EvalContextNew(); GenericAgentConfig *config = CheckOpts(argc, argv); GenericAgentConfigApply(ctx, config); ReportContext *report_context = OpenReports(ctx, config->agent_type); GenericAgentDiscoverContext(ctx, config, report_context); Policy *policy = GenericAgentLoadPolicy(ctx, config->agent_type, config, report_context); CheckLicenses(ctx); ThisAgentInit(ctx); KeepPromises(ctx, policy); MonitorStartServer(ctx, policy, report_context); ReportContextDestroy(report_context); GenericAgentConfigDestroy(config); EvalContextDestroy(ctx); return 0; }
void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, time_t *last_policy_reload) { time_t validated_at; Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'", config->input_file); validated_at = ReadTimestampFromPolicyValidatedMasterfiles(config); if (*last_policy_reload < validated_at) { *last_policy_reload = validated_at; Log(LOG_LEVEL_VERBOSE, "New promises detected..."); if (GenericAgentArePromisesValid(config)) { Log(LOG_LEVEL_INFO, "Rereading policy file '%s'", config->input_file); /* Free & reload -- lock this to avoid access errors during reload */ EvalContextClear(ctx); free(SV.allowciphers); SV.allowciphers = NULL; DeleteItemList(SV.trustkeylist); DeleteItemList(SV.attackerlist); DeleteItemList(SV.nonattackerlist); DeleteItemList(SV.multiconnlist); DeleteAuthList(&SV.admit, &SV.admittail); DeleteAuthList(&SV.deny, &SV.denytail); DeleteAuthList(&SV.varadmit, &SV.varadmittail); DeleteAuthList(&SV.vardeny, &SV.vardenytail); DeleteAuthList(&SV.roles, &SV.rolestail); strcpy(VDOMAIN, "undefined.domain"); SV.trustkeylist = NULL; SV.attackerlist = NULL; SV.nonattackerlist = NULL; SV.multiconnlist = NULL; acl_Free(paths_acl); paths_acl = NULL; acl_Free(classes_acl); classes_acl = NULL; acl_Free(vars_acl); vars_acl = NULL; acl_Free(literals_acl); literals_acl = NULL; acl_Free(query_acl); query_acl = NULL; StringMapDestroy(SV.path_shortcuts); SV.path_shortcuts = NULL; PolicyDestroy(*policy); *policy = NULL; { char *existing_policy_server = ReadPolicyServerFile(GetWorkDir()); SetPolicyServer(ctx, existing_policy_server); free(existing_policy_server); } UpdateLastPolicyUpdateTime(ctx); DetectEnvironment(ctx); KeepHardClasses(ctx); EvalContextClassPutHard(ctx, CF_AGENTTYPES[AGENT_TYPE_SERVER], "cfe_internal,source=agent"); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); *policy = GenericAgentLoadPolicy(ctx, config); KeepPromises(ctx, *policy, config); Summarize(); } else { Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring"); } } else { Log(LOG_LEVEL_DEBUG, "No new promises found"); } }
void CheckFileChanges(Policy **policy, GenericAgentConfig *config, const ReportContext *report_context) { if (EnterpriseExpiry()) { CfOut(OUTPUT_LEVEL_ERROR, "", "!! This enterprise license is invalid."); } CfDebug("Checking file updates on %s\n", config->input_file); if (NewPromiseProposals(config->input_file, InputFiles(*policy))) { CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> New promises detected...\n"); if (CheckPromises(config->input_file, report_context)) { CfOut(OUTPUT_LEVEL_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(OUTPUT_LEVEL_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 = GenericAgentLoadPolicy(AGENT_TYPE_SERVER, config, report_context); KeepPromises(*policy, config, report_context); Summarize(); } else { CfOut(OUTPUT_LEVEL_INFORM, "", " !! File changes contain errors -- ignoring"); PROMISETIME = time(NULL); } } else { CfDebug(" -> No new promises found\n"); } }
int OpenReceiverChannel(void) { struct addrinfo *response, *ap; struct addrinfo query = { .ai_flags = AI_PASSIVE, .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM }; /* Listen to INADDR(6)_ANY if BINDINTERFACE unset. */ char *ptr = NULL; if (BINDINTERFACE[0] != '\0') { ptr = BINDINTERFACE; } /* Resolve listening interface. */ if (getaddrinfo(ptr, STR_CFENGINEPORT, &query, &response) != 0) { Log(LOG_LEVEL_ERR, "DNS/service lookup failure. (getaddrinfo: %s)", GetErrorStr()); return -1; } int sd = -1; for (ap = response; ap != NULL; ap = ap->ai_next) { if ((sd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol)) == -1) { continue; } int yes = 1; if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) { Log(LOG_LEVEL_ERR, "Socket option SO_REUSEADDR was not accepted. (setsockopt: %s)", GetErrorStr()); exit(1); } struct linger cflinger = { .l_onoff = 1, .l_linger = 60 }; if (setsockopt(sd, SOL_SOCKET, SO_LINGER, &cflinger, sizeof(cflinger)) == -1) { Log(LOG_LEVEL_ERR, "Socket option SO_LINGER was not accepted. (setsockopt: %s)", GetErrorStr()); exit(1); } if (bind(sd, ap->ai_addr, ap->ai_addrlen) != -1) { if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { /* Convert IP address to string, no DNS lookup performed. */ char txtaddr[CF_MAX_IP_LEN] = ""; getnameinfo(ap->ai_addr, ap->ai_addrlen, txtaddr, sizeof(txtaddr), NULL, 0, NI_NUMERICHOST); Log(LOG_LEVEL_DEBUG, "Bound to address '%s' on '%s' = %d", txtaddr, CLASSTEXT[VSYSTEMHARDCLASS], VSYSTEMHARDCLASS); } break; } else { Log(LOG_LEVEL_ERR, "Could not bind server address. (bind: %s)", GetErrorStr()); cf_closesocket(sd); } } if (sd < 0) { Log(LOG_LEVEL_ERR, "Couldn't open/bind a socket"); exit(1); } freeaddrinfo(response); return sd; } /*********************************************************************/ /* Level 3 */ /*********************************************************************/ void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config) { Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'", config->input_file); if (NewPromiseProposals(ctx, config, InputFiles(ctx, *policy))) { Log(LOG_LEVEL_VERBOSE, "New promises detected..."); if (CheckPromises(config)) { Log(LOG_LEVEL_INFO, "Rereading policy file '%s'", config->input_file); /* Free & reload -- lock this to avoid access errors during reload */ EvalContextHeapClear(ctx); DeleteItemList(IPADDRESSES); IPADDRESSES = NULL; DeleteItemList(SV.trustkeylist); DeleteItemList(SV.skipverify); DeleteItemList(SV.attackerlist); DeleteItemList(SV.nonattackerlist); DeleteItemList(SV.multiconnlist); DeleteAuthList(SV.admit); DeleteAuthList(SV.deny); DeleteAuthList(SV.varadmit); DeleteAuthList(SV.vardeny); DeleteAuthList(SV.roles); //DeleteRlist(VINPUTLIST); This is just a pointer, cannot free it ScopeDeleteAll(); strcpy(VDOMAIN, "undefined.domain"); POLICY_SERVER[0] = '\0'; SV.admit = NULL; SV.admittop = NULL; SV.varadmit = NULL; SV.varadmittop = NULL; SV.deny = NULL; SV.denytop = NULL; SV.vardeny = NULL; SV.vardenytop = NULL; SV.roles = NULL; SV.rolestop = NULL; SV.trustkeylist = NULL; SV.skipverify = NULL; SV.attackerlist = NULL; SV.nonattackerlist = NULL; SV.multiconnlist = NULL; PolicyDestroy(*policy); *policy = NULL; { char *existing_policy_server = ReadPolicyServerFile(GetWorkDir()); SetPolicyServer(ctx, existing_policy_server); free(existing_policy_server); } GetNameInfo3(ctx, AGENT_TYPE_SERVER); GetInterfacesInfo(ctx, AGENT_TYPE_SERVER); Get3Environment(ctx, AGENT_TYPE_SERVER); BuiltinClasses(ctx); OSClasses(ctx); KeepHardClasses(ctx); EvalContextHeapAddHard(ctx, CF_AGENTTYPES[config->agent_type]); SetReferenceTime(ctx, true); *policy = GenericAgentLoadPolicy(ctx, config); KeepPromises(ctx, *policy, config); Summarize(); } else { Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring"); PROMISETIME = time(NULL); } } else { Log(LOG_LEVEL_DEBUG, "No new promises found"); } }
int main(int argc, char *argv[]) { int ret = 0; GenericAgentConfig *config = CheckOpts(argc, argv); #ifdef HAVE_AVAHI_CLIENT_CLIENT_H #ifdef HAVE_AVAHI_COMMON_ADDRESS_H if (NULL_OR_EMPTY(POLICY_SERVER) && BOOTSTRAP) { int ret = AutomaticBootstrap(); if (ret < 0) { return 1; } } #endif #endif ReportContext *report_context = OpenReports(config->agent_type); GenericAgentDiscoverContext(config, report_context); Policy *policy = NULL; if (GenericAgentCheckPolicy(config, report_context, ALWAYS_VALIDATE)) { policy = GenericAgentLoadPolicy(config->agent_type, config, report_context); } else if (config->tty_interactive) { FatalError("CFEngine was not able to get confirmation of promises from cf-promises, please verify input file\n"); } else { CfOut(OUTPUT_LEVEL_ERROR, "", "CFEngine was not able to get confirmation of promises from cf-promises, so going to failsafe\n"); HardClass("failsafe_fallback"); GenericAgentConfigSetInputFile(config, "failsafe.cf"); policy = GenericAgentLoadPolicy(config->agent_type, config, report_context); } CheckLicenses(); ThisAgentInit(); BeginAudit(); KeepPromises(policy, config, report_context); CloseReports("agent", report_context); // only note class usage when default policy is run if (!config->input_file) { NoteClassUsage(VHEAP, true); NoteClassUsage(VHARDHEAP, true); } #ifdef HAVE_NOVA Nova_NoteVarUsageDB(); Nova_TrackExecution(config->input_file); #endif PurgeLocks(); if (BOOTSTRAP && !VerifyBootstrap()) { ret = 1; } EndAudit(CFA_BACKGROUND); GenericAgentConfigDestroy(config); return ret; }
int main(int argc, char *argv[]) { #if !defined(__MINGW32__) int count = 0; int status; int pid; #endif EvalContext *ctx = EvalContextNew(); GenericAgentConfig *config = CheckOpts(argc, argv); GenericAgentConfigApply(ctx, config); GenericAgentDiscoverContext(ctx, config); Policy *policy = GenericAgentLoadPolicy(ctx, config); ThisAgentInit(); KeepControlPromises(ctx, policy); // Set RUNATTR using copy if (BACKGROUND && INTERACTIVE) { Log(LOG_LEVEL_ERR, "You cannot specify background mode and interactive mode together"); exit(EXIT_FAILURE); } /* HvB */ if (HOSTLIST) { const Rlist *rp = HOSTLIST; while (rp != NULL) { #ifdef __MINGW32__ if (BACKGROUND) { Log(LOG_LEVEL_VERBOSE, "Windows does not support starting processes in the background - starting in foreground"); BACKGROUND = false; } #else if (BACKGROUND) /* parallel */ { if (count <= MAXCHILD) { if (fork() == 0) /* child process */ { HailServer(ctx, RlistScalarValue(rp)); exit(EXIT_SUCCESS); } else /* parent process */ { rp = rp->next; count++; } } else { pid = wait(&status); Log(LOG_LEVEL_DEBUG, "child = %d, child number = %d", pid, count); count--; } } else /* serial */ #endif /* __MINGW32__ */ { HailServer(ctx, RlistScalarValue(rp)); rp = rp->next; } } /* end while */ } /* end if HOSTLIST */ #ifndef __MINGW32__ if (BACKGROUND) { Log(LOG_LEVEL_NOTICE, "Waiting for child processes to finish"); while (count > 1) { pid = wait(&status); Log(LOG_LEVEL_VERBOSE, "Child %d ended, number %d", pid, count); count--; } } #endif PolicyDestroy(policy); GenericAgentConfigDestroy(config); return 0; }
int main(int argc, char *argv[]) { EvalContext *ctx = EvalContextNew(); GenericAgentConfig *config = CheckOpts(ctx, argc, argv); GenericAgentConfigApply(ctx, config); ReportContext *report_context = OpenReports(config->agent_type); GenericAgentDiscoverContext(ctx, config, report_context); Policy *policy = GenericAgentLoadPolicy(ctx, config->agent_type, config, report_context); if (SHOWREPORTS) { ShowPromises(ctx, policy->bundles, policy->bodies); } CheckLicenses(ctx); switch (config->agent_specific.common.policy_output_format) { case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF: { Policy *output_policy = ParserParseFile(GenericAgentResolveInputPath(config->input_file, config->input_file)); Writer *writer = FileWriter(stdout); PolicyToString(policy, writer); WriterClose(writer); PolicyDestroy(output_policy); } break; case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON: { Policy *output_policy = ParserParseFile(GenericAgentResolveInputPath(config->input_file, config->input_file)); JsonElement *json_policy = PolicyToJson(output_policy); Writer *writer = FileWriter(stdout); JsonElementPrint(writer, json_policy, 2); WriterClose(writer); JsonElementDestroy(json_policy); PolicyDestroy(output_policy); } break; case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_NONE: break; } GenericAgentConfigDestroy(config); CloseReports("commmon", report_context); EvalContextDestroy(ctx); if (ERRORCOUNT > 0) { CfOut(OUTPUT_LEVEL_VERBOSE, "", " !! Inputs are invalid\n"); exit(1); } else { CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> Inputs are valid\n"); exit(0); } }
static bool ScheduleRun(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, ExecConfig *exec_config) { Log(LOG_LEVEL_VERBOSE, "Sleeping for pulse time %d seconds...", CFPULSETIME); sleep(CFPULSETIME); /* 1 Minute resolution is enough */ /* * FIXME: this logic duplicates the one from cf-serverd.c. Unify ASAP. */ if (CheckNewPromises(config, *policy) == RELOAD_FULL) { /* Full reload */ Log(LOG_LEVEL_INFO, "Re-reading promise file '%s'", config->input_file); EvalContextClear(ctx); strcpy(VDOMAIN, "undefined.domain"); PolicyDestroy(*policy); *policy = NULL; { char *existing_policy_server = ReadPolicyServerFile(GetWorkDir()); SetPolicyServer(ctx, existing_policy_server); free(existing_policy_server); } EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "policy_hub", POLICY_SERVER, DATA_TYPE_STRING, "goal=update,source=bootstrap"); DetectEnvironment(ctx, false, true); EvalContextClassPutHard(ctx, CF_AGENTTYPES[AGENT_TYPE_EXECUTOR], "goal=state,cfe_internal,source=agent"); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); GenericAgentConfigSetBundleSequence(config, NULL); *policy = GenericAgentLoadPolicy(ctx, config); ExecConfigUpdate(ctx, *policy, exec_config); SetFacility(exec_config->log_facility); } else { /* Environment reload */ EvalContextClear(ctx); DetectEnvironment(ctx, false, false); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); } { StringSetIterator it = StringSetIteratorInit(exec_config->schedule); const char *time_context = NULL; while ((time_context = StringSetIteratorNext(&it))) { if (IsDefinedClass(ctx, time_context, NULL)) { Log(LOG_LEVEL_VERBOSE, "Waking up the agent at %s ~ %s", ctime(&CFSTARTTIME), time_context); return true; } } } Log(LOG_LEVEL_VERBOSE, "Nothing to do at %s", ctime(&CFSTARTTIME)); return false; }
int main(int argc, char *argv[]) { GenericAgentConfig *config = CheckOpts(argc, argv); ReportContext *report_context = OpenReports(config->agent_type); GenericAgentDiscoverContext(config, report_context); Policy *policy = NULL; if (GenericAgentCheckPolicy(config, report_context, false)) { policy = GenericAgentLoadPolicy(config->agent_type, config, report_context); } else if (config->tty_interactive) { FatalError("CFEngine was not able to get confirmation of promises from cf-promises, please verify input file\n"); } else { CfOut(OUTPUT_LEVEL_ERROR, "", "CFEngine was not able to get confirmation of promises from cf-promises, so going to failsafe\n"); HardClass("failsafe_fallback"); GenericAgentConfigSetInputFile(config, "failsafe.cf"); policy = GenericAgentLoadPolicy(config->agent_type, config, report_context); } CheckLicenses(); ThisAgentInit(); ExecConfig exec_config = { .scheduled_run = !ONCE, .exec_command = SafeStringDuplicate(""), .mail_server = SafeStringDuplicate(""), .mail_from_address = SafeStringDuplicate(""), .mail_to_address = SafeStringDuplicate(""), .mail_max_lines = 30, .fq_name = VFQNAME, .ip_address = VIPADDRESS, .agent_expireafter = 10080, }; KeepPromises(policy, &exec_config); #ifdef __MINGW32__ if (WINSERVICE) { NovaWin_StartExecService(); } else #endif /* __MINGW32__ */ { StartServer(policy, config, &exec_config, report_context); } ReportContextDestroy(report_context); GenericAgentConfigDestroy(config); return 0; } /*****************************************************************************/ /* Level 1 */ /*****************************************************************************/ static GenericAgentConfig *CheckOpts(int argc, char **argv) { extern char *optarg; int optindex = 0; int c; char ld_library_path[CF_BUFSIZE]; GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_EXECUTOR); while ((c = getopt_long(argc, argv, "dvnKIf:D:N:VxL:hFOV1gMW", OPTIONS, &optindex)) != EOF) { switch ((char) c) { case 'f': if (optarg && strlen(optarg) < 5) { FatalError(" -f used but argument \"%s\" incorrect", optarg); } GenericAgentConfigSetInputFile(config, optarg); MINUSF = true; break; case 'd': HardClass("opt_debug"); DEBUG = true; break; case 'K': IGNORELOCK = true; break; case 'D': NewClassesFromString(optarg); break; case 'N': NegateClassesFromString(optarg); break; case 'I': INFORM = true; break; case 'v': VERBOSE = true; NO_FORK = true; break; case 'n': DONTDO = true; IGNORELOCK = true; HardClass("opt_dry_run"); break; case 'L': snprintf(ld_library_path, CF_BUFSIZE - 1, "LD_LIBRARY_PATH=%s", optarg); if (putenv(xstrdup(ld_library_path)) != 0) { } break; case 'W': WINSERVICE = false; break; case 'F': NO_FORK = true; break; case 'O': ONCE = true; break; case 'V': PrintVersionBanner("cf-execd"); exit(0); case 'h': Syntax("cf-execd - cfengine's execution agent", OPTIONS, HINTS, ID); exit(0); case 'M': ManPage("cf-execd - cfengine's execution agent", OPTIONS, HINTS, ID); exit(0); case 'x': CfOut(OUTPUT_LEVEL_ERROR, "", "Self-diagnostic functionality is retired."); exit(0); default: Syntax("cf-execd - cfengine's execution agent", OPTIONS, HINTS, ID); exit(1); } } if (argv[optind] != NULL) { CfOut(OUTPUT_LEVEL_ERROR, "", "Unexpected argument with no preceding option: %s\n", argv[optind]); } return config; } /*****************************************************************************/ static void LoadDefaultSchedule(void) { CfDebug("Loading default schedule...\n"); DeleteItemList(SCHEDULE); SCHEDULE = NULL; AppendItem(&SCHEDULE, "Min00", NULL); AppendItem(&SCHEDULE, "Min05", NULL); AppendItem(&SCHEDULE, "Min10", NULL); AppendItem(&SCHEDULE, "Min15", NULL); AppendItem(&SCHEDULE, "Min20", NULL); AppendItem(&SCHEDULE, "Min25", NULL); AppendItem(&SCHEDULE, "Min30", NULL); AppendItem(&SCHEDULE, "Min35", NULL); AppendItem(&SCHEDULE, "Min40", NULL); AppendItem(&SCHEDULE, "Min45", NULL); AppendItem(&SCHEDULE, "Min50", NULL); AppendItem(&SCHEDULE, "Min55", NULL); }
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; }
int main(int argc, char *argv[]) { Rlist *rp; #if !defined(__MINGW32__) int count = 0; int status; int pid; #endif EvalContext *ctx = EvalContextNew(); GenericAgentConfig *config = CheckOpts(ctx, argc, argv); GenericAgentConfigApply(ctx, config); GenericAgentDiscoverContext(ctx, config); Policy *policy = GenericAgentLoadPolicy(ctx, config); WarnAboutDeprecatedFeatures(ctx); CheckForPolicyHub(ctx); ThisAgentInit(); KeepControlPromises(ctx, policy); // Set RUNATTR using copy if (BACKGROUND && INTERACTIVE) { CfOut(OUTPUT_LEVEL_ERROR, "", " !! You cannot specify background mode and interactive mode together"); exit(1); } /* HvB */ if (HOSTLIST) { rp = HOSTLIST; while (rp != NULL) { #ifdef __MINGW32__ if (BACKGROUND) { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Windows does not support starting processes in the background - starting in foreground"); BACKGROUND = false; } #else if (BACKGROUND) /* parallel */ { if (count <= MAXCHILD) { if (fork() == 0) /* child process */ { HailServer(ctx, rp->item); exit(0); } else /* parent process */ { rp = rp->next; count++; } } else { pid = wait(&status); CfDebug("child = %d, child number = %d\n", pid, count); count--; } } else /* serial */ #endif /* __MINGW32__ */ { HailServer(ctx, rp->item); rp = rp->next; } } /* end while */ } /* end if HOSTLIST */ #ifndef __MINGW32__ if (BACKGROUND) { printf("Waiting for child processes to finish\n"); while (count > 1) { pid = wait(&status); CfOut(OUTPUT_LEVEL_VERBOSE, "", "Child = %d ended, number = %d\n", pid, count); count--; } } #endif GenericAgentConfigDestroy(config); return 0; }
static bool ScheduleRun(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, ExecConfig *exec_config) { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Sleeping for pulse time %d seconds...\n", CFPULSETIME); sleep(CFPULSETIME); /* 1 Minute resolution is enough */ /* * FIXME: this logic duplicates the one from cf-serverd.c. Unify ASAP. */ if (CheckNewPromises(ctx, config, InputFiles(ctx, *policy)) == RELOAD_FULL) { /* Full reload */ CfOut(OUTPUT_LEVEL_INFORM, "", "Re-reading promise file %s..\n", config->input_file); EvalContextHeapClear(ctx); DeleteItemList(IPADDRESSES); IPADDRESSES = NULL; ScopeDeleteAll(); strcpy(VDOMAIN, "undefined.domain"); POLICY_SERVER[0] = '\0'; PolicyDestroy(*policy); *policy = NULL; SetPolicyServer(ctx, POLICY_SERVER); ScopeNewSpecialScalar(ctx, "sys", "policy_hub", POLICY_SERVER, DATA_TYPE_STRING); GetNameInfo3(ctx, AGENT_TYPE_EXECUTOR); GetInterfacesInfo(ctx, AGENT_TYPE_EXECUTOR); Get3Environment(ctx, AGENT_TYPE_EXECUTOR); BuiltinClasses(ctx); OSClasses(ctx); EvalContextHeapAddHard(ctx, CF_AGENTTYPES[AGENT_TYPE_EXECUTOR]); SetReferenceTime(ctx, true); GenericAgentConfigSetBundleSequence(config, NULL); *policy = GenericAgentLoadPolicy(ctx, config); ExecConfigUpdate(ctx, *policy, exec_config); SetFacility(exec_config->log_facility); } else { /* Environment reload */ EvalContextHeapClear(ctx); DeleteItemList(IPADDRESSES); IPADDRESSES = NULL; ScopeClear("this"); ScopeClear("mon"); ScopeClear("sys"); GetInterfacesInfo(ctx, AGENT_TYPE_EXECUTOR); Get3Environment(ctx, AGENT_TYPE_EXECUTOR); BuiltinClasses(ctx); OSClasses(ctx); SetReferenceTime(ctx, true); } { StringSetIterator it = StringSetIteratorInit(exec_config->schedule); const char *time_context = NULL; while ((time_context = StringSetIteratorNext(&it))) { if (IsDefinedClass(ctx, time_context, NULL)) { CfOut(OUTPUT_LEVEL_VERBOSE, "", "Waking up the agent at %s ~ %s \n", cf_ctime(&CFSTARTTIME), time_context); return true; } } } CfOut(OUTPUT_LEVEL_VERBOSE, "", "Nothing to do at %s\n", cf_ctime(&CFSTARTTIME)); return false; }
int OpenReceiverChannel(void) { struct addrinfo *response, *ap; struct addrinfo query = { .ai_flags = AI_PASSIVE, .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM }; /* Listen to INADDR(6)_ANY if BINDINTERFACE unset. */ char *ptr = NULL; if (BINDINTERFACE[0] != '\0') { ptr = BINDINTERFACE; } char servname[10]; snprintf(servname, 10, "%d", CFENGINE_PORT); /* Resolve listening interface. */ if (getaddrinfo(ptr, servname, &query, &response) != 0) { Log(LOG_LEVEL_ERR, "DNS/service lookup failure. (getaddrinfo: %s)", GetErrorStr()); return -1; } int sd = -1; for (ap = response; ap != NULL; ap = ap->ai_next) { if ((sd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol)) == -1) { continue; } int yes = 1; if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) { Log(LOG_LEVEL_ERR, "Socket option SO_REUSEADDR was not accepted. (setsockopt: %s)", GetErrorStr()); exit(1); } struct linger cflinger = { .l_onoff = 1, .l_linger = 60 }; if (setsockopt(sd, SOL_SOCKET, SO_LINGER, &cflinger, sizeof(cflinger)) == -1) { Log(LOG_LEVEL_ERR, "Socket option SO_LINGER was not accepted. (setsockopt: %s)", GetErrorStr()); exit(1); } if (bind(sd, ap->ai_addr, ap->ai_addrlen) != -1) { if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { /* Convert IP address to string, no DNS lookup performed. */ char txtaddr[CF_MAX_IP_LEN] = ""; getnameinfo(ap->ai_addr, ap->ai_addrlen, txtaddr, sizeof(txtaddr), NULL, 0, NI_NUMERICHOST); Log(LOG_LEVEL_DEBUG, "Bound to address '%s' on '%s' = %d", txtaddr, CLASSTEXT[VSYSTEMHARDCLASS], VSYSTEMHARDCLASS); } break; } else { Log(LOG_LEVEL_ERR, "Could not bind server address. (bind: %s)", GetErrorStr()); cf_closesocket(sd); } } if (sd < 0) { Log(LOG_LEVEL_ERR, "Couldn't open/bind a socket"); exit(1); } freeaddrinfo(response); return sd; } /*********************************************************************/ /* Level 3 */ /*********************************************************************/ void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, time_t *last_policy_reload) { time_t validated_at; Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'", config->input_file); validated_at = ReadTimestampFromPolicyValidatedMasterfiles(config); if (*last_policy_reload < validated_at) { *last_policy_reload = validated_at; Log(LOG_LEVEL_VERBOSE, "New promises detected..."); if (GenericAgentArePromisesValid(config)) { Log(LOG_LEVEL_INFO, "Rereading policy file '%s'", config->input_file); /* Free & reload -- lock this to avoid access errors during reload */ EvalContextClear(ctx); free(SV.allowciphers); SV.allowciphers = NULL; DeleteItemList(SV.trustkeylist); DeleteItemList(SV.attackerlist); DeleteItemList(SV.nonattackerlist); DeleteItemList(SV.multiconnlist); DeleteAuthList(SV.admit); DeleteAuthList(SV.deny); DeleteAuthList(SV.varadmit); DeleteAuthList(SV.vardeny); DeleteAuthList(SV.roles); strcpy(VDOMAIN, "undefined.domain"); SV.admit = NULL; SV.admittop = NULL; SV.varadmit = NULL; SV.varadmittop = NULL; SV.deny = NULL; SV.denytop = NULL; SV.vardeny = NULL; SV.vardenytop = NULL; SV.roles = NULL; SV.rolestop = NULL; SV.trustkeylist = NULL; SV.attackerlist = NULL; SV.nonattackerlist = NULL; SV.multiconnlist = NULL; PolicyDestroy(*policy); *policy = NULL; { char *existing_policy_server = ReadPolicyServerFile(GetWorkDir()); SetPolicyServer(ctx, existing_policy_server); free(existing_policy_server); } UpdateLastPolicyUpdateTime(ctx); DetectEnvironment(ctx); KeepHardClasses(ctx); EvalContextClassPutHard(ctx, CF_AGENTTYPES[config->agent_type], "cfe_internal,source=agent"); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); *policy = GenericAgentLoadPolicy(ctx, config); KeepPromises(ctx, *policy, config); Summarize(); } else { Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring"); } } else { Log(LOG_LEVEL_DEBUG, "No new promises found"); } }