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 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; }
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"); } } }
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"); } } }
void GenericAgentDiscoverContext(EvalContext *ctx, GenericAgentConfig *config) { strcpy(VPREFIX, ""); Log(LOG_LEVEL_VERBOSE, " %s", NameVersion()); Banner("Initialization preamble"); 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; LoggingSetAgentType(CF_AGENTTYPES[config->agent_type]); EvalContextClassPutHard(ctx, CF_AGENTTYPES[config->agent_type], "cfe_internal,source=agent"); DetectEnvironment(ctx); EvalContextHeapPersistentLoadAll(ctx); LoadSystemConstants(ctx); const char *bootstrap_arg = config->agent_specific.agent.bootstrap_policy_server; /* Are we bootstrapping the agent? */ if (config->agent_type == AGENT_TYPE_AGENT && bootstrap_arg != NULL) { EvalContextClassPutHard(ctx, "bootstrap_mode", "source=environment"); 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); } char canonified_ipaddr[strlen(bootstrap_arg) + 1]; StringCanonify(canonified_ipaddr, bootstrap_arg); bool am_policy_server = EvalContextClassGet(ctx, NULL, canonified_ipaddr) != NULL; if (am_policy_server) { Log(LOG_LEVEL_INFO, "Assuming role as policy server," " with policy distribution point at: %s", GetMasterDir()); MarkAsPolicyServer(ctx); 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); } CheckAndSetHAState(GetWorkDir(), ctx); } else { Log(LOG_LEVEL_INFO, "Assuming role as regular client," " bootstrapping to policy server: %s", bootstrap_arg); if (config->agent_specific.agent.bootstrap_trust_server) { EvalContextClassPutHard(ctx, "trust_server", "source=agent"); Log(LOG_LEVEL_NOTICE, "Bootstrap mode: implicitly trusting server, " "use --trust-server=no if server trust is already established"); } } WriteAmPolicyHubFile(am_policy_server); WritePolicyServerFile(GetWorkDir(), bootstrap_arg); SetPolicyServer(ctx, bootstrap_arg); /* FIXME: Why it is called here? Can't we move both invocations to before if? */ UpdateLastPolicyUpdateTime(ctx); } 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 -" " can't find policy_server.dat in: %s", GetWorkDir()); return; } if (GetAmPolicyHub()) { MarkAsPolicyServer(ctx); /* Should this go in MarkAsPolicyServer() ? */ CheckAndSetHAState(GetWorkDir(), ctx); } } }
static bool ScheduleRun(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, ExecdConfig **execd_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) == 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); } UpdateLastPolicyUpdateTime(ctx); DetectEnvironment(ctx); EvalContextClassPutHard(ctx, CF_AGENTTYPES[AGENT_TYPE_EXECUTOR], "cfe_internal,source=agent"); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); GenericAgentConfigSetBundleSequence(config, NULL); *policy = LoadPolicy(ctx, config); ExecConfigDestroy(*exec_config); ExecdConfigDestroy(*execd_config); *exec_config = ExecConfigNew(!ONCE, ctx, *policy); *execd_config = ExecdConfigNew(ctx, *policy); SetFacility((*execd_config)->log_facility); } else { /* Environment reload */ EvalContextClear(ctx); DetectEnvironment(ctx); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); } { StringSetIterator it = StringSetIteratorInit((*execd_config)->schedule); const char *time_context = NULL; while ((time_context = StringSetIteratorNext(&it))) { if (IsDefinedClass(ctx, time_context)) { 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; }
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(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"); } }
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"); } }
void GenericInitialize(int argc,char **argv,char *agents) { enum cfagenttype ag = Agent2Type(agents); char vbuff[CF_BUFSIZE]; int ok = false; #ifdef HAVE_NOVA CF_DEFAULT_DIGEST = cf_sha256; CF_DEFAULT_DIGEST_LEN = CF_SHA256_LEN; #else CF_DEFAULT_DIGEST = cf_md5; CF_DEFAULT_DIGEST_LEN = CF_MD5_LEN; #endif InitializeGA(argc,argv); SetReferenceTime(true); SetStartTime(false); SetSignals(); SanitizeEnvironment(); strcpy(THIS_AGENT,CF_AGENTTYPES[ag]); NewClass(THIS_AGENT); THIS_AGENT_TYPE = ag; // need scope sys to set vars in expiry function SetNewScope("sys"); if (EnterpriseExpiry()) { CfOut(cf_error,"","Cfengine - autonomous configuration engine. This enterprise license is invalid.\n"); exit(1); } if (AM_NOVA) { CfOut(cf_verbose,""," -> This is CFE Nova\n"); } if (AM_CONSTELLATION) { CfOut(cf_verbose,""," -> This is CFE Constellation\n"); } NewScope("const"); NewScope("match"); NewScope("mon"); GetNameInfo3(); CfGetInterfaceInfo(ag); if (ag != cf_know) { Get3Environment(); BuiltinClasses(); OSClasses(); } LoadPersistentContext(); LoadSystemConstants(); snprintf(vbuff,CF_BUFSIZE,"control_%s",THIS_AGENT); SetNewScope(vbuff); NewScope("this"); NewScope("match"); if (BOOTSTRAP) { CheckAutoBootstrap(); } else { if (strlen(POLICY_SERVER) > 0) { CfOut(cf_verbose,""," -> Found a policy server (hub) on %s",POLICY_SERVER); } else { CfOut(cf_verbose,""," -> No policy server (hub) watch yet registered"); } } SetPolicyServer(POLICY_SERVER); if (ag != cf_keygen) { if (!MissingInputFile()) { bool check_promises = false; if (SHOWREPORTS) { check_promises = true; CfOut(cf_verbose, "", " -> Reports mode is enabled, force-validating policy"); } if (IsFileOutsideDefaultRepository(VINPUTFILE)) { check_promises = true; CfOut(cf_verbose, "", " -> Input file is outside default repository, validating it"); } if (NewPromiseProposals()) { check_promises = true; CfOut(cf_verbose, "", " -> Input file is changed since last validation, validating it"); } if (check_promises) { ok = CheckPromises(ag); if (BOOTSTRAP && !ok) { CfOut(cf_verbose, "", " -> Policy is not valid, but proceeding with bootstrap"); ok = true; } } else { CfOut(cf_verbose, "", " -> Policy is already validated"); ok = true; } } if (ok) { ReadPromises(ag,agents); } else { CfOut(cf_error,"","cf-agent was not able to get confirmation of promises from cf-promises, so going to failsafe\n"); snprintf(VINPUTFILE,CF_BUFSIZE-1,"failsafe.cf"); ReadPromises(ag,agents); } if (SHOWREPORTS) { CompilationReport(VINPUTFILE); } CheckLicenses(); } XML = 0; }
static void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config) { Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'", config->input_file); time_t validated_at = ReadTimestampFromPolicyValidatedFile(config, NULL); bool reload_config = false; if (config->agent_specific.daemon.last_validated_at < validated_at) { Log(LOG_LEVEL_VERBOSE, "New promises detected..."); reload_config = true; } if (ReloadConfigRequested()) { Log(LOG_LEVEL_VERBOSE, "Force reload of inputs files..."); reload_config = true; } if (reload_config) { ClearRequestReloadConfig(); /* Rereading policies now, so update timestamp. */ config->agent_specific.daemon.last_validated_at = validated_at; if (GenericAgentArePromisesValid(config)) { Log(LOG_LEVEL_NOTICE, "Rereading policy file '%s'", config->input_file); /* STEP 1: Free everything */ EvalContextClear(ctx); strcpy(VDOMAIN, "undefined.domain"); ClearAuthAndACLs(); PolicyDestroy(*policy); *policy = NULL; /* STEP 2: Set Environment, Parse and Evaluate policy */ /* * TODO why is this done separately here? What's the difference to * calling the same steps as in cf-serverd.c:main()? Those are: * GenericAgentConfigApply(); // not here! * GenericAgentDiscoverContext(); // not here! * EvalContextClassPutHard("server"); // only here! * if (GenericAgentCheckPolicy()) // not here! * policy = LoadPolicy(); * ThisAgentInit(); // not here, only calls umask() * ReloadHAConfig(); // only here! * KeepPromises(); * Summarize(); * Plus the following from within StartServer() which is only * called during startup: * InitSignals(); // not here * ServerTLSInitialize(); // not here * SetServerListenState(); // not here * InitServer() // not here * PolicyNew()+AcquireServerLock() // not here * PrepareServer(sd); // not here * CollectCallStart(); // both */ char *existing_policy_server = ReadPolicyServerFile(GetWorkDir()); SetPolicyServer(ctx, existing_policy_server); free(existing_policy_server); UpdateLastPolicyUpdateTime(ctx); DetectEnvironment(ctx); KeepHardClasses(ctx); /* During startup this is done in GenericAgentDiscoverContext(). */ EvalContextClassPutHard(ctx, CF_AGENTTYPES[AGENT_TYPE_SERVER], "cfe_internal,source=agent"); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); /* TODO BUG: this modifies config, but previous config has not * been reset/free'd. Ideally we would want LoadPolicy to not * modify config at all, but only modify ctx. */ *policy = LoadPolicy(ctx, config); /* Reload HA related configuration */ ReloadHAConfig(); KeepPromises(ctx, *policy, config); Summarize(); } else { Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring"); } } else { Log(LOG_LEVEL_DEBUG, "No new promises found"); } }
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); }
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"); } }