Beispiel #1
0
void PromiseIteratorUpdateVariable(EvalContext *ctx, const PromiseIterator *iter)
{
    for (size_t i = 0; i < SeqLength(iter->vars); i++)
    {
        CfAssoc *iter_var = SeqAt(iter->vars, i);

        const Rlist *state = SeqAt(iter->var_states, i);

        if (!state || state->val.type == RVAL_TYPE_FNCALL)
        {
            continue;
        }

        assert(state->val.type == RVAL_TYPE_SCALAR);

        switch (iter_var->dtype)
        {
        case CF_DATA_TYPE_STRING_LIST:
            EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, iter_var->lval, RlistScalarValue(state), CF_DATA_TYPE_STRING, "source=promise");
            break;
        case CF_DATA_TYPE_INT_LIST:
            EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, iter_var->lval, RlistScalarValue(state), CF_DATA_TYPE_INT, "source=promise");
            break;
        case CF_DATA_TYPE_REAL_LIST:
            EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, iter_var->lval, RlistScalarValue(state), CF_DATA_TYPE_REAL, "source=promise");
            break;
        default:
            assert(false);
            break;
        }
    }
}
Beispiel #2
0
Datei: expand.c Projekt: tzz/core
void PolicyResolve(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config)
{
    for (size_t i = 0; i < SeqLength(policy->bundles); i++)
    {
        Bundle *bundle = SeqAt(policy->bundles, i);
        if (strcmp("common", bundle->type) == 0)
        {
            EvalContextStackPushBundleFrame(ctx, bundle, NULL, false);
            BundleResolve(ctx, bundle);
            EvalContextStackPopFrame(ctx);
        }
    }

    for (size_t i = 0; i < SeqLength(policy->bundles); i++)
    {
        Bundle *bundle = SeqAt(policy->bundles, i);
        if (strcmp("common", bundle->type) != 0)
        {
            EvalContextStackPushBundleFrame(ctx, bundle, NULL, false);
            BundleResolve(ctx, bundle);
            EvalContextStackPopFrame(ctx);
        }
    }

    for (size_t i = 0; i < SeqLength(policy->bodies); i++)
    {
        Body *bdp = SeqAt(policy->bodies, i);

        if (strcmp(bdp->name, "control") == 0)
        {
            ResolveControlBody(ctx, config, bdp);
        }
    }
}
Beispiel #3
0
static bool VariableStateIncrement(PromiseIterator *iter, size_t index)
{
    assert(index < SeqLength(iter->var_states));

    CfAssoc *var = SeqAt(iter->vars, index);

    switch (var->rval.type)
    {
    case RVAL_TYPE_LIST:
        {
            Rlist *state = SeqAt(iter->var_states, index);
            assert(state);
            // find the next valid value, return false if there is none
            state = FirstRealEntry(state->next);
            SeqSet(iter->var_states, index, state);
            return state != NULL;
        }
        break;

    default:
        ProgrammingError("Unhandled case in switch");
    }

    return false;
}
Beispiel #4
0
Datei: expand.c Projekt: tzz/core
void BundleResolve(EvalContext *ctx, const Bundle *bundle)
{
    Log(LOG_LEVEL_DEBUG, "Resolving variables in bundle '%s' '%s'", bundle->type, bundle->name);

    for (size_t j = 0; j < SeqLength(bundle->promise_types); j++)
    {
        PromiseType *sp = SeqAt(bundle->promise_types, j);

        if (strcmp(bundle->type, "common") == 0 && strcmp(sp->name, "classes") == 0)
        {
            ResolveCommonClassPromises(ctx, sp);
        }
    }

    for (size_t j = 0; j < SeqLength(bundle->promise_types); j++)
    {
        PromiseType *sp = SeqAt(bundle->promise_types, j);

        if (strcmp(sp->name, "vars") == 0)
        {
            ResolveVariablesPromises(ctx, sp);
        }
    }

}
Beispiel #5
0
// Returns true if line is filtered, IOW should not be included.
static bool LineIsFiltered(const ExecConfig *config,
                           const char *line)
{
    // Check whether the line matches mail filters
    int include_filter_len = SeqLength(config->mailfilter_include_regex);
    int exclude_filter_len = SeqLength(config->mailfilter_exclude_regex);
    // Count messages as matched in include set if there is no include set.
    bool included = (include_filter_len == 0);
    bool excluded = false;
    if (include_filter_len > 0)
    {
        for (int i = 0; i < include_filter_len; i++)
        {
            if (StringMatchFullWithPrecompiledRegex(SeqAt(config->mailfilter_include_regex, i),
                                                    line))
            {
                included = true;
            }
        }
    }
    if (exclude_filter_len > 0)
    {
        for (int i = 0; i < exclude_filter_len; i++)
        {
            if (StringMatchFullWithPrecompiledRegex(SeqAt(config->mailfilter_exclude_regex, i),
                                                    line))
            {
                excluded = true;
            }
        }
    }
    return !included || excluded;
}
Beispiel #6
0
// TODO: should be replaced by something not complected with loading
static void ShowContext(EvalContext *ctx)
{
    Seq *hard_contexts = SeqNew(1000, NULL);
    Seq *soft_contexts = SeqNew(1000, NULL);

    {
        ClassTableIterator *iter = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true);
        Class *cls = NULL;
        while ((cls = ClassTableIteratorNext(iter)))
        {
            if (cls->is_soft)
            {
                SeqAppend(soft_contexts, cls->name);
            }
            else
            {
                SeqAppend(hard_contexts, cls->name);
            }
        }

        ClassTableIteratorDestroy(iter);
    }

    SeqSort(soft_contexts, (SeqItemComparator)strcmp, NULL);
    SeqSort(hard_contexts, (SeqItemComparator)strcmp, NULL);

    Log(LOG_LEVEL_VERBOSE, "----------------------------------------------------------------");

    {
        Log(LOG_LEVEL_VERBOSE, "BEGIN Discovered hard classes:");

        for (size_t i = 0; i < SeqLength(hard_contexts); i++)
        {
            const char *context = SeqAt(hard_contexts, i);
            Log(LOG_LEVEL_VERBOSE, "C: discovered hard class %s", context);
        }

        Log(LOG_LEVEL_VERBOSE, "END Discovered hard classes");
    }

    Log(LOG_LEVEL_VERBOSE, "----------------------------------------------------------------");

    if (SeqLength(soft_contexts))
    {
        Log(LOG_LEVEL_VERBOSE, "BEGIN initial soft classes:");

        for (size_t i = 0; i < SeqLength(soft_contexts); i++)
        {
            const char *context = SeqAt(soft_contexts, i);
            Log(LOG_LEVEL_VERBOSE, "C: added soft class %s", context);
        }

        Log(LOG_LEVEL_VERBOSE, "END initial soft classes");
    }

    SeqDestroy(hard_contexts);
    SeqDestroy(soft_contexts);
}
Beispiel #7
0
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);
}
Beispiel #8
0
void PolicyResolve(EvalContext *ctx, const Policy *policy,
                   GenericAgentConfig *config)
{
    /* PRE-EVAL: common bundles: classes,vars. */
    for (size_t i = 0; i < SeqLength(policy->bundles); i++)
    {
        Bundle *bundle = SeqAt(policy->bundles, i);
        if (strcmp("common", bundle->type) == 0)
        {
            EvalContextStackPushBundleFrame(ctx, bundle, NULL, false);
            BundleResolve(ctx, bundle);            /* PRE-EVAL classes,vars */
            EvalContextStackPopFrame(ctx);
        }
    }

/*
 * HACK: yet another pre-eval pass here, WHY? TODO remove, but test fails:
 *       00_basics/03_bodies/dynamic_inputs_findfiles.cf
 */
#if 1

    /* PRE-EVAL: non-common bundles: only vars. */
    for (size_t i = 0; i < SeqLength(policy->bundles); i++)
    {
        Bundle *bundle = SeqAt(policy->bundles, i);
        if (strcmp("common", bundle->type) != 0)
        {
            EvalContextStackPushBundleFrame(ctx, bundle, NULL, false);
            BundleResolve(ctx, bundle);                    /* PRE-EVAL vars */
            EvalContextStackPopFrame(ctx);
        }
    }

#endif

    for (size_t i = 0; i < SeqLength(policy->bodies); i++)
    {
        Body *bdp = SeqAt(policy->bodies, i);

        if (strcmp(bdp->name, "control") == 0)
        {
            ResolveControlBody(ctx, config, bdp);
        }
        /* Collect all package managers data from policy as we don't know yet
         * which ones we will use. */
        else if (strcmp(bdp->type, "package_module") == 0)
        {
            ResolvePackageManagerBody(ctx, bdp);
        }
    }
}
Beispiel #9
0
static void RemoveRemotelyInjectedVars(const EvalContext *ctx, const Bundle *bundle)
{
    const Seq *remote_var_promises = EvalContextGetRemoteVarPromises(ctx, bundle->name);
    if ((remote_var_promises == NULL) || SeqLength(remote_var_promises) == 0)
    {
        /* nothing to do here */
        return;
    }

    size_t promises_length = SeqLength(remote_var_promises);
    Seq *remove_vars = SeqNew(promises_length, NULL);

    /* remove variables that have been attempted to be inserted into this
     * bundle */
    /* TODO: this is expensive and should be removed! */
    for (size_t i = 0; i < promises_length; i++)
    {
        const Promise *pp = (Promise *) SeqAt(remote_var_promises, i);

        VariableTableIterator *iter = EvalContextVariableTableIteratorNew(ctx, NULL, bundle->name, NULL);
        const Variable *var = VariableTableIteratorNext(iter);
        while (var != NULL)
        {
            /* variables are stored together with their original promises (org_pp) */
            if (var->promise && var->promise->org_pp == pp)
            {
                Log(LOG_LEVEL_ERR, "Ignoring remotely-injected variable '%s'",
                    var->ref->lval);
                /* avoid modifications of the variable table being iterated
                 * over and avoid trying to remove the same variable twice */
                SeqAppendOnce(remove_vars, (void *) var, PointerCmp);
            }
            var = VariableTableIteratorNext(iter);
        }
        VariableTableIteratorDestroy(iter);
    }

    /* iteration over the variable table done, time to remove the variables */
    size_t remove_vars_length = SeqLength(remove_vars);
    for (size_t i = 0; i < remove_vars_length; i++)
    {
        Variable *var = (Variable *) SeqAt(remove_vars, i);
        if (var->ref != NULL)
        {
            EvalContextVariableRemove(ctx, var->ref);
        }
    }
    SeqDestroy(remove_vars);
}
Beispiel #10
0
static void ShowPackages(FILE *out, Seq *package_entries)
{
    for (size_t i = 0; i < SeqLength(package_entries); i++)
    {
        fprintf(out, "%s\n", SerializePackage(SeqAt(package_entries, i)));
    }
}
Beispiel #11
0
void DeleteMountInfo(Seq *list)
{
    for (size_t i = 0; i < SeqLength(list); i++)
    {
        Mount *entry = SeqAt(list, i);

        if (entry->host)
        {
            free(entry->host);
        }

        if (entry->source)
        {
            free(entry->source);
        }

        if (entry->mounton)
        {
            free(entry->mounton);
        }

        if (entry->options)
        {
            free(entry->options);
        }
    }

    SeqClear(list);
}
Beispiel #12
0
static bool MethodsParseTreeCheck(const Promise *pp, Seq *errors)
{
    bool success = true;

    for (size_t i = 0; i < SeqLength(pp->conlist); i++)
    {
        const Constraint *cp = SeqAt(pp->conlist, i);

        // ensure: if call and callee are resolved, then they have matching arity
        if (StringSafeEqual(cp->lval, "usebundle"))
        {
            if (cp->rval.type == RVAL_TYPE_FNCALL)
            {
                const FnCall *call = (const FnCall *)cp->rval.item;
                const Bundle *callee = PolicyGetBundle(PolicyFromPromise(pp), NULL, "agent", call->name);
                if (!callee)
                {
                    callee = PolicyGetBundle(PolicyFromPromise(pp), NULL, "common", call->name);
                }

                if (callee)
                {
                    if (RlistLen(call->args) != RlistLen(callee->args))
                    {
                        SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, cp,
                                                         POLICY_ERROR_METHODS_BUNDLE_ARITY,
                                                         call->name, RlistLen(callee->args), RlistLen(call->args)));
                        success = false;
                    }
                }
            }
        }
    }
    return success;
}
Beispiel #13
0
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);
        bool server_bundle = strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_SERVER]) == 0;
        bool common_bundle = strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_COMMON]) == 0;

        if (server_bundle || common_bundle)
        {
            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;
            }
        }

        if (server_bundle)
        {
            EvaluateBundle(ctx, bp, SERVER_TYPESEQUENCE);
        }

        else if (common_bundle)
        {
            EvaluateBundle(ctx, bp, COMMON_TYPESEQUENCE);
        }
    }
}
Beispiel #14
0
static bool RenderVariable(Writer *out,
                           const char *content, size_t content_len,
                           bool escaped,
                           Seq *hash_stack)
{
    JsonElement *var = NULL;
    if (strncmp(content, ".", content_len) == 0)
    {
        var = SeqAt(hash_stack, SeqLength(hash_stack) - 1);
    }
    else
    {
        var = LookupVariable(hash_stack, content, content_len);
    }

    if (!var)
    {
        return true;
    }

    switch (JsonGetElementType(var))
    {
    case JSON_ELEMENT_TYPE_PRIMITIVE:
        return RenderVariablePrimitive(out, var, escaped);

    case JSON_ELEMENT_TYPE_CONTAINER:
        assert(false);
        return false;
    }

    assert(false);
    return false;
}
Beispiel #15
0
static void ShowVariablesFormatted(EvalContext *ctx)
{
    VariableTableIterator *iter = EvalContextVariableTableIteratorNew(ctx, NULL, NULL, NULL);
    Variable *v = NULL;

    Seq *seq = SeqNew(2000, free);

    while ((v = VariableTableIteratorNext(iter)))
    {
        char *varname = VarRefToString(v->ref, true);

        Writer *w = StringWriter();

        switch (DataTypeToRvalType(v->type))
        {
        case RVAL_TYPE_CONTAINER:
            JsonWriteCompact(w, RvalContainerValue(v->rval));
            break;

        default:
            RvalWrite(w, v->rval);
        }

        const char *var_value;
        if (StringIsPrintable(StringWriterData(w)))
        {
            var_value = StringWriterData(w);
        }
        else
        {
            var_value = "<non-printable>";
        }


        StringSet *tagset = EvalContextVariableTags(ctx, v->ref);
        Buffer *tagbuf = StringSetToBuffer(tagset, ',');

        char *line;
        xasprintf(&line, "%-40s %-60s %-40s", varname, var_value, BufferData(tagbuf));

        SeqAppend(seq, line);

        BufferDestroy(tagbuf);
        WriterClose(w);
        free(varname);
    }

    SeqSort(seq, (SeqItemComparator)strcmp, NULL);

    printf("%-40s %-60s %-40s\n", "Variable name", "Variable value", "Meta tags");

    for (size_t i = 0; i < SeqLength(seq); i++)
    {
        const char *variable = SeqAt(seq, i);
        printf("%s\n", variable);
    }

    SeqDestroy(seq);
    VariableTableIteratorDestroy(iter);
}
Beispiel #16
0
static Body *IsBody(Seq *bodies, const char *ns, const char *key)
{
    char fqname[CF_BUFSIZE];

    for (size_t i = 0; i < SeqLength(bodies); i++)
    {
        Body *bp = SeqAt(bodies, i);

        // bp->namespace is where the body belongs, namespace is where we are now
        if (strchr(key, CF_NS) || strcmp(ns,"default") == 0)
        {
            if (strncmp(key,"default:",strlen("default:")) == 0) // CF_NS == ':'
            {
                strcpy(fqname,strchr(key,CF_NS)+1);
            }
            else
            {
                strcpy(fqname,key);
            }
        }
        else
        {
            snprintf(fqname,CF_BUFSIZE-1, "%s%c%s", ns, CF_NS, key);
        }

        if (strcmp(bp->name, fqname) == 0)
        {
            return bp;
        }
    }

    return NULL;
}
Beispiel #17
0
char *EvalContextStackPath(const EvalContext *ctx)
{
    Writer *path = StringWriter();

    for (size_t i = 0; i < SeqLength(ctx->stack); i++)
    {
        StackFrame *frame = SeqAt(ctx->stack, i);
        switch (frame->type)
        {
        case STACK_FRAME_TYPE_BODY:
            WriterWriteF(path, "/%s", frame->data.body.owner->name);
            break;

        case STACK_FRAME_TYPE_BUNDLE:
            WriterWriteF(path, "/%s", frame->data.bundle.owner->name);
            break;

        case STACK_FRAME_TYPE_PROMISE_ITERATION:
            WriterWriteF(path, "/%s", frame->data.promise.owner->parent_promise_type->name);
            WriterWriteF(path, "/'%s'", frame->data.promise.owner->promiser);
            break;

        case STACK_FRAME_TYPE_PROMISE:
            break;
        }
    }

    return StringWriterClose(path);
}
Beispiel #18
0
Datei: expand.c Projekt: tzz/core
static void ResolveCommonClassPromises(EvalContext *ctx, PromiseType *pt)
{
    assert(strcmp("classes", pt->name) == 0);
    assert(strcmp(pt->parent_bundle->type, "common") == 0);

    for (size_t i = 0; i < SeqLength(pt->promises); i++)
    {
        Promise *pp = SeqAt(pt->promises, i);

        char *sp = NULL;
        if (VarClassExcluded(ctx, pp, &sp))
        {
            if (LEGACY_OUTPUT)
            {
                Log(LOG_LEVEL_VERBOSE, "\n");
                Log(LOG_LEVEL_VERBOSE, ". . . . . . . . . . . . . . . . . . . . . . . . . . . . ");
                Log(LOG_LEVEL_VERBOSE, "Skipping whole next promise (%s), as var-context %s is not relevant", pp->promiser, sp);
                Log(LOG_LEVEL_VERBOSE, ". . . . . . . . . . . . . . . . . . . . . . . . . . . . ");
            }
            else
            {
                Log(LOG_LEVEL_VERBOSE, "Skipping next promise '%s', as var-context '%s' is not relevant", pp->promiser, sp);
            }
            continue;
        }

        ExpandPromise(ctx, pp, VerifyClassPromise, NULL);
    }
}
Beispiel #19
0
void SeqAppendSeq(Seq *seq, const Seq *items)
{
    for (size_t i = 0; i < SeqLength(items); i++)
    {
        SeqAppend(seq, SeqAt(items, i));
    }
}
Beispiel #20
0
Datei: expand.c Projekt: tzz/core
PromiseResult ExpandPromise(EvalContext *ctx, const Promise *pp, PromiseActuator *ActOnPromise, void *param)
{
    Rlist *lists = NULL;
    Rlist *scalars = NULL;
    Rlist *containers = NULL;

    Promise *pcopy = DeRefCopyPromise(ctx, pp);

    MapIteratorsFromRval(ctx, PromiseGetBundle(pp), (Rval) { pcopy->promiser, RVAL_TYPE_SCALAR }, &scalars, &lists, &containers);

    if (pcopy->promisee.item != NULL)
    {
        MapIteratorsFromRval(ctx, PromiseGetBundle(pp), pp->promisee, &scalars, &lists, &containers);
    }

    for (size_t i = 0; i < SeqLength(pcopy->conlist); i++)
    {
        Constraint *cp = SeqAt(pcopy->conlist, i);
        MapIteratorsFromRval(ctx, PromiseGetBundle(pp), cp->rval, &scalars, &lists, &containers);
    }

    CopyLocalizedReferencesToBundleScope(ctx, PromiseGetBundle(pp), lists);
    CopyLocalizedReferencesToBundleScope(ctx, PromiseGetBundle(pp), scalars);
    CopyLocalizedReferencesToBundleScope(ctx, PromiseGetBundle(pp), containers);

    PromiseResult result = ExpandPromiseAndDo(ctx, pcopy, lists, containers, ActOnPromise, param);

    PromiseDestroy(pcopy);

    RlistDestroy(lists);
    RlistDestroy(scalars);
    RlistDestroy(containers);

    return result;
}
Beispiel #21
0
static void ShowContextsFormatted(EvalContext *ctx)
{
    ClassTableIterator *iter = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true);
    Class *cls = NULL;

    Seq *seq = SeqNew(1000, free);

    while ((cls = ClassTableIteratorNext(iter)))
    {
        char *class_name = ClassRefToString(cls->ns, cls->name);
        StringSet *tagset = EvalContextClassTags(ctx, cls->ns, cls->name);
        Buffer *tagbuf = StringSetToBuffer(tagset, ',');

        char *line;
        xasprintf(&line, "%-60s %-40s", class_name, BufferData(tagbuf));
        SeqAppend(seq, line);

        BufferDestroy(tagbuf);
        free(class_name);
    }

    SeqSort(seq, (SeqItemComparator)strcmp, NULL);

    printf("%-60s %-40s\n", "Class name", "Meta tags");

    for (size_t i = 0; i < SeqLength(seq); i++)
    {
        const char *context = SeqAt(seq, i);
        printf("%s\n", context);
    }

    SeqDestroy(seq);

    ClassTableIteratorDestroy(iter);
}
Beispiel #22
0
bool CFTestD_GetServerQuery(
    ServerConnectionState *conn, char *recvbuffer, CFTestD_Config *config)
{
    char query[CF_BUFSIZE];
    Seq *report          = config->report;
    const int report_len = config->report_len;
    ConnectionInfo *const conn_info = conn->conn_info;

    query[0] = '\0';
    sscanf(recvbuffer, "QUERY %255[^\n]", query);

    if (strlen(query) == 0)
    {
        return false;
    }

    if (report_len == 0)
    {
        Log(LOG_LEVEL_INFO,
            "No report file argument so returning canned data from enterprise plugin server\n");
        return CFTestD_ReturnQueryData(conn, query);
    }

    Log(LOG_LEVEL_INFO,
        "Report file argument specified. Returning report of length %d",
        report_len);

    const size_t n_report_lines = SeqLength(report);

    assert(n_report_lines > 1);
    char *ts = SeqAt(report, 0);
    char *header = StringFormat("CFR: 0 %s %d\n", ts, report_len);
    SendTransaction(conn_info, header, SafeStringLength(header), CF_MORE);
    free(header);

    for (size_t i = 1; i < n_report_lines; i++)
    {
        const char *report_line = SeqAt(report, i);
        SendTransaction(conn_info, report_line, SafeStringLength(report_line), CF_MORE);
    }

    const char end_reply[] = "QUERY complete";
    SendTransaction(conn_info, end_reply, SafeStringLength(end_reply), CF_DONE);

    return true;
}
Beispiel #23
0
static StackFrame *LastStackFrame(const EvalContext *ctx, size_t offset)
{
    if (SeqLength(ctx->stack) <= offset)
    {
        return NULL;
    }
    return SeqAt(ctx->stack, SeqLength(ctx->stack) - 1 - offset);
}
Beispiel #24
0
static JsonElement *LookupVariable(Seq *hash_stack, const char *name, size_t name_len)
{
    assert(SeqLength(hash_stack) > 0);

    size_t num_comps = StringCountTokens(name, name_len, ".");

    JsonElement *base_var = NULL;
    {
        StringRef base_comp = StringGetToken(name, name_len, 0, ".");
        char *base_comp_str = xstrndup(base_comp.data, base_comp.len);

        for (ssize_t i = SeqLength(hash_stack) - 1; i >= 0; i--)
        {
            JsonElement *hash = SeqAt(hash_stack, i);
            if (!hash)
            {
                continue;
            }

            if (JsonGetElementType(hash) == JSON_ELEMENT_TYPE_CONTAINER && JsonGetContainerType(hash) == JSON_CONTAINER_TYPE_OBJECT)
            {
                JsonElement *var = JsonObjectGet(hash, base_comp_str);
                if (var)
                {
                    base_var = var;
                    break;
                }
            }
        }
        free(base_comp_str);
    }

    if (!base_var)
    {
        return NULL;
    }

    for (size_t i = 1; i < num_comps; i++)
    {
        if (JsonGetElementType(base_var) != JSON_ELEMENT_TYPE_CONTAINER || JsonGetContainerType(base_var) != JSON_CONTAINER_TYPE_OBJECT)
        {
            return NULL;
        }

        StringRef comp = StringGetToken(name, name_len, i, ".");
        char *comp_str = xstrndup(comp.data, comp.len);
        base_var = JsonObjectGet(base_var, comp_str);
        free(comp_str);

        if (!base_var)
        {
            return NULL;
        }
    }

    assert(base_var);
    return base_var;
}
Beispiel #25
0
void BundleResolvePromiseType(EvalContext *ctx, const Bundle *bundle, const char *type, PromiseActuator *actuator)
{
    for (size_t j = 0; j < SeqLength(bundle->promise_types); j++)
    {
        PromiseType *pt = SeqAt(bundle->promise_types, j);

        if (strcmp(pt->name, type) == 0)
        {
            EvalContextStackPushPromiseTypeFrame(ctx, pt);
            for (size_t i = 0; i < SeqLength(pt->promises); i++)
            {
                Promise *pp = SeqAt(pt->promises, i);
                ExpandPromise(ctx, pp, actuator, NULL);
            }
            EvalContextStackPopFrame(ctx);
        }
    }
}
Beispiel #26
0
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;
            }

            BannerBundle(bp, NULL);

            EvalContextStackPushBundleFrame(ctx, bp, NULL, false);
            for (size_t j = 0; j < SeqLength(bp->promise_types); j++)
            {
                PromiseType *sp = SeqAt(bp->promise_types, j);

                if ((strcmp(sp->name, "access") != 0) && (strcmp(sp->name, "roles") != 0))
                {
                    continue;
                }

                BannerPromiseType(bp->name, sp->name, 0);

                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);
        }
    }
}
Beispiel #27
0
static void KeepPromiseBundles(EvalContext *ctx, Policy *policy, const ReportContext *report_context)
{
/* Dial up the generic promise expansion with a callback */

    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)
            {
                CfOut(OUTPUT_LEVEL_ERROR, "", "Cannot implicitly evaluate bundle %s %s, as this bundle takes arguments.", bp->type, bp->name);
                continue;
            }

            BannerBundle(bp, NULL);

            for (size_t j = 0; j < SeqLength(bp->promise_types); j++)
            {
                PromiseType *sp = SeqAt(bp->promise_types, j);

                if ((strcmp(sp->name, "access") != 0) && (strcmp(sp->name, "roles") != 0))
                {
                    continue;
                }

                BannerPromiseType(bp->name, sp->name, 0);

                EvalContextStackPushBundleFrame(ctx, bp, false);
                ScopeAugment(ctx, bp, NULL);

                for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++)
                {
                    Promise *pp = SeqAt(sp->promises, ppi);
                    ExpandPromise(ctx, pp, KeepServerPromise, report_context);
                }

                EvalContextStackPopFrame(ctx);
            }
        }
    }
}
Beispiel #28
0
Promise *ExpandDeRefPromise(EvalContext *ctx, const char *scopeid, const Promise *pp)
{
    Promise *pcopy;
    Rval returnval, final;

    CfDebug("ExpandDerefPromise()\n");

    pcopy = xcalloc(1, sizeof(Promise));

    returnval = ExpandPrivateRval(ctx, "this", (Rval) {pp->promiser, RVAL_TYPE_SCALAR });
    pcopy->promiser = (char *) returnval.item;

    if (pp->promisee.item)
    {
        pcopy->promisee = EvaluateFinalRval(ctx, scopeid, pp->promisee, true, pp);
    }
    else
    {
        pcopy->promisee = (Rval) {NULL, RVAL_TYPE_NOPROMISEE };
    }

    if (pp->classes)
    {
        pcopy->classes = xstrdup(pp->classes);
    }
    else
    {
        pcopy->classes = xstrdup("any");
    }

    if (pcopy->promiser == NULL)
    {
        ProgrammingError("ExpandPromise returned NULL");
    }

    pcopy->parent_promise_type = pp->parent_promise_type;
    pcopy->offset.line = pp->offset.line;
    pcopy->comment = pp->comment ? xstrdup(pp->comment) : NULL;
    pcopy->conlist = SeqNew(10, ConstraintDestroy);
    pcopy->org_pp = pp->org_pp;

/* No further type checking should be necessary here, already done by CheckConstraintTypeMatch */

    for (size_t i = 0; i < SeqLength(pp->conlist); i++)
    {
        Constraint *cp = SeqAt(pp->conlist, i);

        Rval returnval;

        if (ExpectedDataType(cp->lval) == DATA_TYPE_BUNDLE)
        {
            final = ExpandBundleReference(ctx, scopeid, cp->rval);
        }
        else
        {
Beispiel #29
0
/**
 * The "roles" access promise is for remote class activation by means of
 * cf-runagent -D:
 *
 *     pp->promiser is a regex to match classes.
 *     pp->conlist  is an slist of usernames.
 */
static void KeepServerRolePromise(EvalContext *ctx, const Promise *pp)
{
    size_t pos = acl_SortedInsert(&roles_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);
    }

    size_t i = SeqLength(pp->conlist);
    while (i > 0)
    {
        i--;
        Constraint *cp = SeqAt(pp->conlist, i);
        char const * const authorizer =
            CF_REMROLE_BODIES[REMOTE_ROLE_AUTHORIZE].lval;

        if (strcmp(cp->lval, authorizer) == 0)
        {
            if (cp->rval.type != RVAL_TYPE_LIST)
            {
                Log(LOG_LEVEL_ERR,
                    "Right-hand side of authorize promise for '%s' should be a list",
                    pp->promiser);
            }
            else if (IsDefinedClass(ctx, cp->classes))
            {
                for (const Rlist *rp = cp->rval.item; rp != NULL; rp = rp->next)
                {
                    /* The "roles" access promise currently only supports
                     * listing usernames to admit access to, nothing more. */
                    struct resource_acl *racl = &roles_acl->acls[pos];
                    size_t zret = StrList_Append(&racl->admit.usernames,
                                                 RlistScalarValue(rp));
                    if (zret == (size_t) -1)
                    {
                        /* Should never happen, besides when allocation fails. */
                        Log(LOG_LEVEL_CRIT, "StrList_Append: %s", GetErrorStr());
                        exit(255);
                    }
                }
            }
        }
        else if (strcmp(cp->lval, "comment") != 0 &&
                 strcmp(cp->lval, "handle") != 0 &&
                 /* Are there other known list constraints ? if not, skip this: */
                 cp->rval.type != RVAL_TYPE_LIST)
        {
            Log(LOG_LEVEL_WARNING,
                "Unrecognised promise '%s' for %s",
                cp->lval, pp->promiser);
        }
    }
}
Beispiel #30
0
static void SavePackages(const char *database_filename, Seq *package_entries)
{
    FILE *packages_file = fopen(database_filename, "w");

    for (size_t i = 0; i < SeqLength(package_entries); i++)
    {
        fprintf(packages_file, "%s\n", SerializePackage(SeqAt(package_entries, i)));
    }

    fclose(packages_file);
}