static void Apoptosis(void) { char promiser_buf[CF_SMALLBUF]; snprintf(promiser_buf, sizeof(promiser_buf), "%s/bin/cf-execd", CFWORKDIR); if (LoadProcessTable(&PROCESSTABLE)) { char myuid[32]; snprintf(myuid, 32, "%d", (int)getuid()); Rlist *owners = NULL; RlistPrepend(&owners, myuid, RVAL_TYPE_SCALAR); ProcessSelect process_select = { .owner = owners, .process_result = "process_owner", }; Item *killlist = SelectProcesses(PROCESSTABLE, promiser_buf, process_select, true); RlistDestroy(owners); for (Item *ip = killlist; ip != NULL; ip = ip->next) { pid_t pid = ip->counter; if (pid != getpid() && kill(pid, SIGTERM) < 0) { if (errno == ESRCH) { /* That's ok, process exited voluntarily */ } else { Log(LOG_LEVEL_ERR, "Unable to kill stale cf-execd process pid=%d. (kill: %s)", (int)pid, GetErrorStr()); } } } } DeleteItemList(PROCESSTABLE); Log(LOG_LEVEL_VERBOSE, "Pruning complete"); }
static void Apoptosis(void) { static char promiser_buf[CF_SMALLBUF]; snprintf(promiser_buf, sizeof(promiser_buf), "%s/bin/cf-execd", CFWORKDIR); if (LoadProcessTable(&PROCESSTABLE)) { char myuid[32]; snprintf(myuid, 32, "%d", (int)getuid()); Rlist *owners = NULL; RlistPrependScalar(&owners, myuid); ProcessSelect process_select = { .owner = owners, .process_result = "process_owner", }; Item *killlist = SelectProcesses(PROCESSTABLE, promiser_buf, process_select, true); for (Item *ip = killlist; ip != NULL; ip = ip->next) { pid_t pid = ip->counter; if (pid != getpid() && kill(pid, SIGTERM) < 0) { if (errno == ESRCH) { /* That's ok, process exited voluntarily */ } else { CfOut(OUTPUT_LEVEL_ERROR, "kill", "Unable to kill stale cf-execd process (pid=%d)", (int)pid); } } } } DeleteItemList(PROCESSTABLE); CfOut(OUTPUT_LEVEL_VERBOSE, "", " !! Pruning complete"); }
static int FindPidMatches(EvalContext *ctx, Item *procdata, Item **killlist, Attributes a, const char *promiser) { int matches = 0; pid_t cfengine_pid = getpid(); Item *matched = SelectProcesses(ctx, procdata, promiser, a.process_select, a.haveselect); for (Item *ip = matched; ip != NULL; ip = ip->next) { pid_t pid = ip->counter; if (pid == 1) { if ((RlistLen(a.signals) == 1) && (RlistIsStringIn(a.signals, "hup"))) { Log(LOG_LEVEL_VERBOSE, "Okay to send only HUP to init"); } else { continue; } } if ((pid < 4) && (a.signals)) { Log(LOG_LEVEL_VERBOSE, "Will not signal or restart processes 0,1,2,3 (occurred while looking for %s)", promiser); continue; } bool promised_zero = (a.process_count.min_range == 0) && (a.process_count.max_range == 0); if ((a.transaction.action == cfa_warn) && promised_zero) { Log(LOG_LEVEL_ERR, "Process alert '%s'", procdata->name); /* legend */ Log(LOG_LEVEL_ERR, "Process alert '%s'", ip->name); continue; } if ((pid == cfengine_pid) && (a.signals)) { Log(LOG_LEVEL_VERBOSE, "cf-agent will not signal itself!"); continue; } if (a.transaction.action == cfa_warn) { Log(LOG_LEVEL_ERR, "Matched '%s'", ip->name); } else { Log(LOG_LEVEL_VERBOSE, "Matched '%s'", ip->name); } PrependItem(killlist, ip->name, ""); (*killlist)->counter = pid; matches++; } DeleteItemList(matched); return matches; }
static void Apoptosis(void) { char promiser_buf[CF_SMALLBUF]; snprintf(promiser_buf, sizeof(promiser_buf), "%s%cbin%ccf-execd", GetWorkDir(), FILE_SEPARATOR, FILE_SEPARATOR); if (LoadProcessTable()) { char myuid[PRINTSIZE(unsigned)]; xsnprintf(myuid, sizeof(myuid), "%u", (unsigned) getuid()); Rlist *owners = NULL; RlistPrepend(&owners, myuid, RVAL_TYPE_SCALAR); ProcessSelect process_select = { .owner = owners, .process_result = "process_owner", }; Item *killlist = SelectProcesses(promiser_buf, process_select, true); RlistDestroy(owners); for (Item *ip = killlist; ip != NULL; ip = ip->next) { pid_t pid = ip->counter; if (pid != getpid() && kill(pid, SIGTERM) < 0) { if (errno == ESRCH) { /* That's ok, process exited voluntarily */ } else { Log(LOG_LEVEL_ERR, "Unable to kill stale cf-execd process pid=%d. (kill: %s)", (int)pid, GetErrorStr()); } } } } ClearProcessTable(); Log(LOG_LEVEL_VERBOSE, "Pruning complete"); } #endif typedef enum { RELOAD_ENVIRONMENT, RELOAD_FULL } Reload; static Reload CheckNewPromises(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)) { return RELOAD_FULL; } else { Log(LOG_LEVEL_INFO, "New promises file contains syntax errors -- ignoring"); } } else { Log(LOG_LEVEL_DEBUG, "No new promises found"); } return RELOAD_ENVIRONMENT; }
static int FindPidMatches(Item **killlist, Attributes a, const char *promiser) { int matches = 0; pid_t cfengine_pid = getpid(); Item *matched = SelectProcesses(promiser, a.process_select, a.haveselect); for (Item *ip = matched; ip != NULL; ip = ip->next) { pid_t pid = ip->counter; if (a.signals) /* There are some processes we don't want to signal. */ { if (pid == 1) { if (RlistLen(a.signals) == 1 && RlistKeyIn(a.signals, "hup")) { Log(LOG_LEVEL_VERBOSE, "Okay to send only HUP to init"); } else { continue; } } else if (pid < 4) { Log(LOG_LEVEL_VERBOSE, "Will not signal or restart processes 0,1,2,3 (occurred while looking for %s)", promiser); continue; } if (pid == cfengine_pid) { Log(LOG_LEVEL_VERBOSE, "cf-agent will not signal itself!"); continue; } } bool promised_zero = (a.process_count.min_range == 0) && (a.process_count.max_range == 0); if ((a.transaction.action == cfa_warn) && promised_zero) { Log(LOG_LEVEL_WARNING, "Process alert '%s'", GetProcessTableLegend()); Log(LOG_LEVEL_WARNING, "Process alert '%s'", ip->name); continue; } if (a.transaction.action == cfa_warn) { Log(LOG_LEVEL_WARNING, "Matched '%s'", ip->name); } else { Log(LOG_LEVEL_VERBOSE, "Matched '%s'", ip->name); } PrependItem(killlist, ip->name, ""); (*killlist)->counter = pid; matches++; } DeleteItemList(matched); return matches; }