static void LogPromiseContext(const EvalContext *ctx, const Promise *pp) { Rval retval; char *v; if (EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_VERSION, &retval)) { v = (char *) retval.item; } else { v = "not specified"; } const char *sp = PromiseGetHandle(pp); if (sp == NULL) { sp = PromiseID(pp); } if (sp == NULL) { sp = "(unknown)"; } Log(LOG_LEVEL_INFO, "Report relates to a promise with handle '%s'", sp); if (PromiseGetBundle(pp)->source_path) { Log(LOG_LEVEL_INFO, "Made in version '%s' of '%s' near line %zu", v, PromiseGetBundle(pp)->source_path, pp->offset.line); } else { Log(LOG_LEVEL_INFO, "Promise is made internally by CFEngine"); } switch (pp->promisee.type) { case RVAL_TYPE_SCALAR: Log(LOG_LEVEL_INFO,"The promise was made to '%s'", (char *) pp->promisee.item); break; case RVAL_TYPE_LIST: { Writer *w = StringWriter(); RlistWrite(w, pp->promisee.item); Log(LOG_LEVEL_INFO, "The promise was made to (stakeholders) '%s'", StringWriterData(w)); WriterClose(w); break; } default: break; } if (pp->comment) { Log(LOG_LEVEL_INFO, "Comment '%s'", pp->comment); } }
static void LogPromiseContext(const EvalContext *ctx, const Promise *pp) { Writer *w = StringWriter(); WriterWrite(w, "Additional promise info:"); if (PromiseGetHandle(pp)) { WriterWriteF(w, " handle '%s'", PromiseGetHandle(pp)); } { Rval retval; if (EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_VERSION, &retval)) { WriterWriteF(w, " version '%s'", RvalScalarValue(retval)); } } if (PromiseGetBundle(pp)->source_path) { WriterWriteF(w, " source path '%s' at line %zu", PromiseGetBundle(pp)->source_path, pp->offset.line); } switch (pp->promisee.type) { case RVAL_TYPE_SCALAR: WriterWriteF(w, " promisee '%s'", RvalScalarValue(pp->promisee)); break; case RVAL_TYPE_LIST: WriterWrite(w, " promisee "); RlistWrite(w, pp->promisee.item); break; default: break; } if (pp->comment) { WriterWriteF(w, " comment '%s'", pp->comment); } Log(LOG_LEVEL_VERBOSE, "%s", StringWriterData(w)); WriterClose(w); }
static PromiseResult ExpandPromiseAndDo(EvalContext *ctx, const Promise *pp, Rlist *lists, Rlist *containers, PromiseActuator *ActOnPromise, void *param) { const char *handle = PromiseGetHandle(pp); EvalContextStackPushPromiseFrame(ctx, pp, true); PromiseIterator *iter_ctx = NULL; size_t i = 0; PromiseResult result = PROMISE_RESULT_NOOP; Buffer *expbuf = BufferNew(); for (iter_ctx = PromiseIteratorNew(ctx, pp, lists, containers); PromiseIteratorHasMore(iter_ctx); i++, PromiseIteratorNext(iter_ctx)) { if (handle) { // This ordering is necessary to get automated canonification BufferClear(expbuf); ExpandScalar(ctx, NULL, "this", handle, expbuf); CanonifyNameInPlace(BufferGet(expbuf)); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "handle", BufferData(expbuf), CF_DATA_TYPE_STRING, "source=promise"); } else { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "handle", PromiseID(pp), CF_DATA_TYPE_STRING, "source=promise"); } const Promise *pexp = EvalContextStackPushPromiseIterationFrame(ctx, i, iter_ctx); if (!pexp) { // excluded result = PromiseResultUpdate(result, PROMISE_RESULT_SKIPPED); continue; } PromiseResult iteration_result = ActOnPromise(ctx, pexp, param); NotifyDependantPromises(ctx, pexp, iteration_result); result = PromiseResultUpdate(result, iteration_result); if (strcmp(pp->parent_promise_type->name, "vars") == 0 || strcmp(pp->parent_promise_type->name, "meta") == 0) { VerifyVarPromise(ctx, pexp, true); } EvalContextStackPopFrame(ctx); } BufferDestroy(expbuf); PromiseIteratorDestroy(iter_ctx); EvalContextStackPopFrame(ctx); return result; }
void MarkPromiseHandleDone(EvalContext *ctx, const Promise *pp) { char name[CF_BUFSIZE]; const char *handle = PromiseGetHandle(pp); if (handle == NULL) { return; } snprintf(name, CF_BUFSIZE, "%s:%s", PromiseGetNamespace(pp), handle); StringSetAdd(ctx->dependency_handles, xstrdup(name)); }
void PromiseBanner(Promise *pp) { char handle[CF_MAXVARSIZE]; const char *sp; if ((sp = PromiseGetHandle(pp)) || (sp = PromiseID(pp))) { strncpy(handle, sp, CF_MAXVARSIZE - 1); } else { strcpy(handle, "(enterprise only)"); } CfOut(OUTPUT_LEVEL_VERBOSE, "", "\n"); CfOut(OUTPUT_LEVEL_VERBOSE, "", " .........................................................\n"); if (VERBOSE || DEBUG) { printf("%s> Promise's handle: %s\n", VPREFIX, handle); printf("%s> Promise made by: \"%s\"", VPREFIX, pp->promiser); } if (pp->promisee.item) { if (VERBOSE) { printf("\n%s> Promise made to (stakeholders): ", VPREFIX); RvalShow(stdout, pp->promisee); } } if (VERBOSE) { printf("\n"); } if (pp->ref) { CfOut(OUTPUT_LEVEL_VERBOSE, "", "\n"); CfOut(OUTPUT_LEVEL_VERBOSE, "", " Comment: %s\n", pp->ref); } CfOut(OUTPUT_LEVEL_VERBOSE, "", " .........................................................\n"); CfOut(OUTPUT_LEVEL_VERBOSE, "", "\n"); }
static void PutHandleVariable(EvalContext *ctx, const Promise *pp) { char *handle_s; const char *existing_handle = PromiseGetHandle(pp); if (existing_handle != NULL) { // This ordering is necessary to get automated canonification handle_s = ExpandScalar(ctx, NULL, "this", existing_handle, NULL); CanonifyNameInPlace(handle_s); } else { handle_s = xstrdup(PromiseID(pp)); /* default handle */ } EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "handle", handle_s, CF_DATA_TYPE_STRING, "source=promise"); free(handle_s); }
void PromiseBanner(const Promise *pp) { if (!LEGACY_OUTPUT) { if (pp->comment) { Log(LOG_LEVEL_VERBOSE, "Comment '%s'", pp->comment); } return; } char handle[CF_MAXVARSIZE]; const char *sp; if ((sp = PromiseGetHandle(pp)) || (sp = PromiseID(pp))) { strncpy(handle, sp, CF_MAXVARSIZE - 1); } else { strcpy(handle, "(enterprise only)"); } Log(LOG_LEVEL_VERBOSE, " ........................................................."); Log(LOG_LEVEL_VERBOSE, " Promise's handle: '%s'", handle); Log(LOG_LEVEL_VERBOSE, " Promise made by: '%s'", pp->promiser); if (pp->comment) { Log(LOG_LEVEL_VERBOSE, "\n"); Log(LOG_LEVEL_VERBOSE, " Comment: %s", pp->comment); } Log(LOG_LEVEL_VERBOSE, " ........................................................."); Log(LOG_LEVEL_VERBOSE, "\n"); }
void KeepLiteralAccessPromise(EvalContext *ctx, const Promise *pp, const char *type) { Auth *ap, *dp; const char *handle = PromiseGetHandle(pp); if (handle == NULL && strcmp(type, "literal") == 0) { Log(LOG_LEVEL_ERR, "Access to literal server data requires you to define a promise handle for reference"); return; } if (strcmp(type, "literal") == 0) { Log(LOG_LEVEL_VERBOSE,"Looking at literal access promise '%s', type '%s'", pp->promiser, type); ap = GetOrCreateAuth(handle, &SV.varadmit, &SV.varadmittail); dp = GetOrCreateAuth(handle, &SV.vardeny, &SV.vardenytail); RegisterLiteralServerData(ctx, handle, pp); ap->literal = true; size_t pos = acl_SortedInsert(&literals_acl, handle); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); exit(255); } AccessPromise_AddAccessConstraints(ctx, pp, &literals_acl->acls[pos], ap, dp); } else { Log(LOG_LEVEL_VERBOSE,"Looking at context/var access promise '%s', type '%s'", pp->promiser, type); ap = GetOrCreateAuth(pp->promiser, &SV.varadmit, &SV.varadmittail); dp = GetOrCreateAuth(pp->promiser, &SV.vardeny, &SV.vardenytail); if (strcmp(type, "context") == 0) { ap->classpattern = true; size_t pos = acl_SortedInsert(&classes_acl, pp->promiser); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); exit(255); } AccessPromise_AddAccessConstraints(ctx, pp, &classes_acl->acls[pos], ap, dp); } else if (strcmp(type, "variable") == 0) { ap->variable = true; size_t pos = acl_SortedInsert(&vars_acl, pp->promiser); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); exit(255); } AccessPromise_AddAccessConstraints(ctx, pp, &vars_acl->acls[pos], ap, dp); } } }
static void AmendErrorMessageWithPromiseInformation(EvalContext *ctx, Item **error_message, const Promise *pp) { Rval retval; char *v; if (ScopeControlCommonGet(ctx, COMMON_CONTROL_VERSION, &retval) != DATA_TYPE_NONE) { v = (char *) retval.item; } else { v = "not specified"; } const char *sp; char handle[CF_MAXVARSIZE]; if ((sp = PromiseGetHandle(pp)) || (sp = PromiseID(pp))) { strncpy(handle, sp, CF_MAXVARSIZE - 1); } else { strcpy(handle, "(unknown)"); } char output[CF_BUFSIZE]; if (INFORM || VERBOSE || DEBUG) { snprintf(output, CF_BUFSIZE - 1, "I: Report relates to a promise with handle \"%s\"", handle); AppendItem(error_message, output, NULL); } if (pp && PromiseGetBundle(pp)->source_path) { snprintf(output, CF_BUFSIZE - 1, "I: Made in version \'%s\' of \'%s\' near line %zu", v, PromiseGetBundle(pp)->source_path, pp->offset.line); } else { snprintf(output, CF_BUFSIZE - 1, "I: Promise is made internally by cfengine"); } AppendItem(error_message, output, NULL); if (pp != NULL) { switch (pp->promisee.type) { case RVAL_TYPE_SCALAR: snprintf(output, CF_BUFSIZE - 1, "I: The promise was made to: \'%s\'", (char *) pp->promisee.item); AppendItem(error_message, output, NULL); break; case RVAL_TYPE_LIST: { Writer *w = StringWriter(); WriterWriteF(w, "I: The promise was made to (stakeholders): "); RlistWrite(w, pp->promisee.item); AppendItem(error_message, StringWriterClose(w), NULL); break; } default: break; } if (pp->ref) { snprintf(output, CF_BUFSIZE - 1, "I: Comment: %s\n", pp->ref); AppendItem(error_message, output, NULL); } } }
void KeepLiteralAccessPromise(EvalContext *ctx, Promise *pp, char *type) { Rlist *rp; Auth *ap = NULL, *dp = NULL; const char *handle = PromiseGetHandle(pp); if ((handle == NULL) && (strcmp(type,"literal") == 0)) { Log(LOG_LEVEL_ERR, "Access to literal server data requires you to define a promise handle for reference"); return; } if (strcmp(type, "literal") == 0) { Log(LOG_LEVEL_VERBOSE,"Looking at literal access promise '%s', type '%s'", pp->promiser, type); if (!GetAuthPath(handle, SV.varadmit)) { InstallServerAuthPath(handle, &SV.varadmit, &SV.varadmittop); } if (!GetAuthPath(handle, SV.vardeny)) { InstallServerAuthPath(handle, &SV.vardeny, &SV.vardenytop); } RegisterLiteralServerData(ctx, handle, pp); ap = GetAuthPath(handle, SV.varadmit); dp = GetAuthPath(handle, SV.vardeny); ap->literal = true; } else { Log(LOG_LEVEL_VERBOSE,"Looking at context/var access promise '%s', type '%s'", pp->promiser, type); if (!GetAuthPath(pp->promiser, SV.varadmit)) { InstallServerAuthPath(pp->promiser, &SV.varadmittop, &SV.varadmittop); } if (!GetAuthPath(pp->promiser, SV.vardeny)) { InstallServerAuthPath(pp->promiser, &SV.vardeny, &SV.vardenytop); } if (strcmp(type, "context") == 0) { ap = GetAuthPath(pp->promiser, SV.varadmit); dp = GetAuthPath(pp->promiser, SV.vardeny); ap->classpattern = true; } if (strcmp(type, "variable") == 0) { ap = GetAuthPath(pp->promiser, SV.varadmit); // Allow the promiser (preferred) as well as handle as variable name dp = GetAuthPath(pp->promiser, SV.vardeny); ap->variable = true; } } for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *cp = SeqAt(pp->conlist, i); if (!IsDefinedClass(ctx, cp->classes, PromiseGetNamespace(pp))) { continue; } switch (cp->rval.type) { case RVAL_TYPE_SCALAR: if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_ENCRYPTED].lval) == 0) { ap->encrypt = true; } break; case RVAL_TYPE_LIST: for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next) { if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_ADMIT].lval) == 0) { PrependItem(&(ap->accesslist), rp->item, NULL); continue; } if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_DENY].lval) == 0) { PrependItem(&(dp->accesslist), rp->item, NULL); continue; } if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_MAPROOT].lval) == 0) { PrependItem(&(ap->maproot), rp->item, NULL); continue; } } break; default: /* Shouldn't happen */ break; } } }
static void ExpandPromiseAndDo(EvalContext *ctx, const Promise *pp, Rlist *lists, Rlist *containers, PromiseActuator *ActOnPromise, void *param) { const char *handle = PromiseGetHandle(pp); char v[CF_MAXVARSIZE]; EvalContextStackPushPromiseFrame(ctx, pp, true); PromiseIterator *iter_ctx = NULL; for (iter_ctx = PromiseIteratorNew(ctx, pp, lists, containers); PromiseIteratorHasMore(iter_ctx); PromiseIteratorNext(iter_ctx)) { EvalContextStackPushPromiseIterationFrame(ctx, iter_ctx); char number[CF_SMALLBUF]; /* Allow $(this.handle) etc variables */ if (PromiseGetBundle(pp)->source_path) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promise_filename",PromiseGetBundle(pp)->source_path, DATA_TYPE_STRING); snprintf(number, CF_SMALLBUF, "%zu", pp->offset.line); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promise_linenumber", number, DATA_TYPE_STRING); } snprintf(v, CF_MAXVARSIZE, "%d", (int) getuid()); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser_uid", v, DATA_TYPE_INT); snprintf(v, CF_MAXVARSIZE, "%d", (int) getgid()); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser_gid", v, DATA_TYPE_INT); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "bundle", PromiseGetBundle(pp)->name, DATA_TYPE_STRING); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "namespace", PromiseGetNamespace(pp), DATA_TYPE_STRING); /* Must expand $(this.promiser) here for arg dereferencing in things like edit_line and methods, but we might have to adjust again later if the value changes -- need to qualify this so we don't expand too early for some other promsies */ if (pp->has_subbundles) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser", pp->promiser, DATA_TYPE_STRING); } if (handle) { char tmp[CF_EXPANDSIZE]; // This ordering is necessary to get automated canonification ExpandScalar(ctx, NULL, "this", handle, tmp); CanonifyNameInPlace(tmp); Log(LOG_LEVEL_DEBUG, "Expanded handle to '%s'", tmp); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "handle", tmp, DATA_TYPE_STRING); } else { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "handle", PromiseID(pp), DATA_TYPE_STRING); } Promise *pexp = ExpandDeRefPromise(ctx, pp); assert(ActOnPromise); ActOnPromise(ctx, pexp, param); if (strcmp(pp->parent_promise_type->name, "vars") == 0 || strcmp(pp->parent_promise_type->name, "meta") == 0) { VerifyVarPromise(ctx, pexp, true); } PromiseDestroy(pexp); EvalContextStackPopFrame(ctx); } PromiseIteratorDestroy(iter_ctx); EvalContextStackPopFrame(ctx); }
if (!OpenDB(&dbp, dbid_static)) { return; } snprintf(id, CF_MAXVARSIZE - 1, "%s:%d", handle, a.measure.data_type); WriteDB(dbp, id, value, strlen(value) + 1); CloseDB(dbp); } } /************************************************************************************/ PromiseResult VerifyMeasurement(EvalContext *ctx, double *this, Attributes a, const Promise * pp) { const char *handle = PromiseGetHandle(pp); Item *stream = NULL; int slot = 0; double new_value; if (!handle) { Log(LOG_LEVEL_ERR, "The promised measurement has no handle to register it by."); return PROMISE_RESULT_NOOP; } else { Log(LOG_LEVEL_VERBOSE, "Considering promise \"%s\"", handle); } char *bundle = PromiseGetBundle(pp)->name;