예제 #1
0
static void execd_config_full_cb(const EvalContext *ctx, const Policy *policy)
{
    ExecdConfig *config = ExecdConfigNew(ctx, policy);

    assert_int_equal(2, StringSetSize(config->schedule));
    assert_int_equal(true, StringSetContains(config->schedule, "Min00_05"));
    assert_int_equal(true, StringSetContains(config->schedule, "Min05_10"));
    /* Splay calculation uses FQNAME and getuid(), so can't predict
       actual splay value */
    assert_int_equal(true, config->splay_time>=0 && config->splay_time<60);
    assert_string_equal("LOG_LOCAL6", config->log_facility);

    ExecdConfigDestroy(config);
}
예제 #2
0
int MissingDependencies(EvalContext *ctx, const Promise *pp)
{
    if (pp == NULL)
    {
        return false;
    }

    char name[CF_BUFSIZE], *d;
    Rlist *rp, *deps = PromiseGetConstraintAsList(ctx, "depends_on", pp);
    
    for (rp = deps; rp != NULL; rp = rp->next)
    {
        if (strchr(rp->item, ':'))
        {
            d = (char *)rp->item;
        }
        else
        {
            snprintf(name, CF_BUFSIZE, "%s:%s", PromiseGetNamespace(pp), (char *)rp->item);
            d = name;
        }

        if (!StringSetContains(ctx->dependency_handles, d))
        {
            CfOut(OUTPUT_LEVEL_VERBOSE, "", "\n");
            CfOut(OUTPUT_LEVEL_VERBOSE, "", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . \n");
            CfOut(OUTPUT_LEVEL_VERBOSE, "", "Skipping whole next promise (%s), as promise dependency %s has not yet been kept\n", pp->promiser, d);
            CfOut(OUTPUT_LEVEL_VERBOSE, "", ". . . . . . . . . . . . . . . . . . . . . . . . . . . . \n");

            return true;
        }
    }

    return false;
}
예제 #3
0
파일: class.c 프로젝트: maciejmrowiec/core
/**
 * @param #tags is a comma separated string of words.
 *              Both "" or NULL are equivalent.
 */
static void ClassInit(Class *cls,
                      const char *ns, const char *name,
                      bool is_soft, ContextScope scope, const char *tags)
{
    if (ns == NULL || strcmp(ns, "default") == 0)
    {
        cls->ns = NULL;
    }
    else
    {
        cls->ns = xstrdup(ns);
    }

    cls->name = xstrdup(name);
    CanonifyNameInPlace(cls->name);

    cls->is_soft = is_soft;
    cls->scope = scope;

    cls->tags = StringSetFromString(tags, ',');
    if (!is_soft && !StringSetContains(cls->tags, "hardclass"))
    {
        StringSetAdd(cls->tags, xstrdup("hardclass"));
    }
}
예제 #4
0
static bool EvalContextStackFrameContainsNegated(const EvalContext *ctx, const char *context)
{
    if (SeqLength(ctx->stack) == 0)
    {
        return false;
    }

    return StringSetContains(EvalContextStackFrame(ctx)->contexts_negated, context);
}
예제 #5
0
bool StackFrameContainsNegatedRecursive(const EvalContext *ctx, const char *context, size_t stack_index)
{
    StackFrame *frame = SeqAt(ctx->stack, stack_index);
    if (frame->type == STACK_FRAME_TYPE_BUNDLE && StringSetContains(frame->data.bundle.contexts_negated, context))
    {
        return true;
    }
    else if (stack_index > 0 && frame->inherits_previous)
    {
        return StackFrameContainsNegatedRecursive(ctx, context, stack_index - 1);
    }
    else
    {
        return false;
    }
}
예제 #6
0
bool StackFrameContainsSoftRecursive(const EvalContext *ctx, const char *context, size_t stack_index)
{
    StackFrame *frame = SeqAt(ctx->stack, stack_index);
    if (StringSetContains(frame->contexts, context))
    {
        return true;
    }
    else if (stack_index > 0 && frame->inherits_previous)
    {
        return StackFrameContainsSoftRecursive(ctx, context, stack_index - 1);
    }
    else
    {
        return false;
    }
}
예제 #7
0
static ExpressionValue EvalTokenFromList(ARG_UNUSED const EvalContext *ctx,
                                         const char *token, void *param)
{
    StringSet *set = param;
    return StringSetContains(set, token);
}
예제 #8
0
bool EvalContextHeapContainsNegated(const EvalContext *ctx, const char *context)
{
    return StringSetContains(ctx->heap_negated, context);
}
예제 #9
0
bool EvalContextHeapContainsHard(const EvalContext *ctx, const char *context)
{
    return StringSetContains(ctx->heap_hard, context);
}
예제 #10
0
bool EvalContextHeapContainsSoft(const EvalContext *ctx, const char *context)
{
    return StringSetContains(ctx->heap_soft, context);
}
예제 #11
0
파일: env_context.c 프로젝트: jeffali/core
static ExpressionValue EvalTokenFromList(const char *token, void *param)
{
    StringSet *set = param;
    return StringSetContains(set, token);
}
예제 #12
0
파일: loading.c 프로젝트: lra/core
static Policy *LoadPolicyFile(EvalContext *ctx, GenericAgentConfig *config, const char *policy_file, StringSet *parsed_files_and_checksums, StringSet *failed_files)
{
    Policy *policy = NULL;
    unsigned char digest[EVP_MAX_MD_SIZE + 1] = { 0 };
    char hashbuffer[EVP_MAX_MD_SIZE * 4] = { 0 };
    char hashprintbuffer[CF_BUFSIZE] = { 0 };

    HashFile(policy_file, digest, CF_DEFAULT_DIGEST);
    snprintf(hashprintbuffer, CF_BUFSIZE - 1, "{checksum}%s",
             HashPrintSafe(CF_DEFAULT_DIGEST, true, digest, hashbuffer));

    Log(LOG_LEVEL_DEBUG, "Hashed policy file %s to %s", policy_file, hashprintbuffer);

    if (StringSetContains(parsed_files_and_checksums, policy_file))
    {
        Log(LOG_LEVEL_VERBOSE, "Skipping loading of duplicate policy file %s", policy_file);
        return NULL;
    }
    else if (StringSetContains(parsed_files_and_checksums, hashprintbuffer))
    {
        Log(LOG_LEVEL_VERBOSE, "Skipping loading of duplicate (detected by hash) policy file %s", policy_file);
        return NULL;
    }
    else
    {
        Log(LOG_LEVEL_DEBUG, "Loading policy file %s", policy_file);
    }

    policy = Cf3ParseFile(config, policy_file);
    // we keep the checksum and the policy file name to help debugging
    StringSetAdd(parsed_files_and_checksums, xstrdup(policy_file));
    StringSetAdd(parsed_files_and_checksums, xstrdup(hashprintbuffer));

    if (policy)
    {
        Seq *errors = SeqNew(10, free);
        if (!PolicyCheckPartial(policy, errors))
        {
            Writer *writer = FileWriter(stderr);
            for (size_t i = 0; i < errors->length; i++)
            {
                PolicyErrorWrite(writer, errors->data[i]);
            }
            WriterClose(writer);
            SeqDestroy(errors);

            StringSetAdd(failed_files, xstrdup(policy_file));
            return NULL;
        }

        SeqDestroy(errors);
    }
    else
    {
        StringSetAdd(failed_files, xstrdup(policy_file));
        return NULL;
    }

    PolicyResolve(ctx, policy, config);

    Body *body_common_control = PolicyGetBody(policy, NULL, "common", "control");
    Body *body_file_control = PolicyGetBody(policy, NULL, "file", "control");

    if (body_common_control)
    {
        Seq *potential_inputs = BodyGetConstraint(body_common_control, "inputs");
        Constraint *cp = EffectiveConstraint(ctx, potential_inputs);
        SeqDestroy(potential_inputs);

        if (cp)
        {
            Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval), parsed_files_and_checksums, failed_files);
            if (aux_policy)
            {
                policy = PolicyMerge(policy, aux_policy);
            }
        }
    }

    if (body_file_control)
    {
        Seq *potential_inputs = BodyGetConstraint(body_file_control, "inputs");
        Constraint *cp = EffectiveConstraint(ctx, potential_inputs);
        SeqDestroy(potential_inputs);

        if (cp)
        {
            Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval), parsed_files_and_checksums, failed_files);
            if (aux_policy)
            {
                policy = PolicyMerge(policy, aux_policy);
            }
        }
    }

    return policy;
}
예제 #13
0
static void execd_config_empty_cb(const EvalContext *ctx, const Policy *policy)
{
    ExecdConfig *config = ExecdConfigNew(ctx, policy);

    assert_int_equal(12, StringSetSize(config->schedule));
    assert_int_equal(true, StringSetContains(config->schedule, "Min00"));
    assert_int_equal(true, StringSetContains(config->schedule, "Min05"));
    assert_int_equal(true, StringSetContains(config->schedule, "Min10"));
    assert_int_equal(true, StringSetContains(config->schedule, "Min15"));
    assert_int_equal(true, StringSetContains(config->schedule, "Min20"));
    assert_int_equal(true, StringSetContains(config->schedule, "Min25"));
    assert_int_equal(true, StringSetContains(config->schedule, "Min30"));
    assert_int_equal(true, StringSetContains(config->schedule, "Min35"));
    assert_int_equal(true, StringSetContains(config->schedule, "Min40"));
    assert_int_equal(true, StringSetContains(config->schedule, "Min45"));
    assert_int_equal(true, StringSetContains(config->schedule, "Min50"));
    assert_int_equal(true, StringSetContains(config->schedule, "Min55"));
    assert_int_equal(0, config->splay_time);
    assert_string_equal("LOG_USER", config->log_facility);

    ExecdConfigDestroy(config);
}
예제 #14
0
파일: loading.c 프로젝트: ddurieux/core
static Policy *LoadPolicyFile(EvalContext *ctx, GenericAgentConfig *config, const char *policy_file, StringSet *parsed_files_and_checksums, StringSet *failed_files)
{
    unsigned char digest[EVP_MAX_MD_SIZE + 1] = { 0 };
    char hashbuffer[CF_HOSTKEY_STRING_SIZE] = { 0 };
    char hashprintbuffer[CF_BUFSIZE] = { 0 };

    HashFile(policy_file, digest, CF_DEFAULT_DIGEST);
    snprintf(hashprintbuffer, CF_BUFSIZE - 1, "{checksum}%s",
             HashPrintSafe(hashbuffer, sizeof(hashbuffer), digest,
                           CF_DEFAULT_DIGEST, true));

    Log(LOG_LEVEL_DEBUG, "Hashed policy file %s to %s", policy_file, hashprintbuffer);

    if (StringSetContains(parsed_files_and_checksums, policy_file))
    {
        Log(LOG_LEVEL_VERBOSE, "Skipping loading of duplicate policy file %s", policy_file);
        return NULL;
    }
    else if (StringSetContains(parsed_files_and_checksums, hashprintbuffer))
    {
        Log(LOG_LEVEL_VERBOSE, "Skipping loading of duplicate (detected by hash) policy file %s", policy_file);
        return NULL;
    }
    else
    {
        Log(LOG_LEVEL_DEBUG, "Loading policy file %s", policy_file);
    }

    Policy *policy = Cf3ParseFile(config, policy_file);
    // we keep the checksum and the policy file name to help debugging
    StringSetAdd(parsed_files_and_checksums, xstrdup(policy_file));
    StringSetAdd(parsed_files_and_checksums, xstrdup(hashprintbuffer));

    if (policy)
    {
        Seq *errors = SeqNew(10, free);
        if (!PolicyCheckPartial(policy, errors))
        {
            Writer *writer = FileWriter(stderr);
            for (size_t i = 0; i < errors->length; i++)
            {
                PolicyErrorWrite(writer, errors->data[i]);
            }
            WriterClose(writer);
            SeqDestroy(errors);

            StringSetAdd(failed_files, xstrdup(policy_file));
            PolicyDestroy(policy);
            return NULL;
        }

        SeqDestroy(errors);
    }
    else
    {
        StringSetAdd(failed_files, xstrdup(policy_file));
        return NULL;
    }

    PolicyResolve(ctx, policy, config);

    DataType def_inputs_type = CF_DATA_TYPE_NONE;
    VarRef *inputs_ref = VarRefParse("def.augment_inputs");
    const void *def_inputs = EvalContextVariableGet(ctx, inputs_ref, &def_inputs_type);
    VarRefDestroy(inputs_ref);

    if (RVAL_TYPE_CONTAINER == DataTypeToRvalType(def_inputs_type) && NULL != def_inputs)
    {
        const JsonElement *el;
        JsonIterator iter = JsonIteratorInit((JsonElement*) def_inputs);
        while ((el = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true)))
        {
            char *input = JsonPrimitiveToString(el);

            Log(LOG_LEVEL_VERBOSE, "Loading augments from def.augment_inputs: %s", input);

            Rlist* inputs_rlist = NULL;
            RlistAppendScalar(&inputs_rlist, input);
            Policy *aux_policy = LoadPolicyInputFiles(ctx, config, inputs_rlist,
                                                      parsed_files_and_checksums, failed_files);
            if (aux_policy)
            {
                policy = PolicyMerge(policy, aux_policy);
            }

            RlistDestroy(inputs_rlist);
            free(input);
        }
    }

    Body *body_common_control = PolicyGetBody(policy, NULL, "common", "control");
    Body *body_file_control = PolicyGetBody(policy, NULL, "file", "control");

    if (body_common_control)
    {
        Seq *potential_inputs = BodyGetConstraint(body_common_control, "inputs");
        Constraint *cp = EffectiveConstraint(ctx, potential_inputs);
        SeqDestroy(potential_inputs);

        if (cp)
        {
            Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval), parsed_files_and_checksums, failed_files);
            if (aux_policy)
            {
                policy = PolicyMerge(policy, aux_policy);
            }
        }
    }

    if (body_file_control)
    {
        Seq *potential_inputs = BodyGetConstraint(body_file_control, "inputs");
        Constraint *cp = EffectiveConstraint(ctx, potential_inputs);
        SeqDestroy(potential_inputs);

        if (cp)
        {
            Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval), parsed_files_and_checksums, failed_files);
            if (aux_policy)
            {
                policy = PolicyMerge(policy, aux_policy);
            }
        }
    }

    return policy;
}
예제 #15
0
static void test_load(void)
{
    GenericAgentConfig *agent_config = GenericAgentConfigNewDefault(AGENT_TYPE_EXECUTOR);
    ExecConfig *c = ExecConfigNewDefault(true, "host", "ip");

    assert_true(c->scheduled_run);
    assert_string_equal("host", c->fq_name);
    assert_string_equal("ip", c->ip_address);

    TestCheckConfigIsDefault(c);

    EvalContext *ctx = EvalContextNew();
    {
        VarRef *lval = VarRefParse("g.host");
        EvalContextVariablePut(ctx, lval, "snookie", DATA_TYPE_STRING, NULL);
        VarRefDestroy(lval);
    }

    // provide a full body executor control and check that all options are collected
    {
        Policy *p = LoadPolicy("body_executor_control_full.cf");
        PolicyResolve(ctx, p, agent_config);

        ExecConfigUpdate(ctx, p, c);

        assert_true(c->scheduled_run);
        assert_string_equal("host", c->fq_name);
        assert_string_equal("ip", c->ip_address);

        assert_int_equal(120, c->agent_expireafter);
        assert_string_equal("/bin/echo", c->exec_command);
        assert_string_equal("LOG_LOCAL6",c->log_facility);
        assert_string_equal("*****@*****.**",c->mail_from_address);
        assert_int_equal(50, c->mail_max_lines);
        assert_string_equal("localhost", c->mail_server);
        assert_string_equal("*****@*****.**",c->mail_to_address);
        assert_string_equal("Test [localhost/127.0.0.1]",c->mail_subject);

        // splay time hard to test (pseudo random)

        assert_int_equal(2, StringSetSize(c->schedule));
        assert_true(StringSetContains(c->schedule, "Min00_05"));
        assert_true(StringSetContains(c->schedule, "Min05_10"));

        PolicyDestroy(p);
    }

    // provide a small policy and check that missing settings are being reverted to default
    {
        {
            Policy *p = LoadPolicy("body_executor_control_agent_expireafter_only.cf");
            PolicyResolve(ctx, p, agent_config);

            ExecConfigUpdate(ctx, p, c);

            assert_true(c->scheduled_run);
            assert_string_equal("host", c->fq_name);
            assert_string_equal("ip", c->ip_address);

            assert_int_equal(121, c->agent_expireafter);

            // rest should be default
            assert_string_equal("", c->exec_command);
            assert_string_equal("LOG_USER",c->log_facility);
            assert_string_equal("",c->mail_from_address);
            assert_int_equal(30, c->mail_max_lines);
            assert_string_equal("", c->mail_server);
            assert_string_equal("",c->mail_to_address);
            assert_string_equal("",c->mail_subject);
            assert_int_equal(0, c->splay_time);

            assert_int_equal(12, StringSetSize(c->schedule));

            PolicyDestroy(p);
        }
    }

    EvalContextDestroy(ctx);
    GenericAgentConfigDestroy(agent_config);

}
예제 #16
0
static void test_class_persistence(void)
{
    EvalContext *ctx = EvalContextNew();

    // simulate old version
    {
        CF_DB *dbp;
        PersistentClassInfo i;
        assert_true(OpenDB(&dbp, dbid_state));

        i.expires = UINT_MAX;
        i.policy = CONTEXT_STATE_POLICY_RESET;

        WriteDB(dbp, "old", &i, sizeof(PersistentClassInfo));

        CloseDB(dbp);
    }

    // e.g. by monitoring
    EvalContextHeapPersistentSave(ctx, "class1", 3, CONTEXT_STATE_POLICY_PRESERVE, "a,b");

    // e.g. by a class promise in a bundle with a namespace
    {
        Policy *p = PolicyNew();
        Bundle *bp = PolicyAppendBundle(p, "ns1", "bundle1", "agent", NULL, NULL);

        EvalContextStackPushBundleFrame(ctx, bp, NULL, false);
        EvalContextHeapPersistentSave(ctx, "class2", 5, CONTEXT_STATE_POLICY_PRESERVE, "x");
        EvalContextStackPopFrame(ctx);

        PolicyDestroy(p);
    }

    EvalContextHeapPersistentLoadAll(ctx);

    {
        const Class *cls = EvalContextClassGet(ctx, "default", "old");
        assert_true(cls != NULL);

        assert_string_equal("old", cls->name);
        assert_true(cls->tags != NULL);
        assert_int_equal(1, StringSetSize(cls->tags));
        assert_true(StringSetContains(cls->tags, "source=persistent"));
    }

    {
        const Class *cls = EvalContextClassGet(ctx, "default", "class1");
        assert_true(cls != NULL);

        assert_string_equal("class1", cls->name);
        assert_true(cls->tags != NULL);
        assert_int_equal(3, StringSetSize(cls->tags));
        assert_true(StringSetContains(cls->tags, "source=persistent"));
        assert_true(StringSetContains(cls->tags, "a"));
        assert_true(StringSetContains(cls->tags, "b"));
    }

    {
        const Class *cls = EvalContextClassGet(ctx, "ns1", "class2");
        assert_true(cls != NULL);

        assert_string_equal("ns1", cls->ns);
        assert_string_equal("class2", cls->name);
        assert_true(cls->tags != NULL);
        assert_int_equal(2, StringSetSize(cls->tags));
        assert_true(StringSetContains(cls->tags, "source=persistent"));
        assert_true(StringSetContains(cls->tags, "x"));
    }

    EvalContextDestroy(ctx);
}