void GenericAgentConfigApply(EvalContext *ctx, const GenericAgentConfig *config) { if (config->heap_soft) { StringSetIterator it = StringSetIteratorInit(config->heap_soft); const char *context = NULL; while ((context = StringSetIteratorNext(&it))) { if (EvalContextHeapContainsHard(ctx, context)) { FatalError(ctx, "cfengine: You cannot use -D to define a reserved class!"); } EvalContextHeapAddSoft(ctx, context, NULL); } } if (config->heap_negated) { StringSetIterator it = StringSetIteratorInit(config->heap_negated); const char *context = NULL; while ((context = StringSetIteratorNext(&it))) { if (EvalContextHeapContainsHard(ctx, context)) { FatalError(ctx, "Cannot negate the reserved class [%s]\n", context); } EvalContextHeapAddNegated(ctx, context); } } switch (LogGetGlobalLevel()) { case LOG_LEVEL_DEBUG: EvalContextHeapAddHard(ctx, "debug_mode"); EvalContextHeapAddHard(ctx, "opt_debug"); // intentional fall case LOG_LEVEL_VERBOSE: EvalContextHeapAddHard(ctx, "verbose_mode"); // intentional fall case LOG_LEVEL_INFO: EvalContextHeapAddHard(ctx, "inform_mode"); break; default: break; } if (config->agent_specific.agent.bootstrap_policy_server) { EvalContextHeapAddHard(ctx, "bootstrap_mode"); } if (config->color) { LoggingSetColor(config->color); } }
static void DeleteAllClasses(EvalContext *ctx, const Rlist *list) { for (const Rlist *rp = list; rp != NULL; rp = rp->next) { if (CheckParseContext((char *) rp->item, CF_IDRANGE) != SYNTAX_TYPE_MATCH_OK) { return; // TODO: interesting course of action, but why is the check there in the first place? } if (EvalContextHeapContainsHard(ctx, (char *) rp->item)) { Log(LOG_LEVEL_ERR, "You cannot cancel a reserved hard class '%s' in post-condition classes", RlistScalarValue(rp)); } const char *string = (char *) (rp->item); Log(LOG_LEVEL_VERBOSE, "Cancelling class '%s'", string); EvalContextHeapPersistentRemove(string); EvalContextHeapRemoveSoft(ctx, CanonifyName(string)); EvalContextStackFrameAddNegated(ctx, CanonifyName(string)); } }
void EvalContextHeapAddHard(EvalContext *ctx, const char *context) { char context_copy[CF_MAXVARSIZE]; strcpy(context_copy, context); if (Chop(context_copy, CF_EXPANDSIZE) == -1) { CfOut(OUTPUT_LEVEL_ERROR, "", "Chop was called on a string that seemed to have no terminator"); } CanonifyNameInPlace(context_copy); CfDebug("EvalContextHeapAddHard(%s)\n", context_copy); if (strlen(context_copy) == 0) { return; } if (IsRegexItemIn(ctx, ctx->heap_abort_current_bundle, context_copy)) { CfOut(OUTPUT_LEVEL_ERROR, "", "Bundle aborted on defined class \"%s\"\n", context_copy); ABORTBUNDLE = true; } if (IsRegexItemIn(ctx, ctx->heap_abort, context_copy)) { CfOut(OUTPUT_LEVEL_ERROR, "", "cf-agent aborted on defined class \"%s\"\n", context_copy); exit(1); } if (EvalContextHeapContainsHard(ctx, context_copy)) { return; } StringSetAdd(ctx->heap_hard, xstrdup(context_copy)); for (const Item *ip = ctx->heap_abort; ip != NULL; ip = ip->next) { if (IsDefinedClass(ctx, ip->name, NULL)) { CfOut(OUTPUT_LEVEL_ERROR, "", "cf-agent aborted on defined class \"%s\" defined in bundle %s\n", ip->name, StackFrameOwnerName(LastStackFrame(ctx, 0))); exit(1); } } if (!ABORTBUNDLE) { for (const Item *ip = ctx->heap_abort_current_bundle; ip != NULL; ip = ip->next) { if (IsDefinedClass(ctx, ip->name, NULL)) { CfOut(OUTPUT_LEVEL_ERROR, "", " -> Setting abort for \"%s\" when setting \"%s\"", ip->name, context_copy); ABORTBUNDLE = true; break; } } } }
static ExpressionValue EvalTokenAsClass(const char *classname, void *param) { const EvalContext *ctx = ((EvalTokenAsClassContext *)param)->ctx; const char *ns = ((EvalTokenAsClassContext *)param)->ns; char qualified_class[CF_MAXVARSIZE]; if (strcmp(classname, "any") == 0) { return true; } if (strchr(classname, ':')) { if (strncmp(classname, "default:", strlen("default:")) == 0) { snprintf(qualified_class, CF_MAXVARSIZE, "%s", classname + strlen("default:")); } else { snprintf(qualified_class, CF_MAXVARSIZE, "%s", classname); } } else if (ns != NULL && strcmp(ns, "default") != 0) { snprintf(qualified_class, CF_MAXVARSIZE, "%s:%s", ns, (char *)classname); } else { snprintf(qualified_class, CF_MAXVARSIZE, "%s", classname); } if (EvalContextHeapContainsNegated(ctx, qualified_class)) { return false; } if (EvalContextStackFrameContainsNegated(ctx, qualified_class)) { return false; } if (EvalContextHeapContainsHard(ctx, classname)) // Hard classes are always unqualified { return true; } if (EvalContextHeapContainsSoft(ctx, qualified_class)) { return true; } if (EvalContextStackFrameContainsSoft(ctx, qualified_class)) { return true; } return false; }
static void AddAllClasses(EvalContext *ctx, const char *ns, const Rlist *list, bool persist, ContextStatePolicy policy, ContextScope context_scope) { for (const Rlist *rp = list; rp != NULL; rp = rp->next) { char *classname = xstrdup(rp->item); CanonifyNameInPlace(classname); if (EvalContextHeapContainsHard(ctx, classname)) { Log(LOG_LEVEL_ERR, "You cannot use reserved hard class '%s' as post-condition class", classname); // TODO: ok.. but should we take any action? continue; maybe? } if (persist > 0) { if (context_scope != CONTEXT_SCOPE_NAMESPACE) { Log(LOG_LEVEL_INFO, "Automatically promoting context scope for '%s' to namespace visibility, due to persistence", classname); } Log(LOG_LEVEL_VERBOSE, "Defining persistent promise result class '%s'", classname); EvalContextHeapPersistentSave(CanonifyName(rp->item), ns, persist, policy); EvalContextHeapAddSoft(ctx, classname, ns); } else { Log(LOG_LEVEL_VERBOSE, "Defining promise result class '%s'", classname); switch (context_scope) { case CONTEXT_SCOPE_BUNDLE: EvalContextStackFrameAddSoft(ctx, classname); break; default: case CONTEXT_SCOPE_NAMESPACE: EvalContextHeapAddSoft(ctx, classname, ns); break; } } } }