static void VerifyPromises(EvalContext *ctx, Policy *policy, GenericAgentConfig *config) { /* Now look once through ALL the bundles themselves */ for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); EvalContextStackPushBundleFrame(ctx, bp, NULL, false); for (size_t j = 0; j < SeqLength(bp->promise_types); j++) { PromiseType *sp = SeqAt(bp->promise_types, j); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, CommonEvalPromise, NULL); } } EvalContextStackPopFrame(ctx); } PolicyResolve(ctx, policy, config); // TODO: need to move this inside PolicyCheckRunnable eventually. if (!config->bundlesequence && config->check_runnable) { // only verify policy-defined bundlesequence for cf-agent, cf-promises if ((config->agent_type == AGENT_TYPE_AGENT) || (config->agent_type == AGENT_TYPE_COMMON)) { if (!VerifyBundleSequence(ctx, policy, config)) { FatalError(ctx, "Errors in promise bundles"); } } } }
Policy *LoadPolicy(EvalContext *ctx, GenericAgentConfig *config) { StringSet *parsed_files_and_checksums = StringSetNew(); StringSet *failed_files = StringSetNew(); Policy *policy = LoadPolicyFile(ctx, config, config->input_file, parsed_files_and_checksums, failed_files); if (StringSetSize(failed_files) > 0) { Log(LOG_LEVEL_ERR, "There are syntax errors in policy files"); exit(EXIT_FAILURE); } StringSetDestroy(parsed_files_and_checksums); StringSetDestroy(failed_files); { Seq *errors = SeqNew(100, PolicyErrorDestroy); if (PolicyCheckPartial(policy, errors)) { if (!config->bundlesequence && (PolicyIsRunnable(policy) || config->check_runnable)) { Log(LOG_LEVEL_VERBOSE, "Running full policy integrity checks"); PolicyCheckRunnable(ctx, policy, errors, config->ignore_missing_bundles); } } if (SeqLength(errors) > 0) { Writer *writer = FileWriter(stderr); for (size_t i = 0; i < errors->length; i++) { PolicyErrorWrite(writer, errors->data[i]); } WriterClose(writer); exit(EXIT_FAILURE); // TODO: do not exit } SeqDestroy(errors); } if (LogGetGlobalLevel() >= LOG_LEVEL_VERBOSE) { ShowContext(ctx); } if (policy) { for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); EvalContextStackPushBundleFrame(ctx, bp, NULL, false); for (size_t j = 0; j < SeqLength(bp->promise_types); j++) { PromiseType *sp = SeqAt(bp->promise_types, j); EvalContextStackPushPromiseTypeFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, CommonEvalPromise, NULL); } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); } PolicyResolve(ctx, policy, config); // TODO: need to move this inside PolicyCheckRunnable eventually. if (!config->bundlesequence && config->check_runnable) { // only verify policy-defined bundlesequence for cf-agent, cf-promises if ((config->agent_type == AGENT_TYPE_AGENT) || (config->agent_type == AGENT_TYPE_COMMON)) { if (!VerifyBundleSequence(ctx, policy, config)) { FatalError(ctx, "Errors in promise bundles: could not verify bundlesequence"); } } } } JsonElement *validated_doc = ReadReleaseIdFileFromInputs(); if (validated_doc) { const char *release_id = JsonObjectGetAsString(validated_doc, "releaseId"); if (release_id) { policy->release_id = xstrdup(release_id); } JsonDestroy(validated_doc); } return policy; }
static void VerifyPromises(enum cfagenttype agent) { struct Bundle *bp; struct SubType *sp; struct Promise *pp; struct Body *bdp; struct Rlist *rp; struct FnCall *fp; char *scope; if (REQUIRE_COMMENTS == CF_UNDEFINED) { for (bdp = BODIES; bdp != NULL; bdp = bdp->next) /* get schedule */ { if ((strcmp(bdp->name,"control") == 0) && (strcmp(bdp->type,"common") == 0)) { REQUIRE_COMMENTS = GetRawBooleanConstraint("require_comments",bdp->conlist); break; } } } for (rp = BODYPARTS; rp != NULL; rp=rp->next) { switch (rp->type) { case CF_SCALAR: if (!IsBody(BODIES,(char *)rp->item)) { CfOut(cf_error,"","Undeclared promise body \"%s()\" was referenced in a promise\n",(char *)rp->item); ERRORCOUNT++; } break; case CF_FNCALL: fp = (struct FnCall *)rp->item; if (!IsBody(BODIES,fp->name)) { CfOut(cf_error,"","Undeclared promise body \"%s()\" was referenced in a promise\n",fp->name); ERRORCOUNT++; } break; } } /* Check for undefined subbundles */ for (rp = SUBBUNDLES; rp != NULL; rp=rp->next) { switch (rp->type) { case CF_SCALAR: if (!IGNORE_MISSING_BUNDLES && !IsCf3VarString(rp->item) && !IsBundle(BUNDLES,(char *)rp->item)) { CfOut(cf_error,"","Undeclared promise bundle \"%s()\" was referenced in a promise\n",(char *)rp->item); ERRORCOUNT++; } break; case CF_FNCALL: fp = (struct FnCall *)rp->item; if (!IGNORE_MISSING_BUNDLES && !IsCf3VarString(fp->name) && !IsBundle(BUNDLES,fp->name)) { CfOut(cf_error,"","Undeclared promise bundle \"%s()\" was referenced in a promise\n",fp->name); ERRORCOUNT++; } break; } } /* Now look once through ALL the bundles themselves */ for (bp = BUNDLES; bp != NULL; bp = bp->next) /* get schedule */ { scope = bp->name; THIS_BUNDLE = bp->name; for (sp = bp->subtypes; sp != NULL; sp = sp->next) /* get schedule */ { if (strcmp(sp->name,"classes") == 0) { /* these should not be evaluated here */ if (agent != cf_common) { continue; } } for (pp = sp->promiselist; pp != NULL; pp=pp->next) { ExpandPromise(agent,scope,pp,NULL); } } } HashVariables(NULL); HashControls(); /* Now look once through the sequences bundles themselves */ if (VerifyBundleSequence(agent) == false) { FatalError("Errors in promise bundles"); } }