static void EvaluateBundle(EvalContext *ctx, const Bundle *bp, const char * const *seq) { EvalContextStackPushBundleFrame(ctx, bp, NULL, false); for (int type = 0; seq[type] != NULL; type++) { const PromiseType *sp = BundleGetPromiseType((Bundle *)bp, seq[type]); /* Some promise types might not be there. */ if (!sp || SeqLength(sp->promises) == 0) { Log(LOG_LEVEL_DEBUG, "No promise type %s in bundle %s", seq[type], bp->name); continue; } EvalContextStackPushPromiseTypeFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepServerPromise, NULL); } EvalContextStackPopFrame(ctx); } /* Check if we are having some other promise types which we * should evaluate. THIS IS ONLY FOR BACKWARD COMPATIBILITY! */ for (size_t j = 0; j < SeqLength(bp->promise_types); j++) { PromiseType *sp = SeqAt(bp->promise_types, j); /* Skipping evaluation of promise as this was evaluated in * loop above. */ if (!IsPromiseTypeNotInTypeSequence(sp->name, seq)) { Log(LOG_LEVEL_DEBUG, "Skipping subsequent evaluation of " "promise type %s in bundle %s", sp->name, bp->name); continue; } Log(LOG_LEVEL_WARNING, "Trying to evaluate unsupported/obsolete " "promise type %s in %s bundle %s", sp->name, bp->type, bp->name); EvalContextStackPushPromiseTypeFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepServerPromise, NULL); } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); }
static void KeepPromiseBundles(EvalContext *ctx, const Policy *policy) { /* Dial up the generic promise expansion with a callback */ CleanReportBookFilterSet(); for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); if ((strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_SERVER]) == 0) || (strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_COMMON]) == 0)) { if (RlistLen(bp->args) > 0) { Log(LOG_LEVEL_WARNING, "Cannot implicitly evaluate bundle '%s %s', as this bundle takes arguments.", bp->type, bp->name); continue; } EvalContextStackPushBundleFrame(ctx, bp, NULL, false); for (int type = 0; SERVER_TYPESEQUENCE[type] != NULL; type++) { const PromiseType *sp = BundleGetPromiseType((Bundle *)bp, SERVER_TYPESEQUENCE[type]); /* Some promise types might not be there. */ if (!sp || SeqLength(sp->promises) == 0) { Log(LOG_LEVEL_DEBUG, "No promise type %s in bundle %s", SERVER_TYPESEQUENCE[type], bp->name); continue; } EvalContextStackPushPromiseTypeFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepServerPromise, NULL); } EvalContextStackPopFrame(ctx); } /* Check if we are having some other promise types which we * should evaluate. THIS IS ONLY FOR BACKWARD COMPATIBILITY! */ for (size_t j = 0; j < SeqLength(bp->promise_types); j++) { PromiseType *sp = SeqAt(bp->promise_types, j); /* Skipping evaluation of promise as this was evaluated in * loop above. */ if (!IsPromiseTypeNotInServerTypeSequence(sp->name)) { Log(LOG_LEVEL_DEBUG, "Skipping subsequent evaluation of " "promise type %s in bundle %s", sp->name, bp->name); continue; } Log(LOG_LEVEL_WARNING, "Trying to evaluate unsupported/obsolete " "promise type %s in bundle %s", sp->name, bp->name); EvalContextStackPushPromiseTypeFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepServerPromise, NULL); } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); } } }
static void test_policy_json_to_from(void) { EvalContext *ctx = EvalContextNew(); Policy *policy = NULL; { Policy *original = LoadPolicy("benchmark.cf"); JsonElement *json = PolicyToJson(original); PolicyDestroy(original); policy = PolicyFromJson(json); JsonDestroy(json); } assert_true(policy); assert_int_equal(1, SeqLength(policy->bundles)); assert_int_equal(2, SeqLength(policy->bodies)); { Bundle *main_bundle = PolicyGetBundle(policy, NULL, "agent", "main"); assert_true(main_bundle); { { PromiseType *files = BundleGetPromiseType(main_bundle, "files"); assert_true(files); assert_int_equal(1, SeqLength(files->promises)); for (size_t i = 0; i < SeqLength(files->promises); i++) { Promise *promise = SeqAt(files->promises, i); if (strcmp("/tmp/stuff", promise->promiser) == 0) { assert_string_equal("any", promise->classes); assert_int_equal(2, SeqLength(promise->conlist)); { Constraint *create = PromiseGetConstraint(ctx, promise, "create"); assert_true(create); assert_string_equal("create", create->lval); assert_string_equal("true", RvalScalarValue(create->rval)); } { Constraint *create = PromiseGetConstraint(ctx, promise, "perms"); assert_true(create); assert_string_equal("perms", create->lval); assert_string_equal("myperms", RvalScalarValue(create->rval)); } } else { fprintf(stderr, "Found unknown promise"); fail(); } } } { const char* reportOutput[2] = { "Hello, CFEngine", "Hello, world" }; const char* reportClass[2] = { "cfengine", "any" }; PromiseType *reports = BundleGetPromiseType(main_bundle, "reports"); assert_true(reports); assert_int_equal(2, SeqLength(reports->promises)); for (size_t i = 0; i < SeqLength(reports->promises); i++) { Promise *promise = SeqAt(reports->promises, i); if (strcmp(reportOutput[i], promise->promiser) == 0) { assert_string_equal(reportClass[i], promise->classes); assert_int_equal(1, SeqLength(promise->conlist)); { Constraint *friend_pattern = SeqAt(promise->conlist, 0); assert_true(friend_pattern); assert_string_equal("friend_pattern", friend_pattern->lval); assert_int_equal(RVAL_TYPE_FNCALL, friend_pattern->rval.type); FnCall *fn = RvalFnCallValue(friend_pattern->rval); assert_string_equal("hash", fn->name); assert_int_equal(2, RlistLen(fn->args)); } } else { fprintf(stderr, "Found unknown promise"); fail(); } } } } } { Body *myperms = PolicyGetBody(policy, NULL, "perms", "myperms"); assert_true(myperms); { Seq *mode_cps = BodyGetConstraint(myperms, "mode"); assert_int_equal(1, SeqLength(mode_cps)); Constraint *mode = SeqAt(mode_cps, 0); assert_string_equal("mode", mode->lval); assert_string_equal("555", RvalScalarValue(mode->rval)); } } PolicyDestroy(policy); EvalContextDestroy(ctx); }