Beispiel #1
0
int ParseFlagString(Rlist *bitlist, u_long *plusmask, u_long *minusmask)
{
    if (bitlist == NULL)
    {
        return true;
    }

    *plusmask = 0;
    *minusmask = 0;

    for (const Rlist *rp = bitlist; rp != NULL; rp = rp->next)
    {
        const char *flag = RlistScalarValue(rp);
        char op = *RlistScalarValue(rp);

        switch (op)
        {
        case '-':
            *minusmask |= ConvertBSDBits(flag + 1);
            break;

        case '+':
            *plusmask |= ConvertBSDBits(flag + 1);
            break;

        default:
            *plusmask |= ConvertBSDBits(flag);
            break;

        }
    }

    Log(LOG_LEVEL_DEBUG, "ParseFlagString: [PLUS = %lo] [MINUS = %lo]", *plusmask, *minusmask);
    return true;
}
Beispiel #2
0
static bool RlistItemMACLess(void *lhs, void *rhs, ARG_UNUSED void *ctx)
{
    int bytes = 6;
    unsigned char left[bytes], right[bytes];
    int matched_left = 6 == ParseEtherAddress(RlistScalarValue((Rlist*)lhs), left);
    int matched_right = 6 == ParseEtherAddress(RlistScalarValue((Rlist*)rhs), right);

    if (matched_left && matched_right)
    {
        int difference = memcmp(left, right, bytes);
        if (difference != 0) return difference < 0;
    }

    if (matched_left)
    {
        return false;
    }

    if (matched_right)
    {
        return true;
    }

    // neither item matched
    return RlistItemLess(lhs, rhs, ctx);
}
Beispiel #3
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 #4
0
int DoAllSignals(EvalContext *ctx, Item *siglist, Attributes a, const Promise *pp, PromiseResult *result)
{
    Item *ip;
    Rlist *rp;
    pid_t pid;
    int killed = false;

    if (siglist == NULL)
    {
        return 0;
    }

    if (a.signals == NULL)
    {
        Log(LOG_LEVEL_VERBOSE, "No signals to send for '%s'", pp->promiser);
        return 0;
    }

    for (ip = siglist; ip != NULL; ip = ip->next)
    {
        pid = ip->counter;

        for (rp = a.signals; rp != NULL; rp = rp->next)
        {
            int signal = SignalFromString(RlistScalarValue(rp));

            if (!DONTDO)
            {
                if ((signal == SIGKILL) || (signal == SIGTERM))
                {
                    killed = true;
                }

                if (kill((pid_t) pid, signal) < 0)
                {
                    cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a,
                         "Couldn't send promised signal '%s' (%d) to pid %jd (might be dead). (kill: %s)", RlistScalarValue(rp),
                         signal, (intmax_t)pid, GetErrorStr());
                    *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL);
                }
                else
                {
                    cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Signalled '%s' (%d) to process %jd (%s)",
                         RlistScalarValue(rp), signal, (intmax_t)pid, ip->name);
                    *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE);
                }
            }
            else
            {
                Log(LOG_LEVEL_ERR, "Need to keep signal promise '%s' in process entry '%s'",
                      RlistScalarValue(rp), ip->name);
            }
        }
    }

    return killed;
}
Beispiel #5
0
static void test_split_escaped(void)
{
    Rlist *list = RlistFromSplitString("a\\,b\\c\\,d,w\\,x\\,y\\,z", ',');
    assert_int_equal(2, RlistLen(list));
    assert_string_equal("a,b\\c,d", RlistScalarValue(list));
    assert_string_equal("w,x,y,z", RlistScalarValue(list->next));

    RlistDestroy(list);
}
Beispiel #6
0
static int DoAllSignals(Item *siglist, Attributes a, Promise *pp)
{
    Item *ip;
    Rlist *rp;
    pid_t pid;
    int killed = false;

    CfDebug("DoSignals(%s)\n", pp->promiser);

    if (siglist == NULL)
    {
        return 0;
    }

    if (a.signals == NULL)
    {
        CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> No signals to send for %s\n", pp->promiser);
        return 0;
    }

    for (ip = siglist; ip != NULL; ip = ip->next)
    {
        pid = ip->counter;

        for (rp = a.signals; rp != NULL; rp = rp->next)
        {
            int signal = SignalFromString(rp->item);

            if (!DONTDO)
            {
                if ((signal == SIGKILL) || (signal == SIGTERM))
                {
                    killed = true;
                }

                if (kill((pid_t) pid, signal) < 0)
                {
                    cfPS(OUTPUT_LEVEL_VERBOSE, CF_FAIL, "kill", pp, a,
                         " !! Couldn't send promised signal \'%s\' (%d) to pid %jd (might be dead)\n", RlistScalarValue(rp),
                         signal, (intmax_t)pid);
                }
                else
                {
                    cfPS(OUTPUT_LEVEL_INFORM, CF_CHG, "", pp, a, " -> Signalled '%s' (%d) to process %jd (%s)\n",
                         RlistScalarValue(rp), signal, (intmax_t)pid, ip->name);
                }
            }
            else
            {
                CfOut(OUTPUT_LEVEL_ERROR, "", " -> Need to keep signal promise \'%s\' in process entry %s",
                      RlistScalarValue(rp), ip->name);
            }
        }
    }

    return killed;
}
Beispiel #7
0
static int CheckRegistrySanity(const Attributes *a, const Promise *pp)
{
    assert(a != NULL);
    bool retval = true;

    ValidateRegistryPromiser(pp->promiser, pp);

    if ((a->database.operation) && (strcmp(a->database.operation, "create") == 0))
    {
        if (a->database.rows == NULL)
        {
            Log(LOG_LEVEL_INFO, "No row values promised for the MS registry database");
        }

        if (a->database.columns != NULL)
        {
            Log(LOG_LEVEL_ERR, "Columns are only used to delete promised values for the MS registry database");
            retval = false;
        }
    }

    if ((a->database.operation)
        && ((strcmp(a->database.operation, "delete") == 0) || (strcmp(a->database.operation, "drop") == 0)))
    {
        if (a->database.columns == NULL)
        {
            Log(LOG_LEVEL_INFO, "No columns were promised deleted in the MS registry database");
        }

        if (a->database.rows != NULL)
        {
            Log(LOG_LEVEL_ERR, "Rows cannot be deleted in the MS registry database, only entire columns");
            retval = false;
        }
    }

    for (Rlist *rp = a->database.rows; rp != NULL; rp = rp->next)
    {
        if (CountChar(RlistScalarValue(rp), ',') != 2)
        {
            Log(LOG_LEVEL_ERR, "Registry row format should be NAME,REG_SZ,VALUE, not '%s'", RlistScalarValue(rp));
            retval = false;
        }
    }

    for (Rlist *rp = a->database.columns; rp != NULL; rp = rp->next)
    {
        if (CountChar(RlistScalarValue(rp), ',') > 0)
        {
            Log(LOG_LEVEL_ERR, "MS registry column format should be NAME only in deletion");
            retval = false;
        }
    }

    return retval;
}
Beispiel #8
0
static void test_last(void)
{
    Rlist *l = NULL;
    assert_true(RlistLast(l) == NULL);
    RlistAppendScalar(&l, "a");
    assert_string_equal("a", RlistScalarValue(RlistLast(l)));
    RlistAppendScalar(&l, "b");
    assert_string_equal("b", RlistScalarValue(RlistLast(l)));
    RlistDestroy(l);
}
static bool DistributeClass(EvalContext *ctx, const Rlist *dist, const Promise *pp)
{
    int total = 0;
    const Rlist *rp;

    for (rp = dist; rp != NULL; rp = rp->next)
    {
        int result = IntFromString(RlistScalarValue(rp));

        if (result < 0)
        {
            Log(LOG_LEVEL_ERR, "Negative integer in class distribution");
            PromiseRef(LOG_LEVEL_ERR, pp);
            return false;
        }

        total += result;
    }

    if (total == 0)
    {
        Log(LOG_LEVEL_ERR, "An empty distribution was specified on RHS");
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

    double fluct = drand48() * total;
    assert(0 <= fluct && fluct < total);

    for (rp = dist; rp != NULL; rp = rp->next)
    {
        fluct -= IntFromString(RlistScalarValue(rp));
        if (fluct < 0)
        {
            break;
        }
    }
    assert(rp);

    char buffer[CF_MAXVARSIZE];
    snprintf(buffer, CF_MAXVARSIZE, "%s_%s", pp->promiser, RlistScalarValue(rp));

    if (strcmp(PromiseGetBundle(pp)->type, "common") == 0)
    {
        EvalContextClassPutSoft(ctx, buffer, CONTEXT_SCOPE_NAMESPACE,
                                "source=promise");
    }
    else
    {
        EvalContextClassPutSoft(ctx, buffer, CONTEXT_SCOPE_BUNDLE,
                                "source=promise");
    }

    return true;
}
Beispiel #10
0
bool RlistIsUnresolved(const Rlist *list)
{
    for (const Rlist *rp = list; rp != NULL; rp = rp->next)
    {
        if (rp->val.type != RVAL_TYPE_SCALAR)
        {
            return true;
        }

        if (IsCf3Scalar(RlistScalarValue(rp)))
        {
            if (strstr(RlistScalarValue(rp), "$(this)") || strstr(RlistScalarValue(rp), "${this}") ||
                strstr(RlistScalarValue(rp), "$(this.k)") || strstr(RlistScalarValue(rp), "${this.k}") ||
                strstr(RlistScalarValue(rp), "$(this.k[1])") || strstr(RlistScalarValue(rp), "${this.k[1]}") ||
                strstr(RlistScalarValue(rp), "$(this.v)") || strstr(RlistScalarValue(rp), "${this.v}"))
            {
                // We should allow this in function args for substitution in maplist() etc
                // We should allow this.k and this.k[1] and this.v in function args for substitution in maparray() etc
            }
            else
            {
                return true;
            }
        }
    }

    return false;
}
Beispiel #11
0
static int SelectOwnerMatch(EvalContext *ctx, char *path, struct stat *lstatptr, Rlist *crit)
{
    Rlist *rp;
    char ownerName[CF_BUFSIZE];
    int gotOwner;

    StringSet *leafattrib = StringSetNew();

#ifndef __MINGW32__                   // no uids on Windows
    char buffer[CF_SMALLBUF];
    snprintf(buffer, CF_SMALLBUF, "%jd", (uintmax_t) lstatptr->st_uid);
    StringSetAdd(leafattrib, xstrdup(buffer));
#endif /* __MINGW32__ */

    gotOwner = GetOwnerName(path, lstatptr, ownerName, sizeof(ownerName));

    if (gotOwner)
    {
        StringSetAdd(leafattrib, xstrdup(ownerName));
    }
    else
    {
        StringSetAdd(leafattrib, xstrdup("none"));
    }

    for (rp = crit; rp != NULL; rp = rp->next)
    {
        if (EvalFileResult((char *) rp->item, leafattrib))
        {
            Log(LOG_LEVEL_DEBUG, "Select owner match");
            StringSetDestroy(leafattrib);
            return true;
        }

        if (gotOwner && (FullTextMatch(ctx, RlistScalarValue(rp), ownerName)))
        {
            Log(LOG_LEVEL_DEBUG, "Select owner match");
            StringSetDestroy(leafattrib);
            return true;
        }

#ifndef __MINGW32__
        if (FullTextMatch(ctx, RlistScalarValue(rp), buffer))
        {
            Log(LOG_LEVEL_DEBUG, "Select owner match");
            StringSetDestroy(leafattrib);
            return true;
        }
#endif /* !__MINGW32__ */
    }

    StringSetDestroy(leafattrib);
    return false;
}
Beispiel #12
0
static void test_reverse(void)
{
    Rlist *list = RlistFromSplitString("a,b,c", ',');

    RlistReverse(&list);
    assert_string_equal("c", RlistScalarValue(list));
    assert_string_equal("b", RlistScalarValue(list->next));
    assert_string_equal("a", RlistScalarValue(list->next->next));

    RlistDestroy(list);
}
Beispiel #13
0
static void test_regex_split_too_few_chunks()
{
    Rlist *list = RlistFromRegexSplitNoOverflow("one:two:three", ":", 2);

    assert_int_equal(2, RlistLen(list));

    assert_string_equal(RlistScalarValue(list), "one");
    assert_string_equal(RlistScalarValue(list->next), "two:three");

    RlistDestroy(list);
}
Beispiel #14
0
static void test_regex_split_overlapping_delimiters()
{
    Rlist *list = RlistFromRegexSplitNoOverflow("-one---two---three", "--", 3);

    assert_int_equal(3, RlistLen(list));

    assert_string_equal(RlistScalarValue(list), "-one");
    assert_string_equal(RlistScalarValue(list->next), "-two");
    assert_string_equal(RlistScalarValue(list->next->next), "-three");

    RlistDestroy(list);
}
Beispiel #15
0
static void test_regex_split()
{
    Rlist *list = RlistFromRegexSplitNoOverflow("one-->two-->three", "-+>", 3);

    assert_int_equal(3, RlistLen(list));

    assert_string_equal(RlistScalarValue(list), "one");
    assert_string_equal(RlistScalarValue(list->next), "two");
    assert_string_equal(RlistScalarValue(list->next->next), "three");

    RlistDestroy(list);
}
Beispiel #16
0
static void CopyLocalizedReferencesToBundleScope(EvalContext *ctx,
                                                 const Bundle *bundle,
                                                 const Rlist *ref_names)
{
    for (const Rlist *rp = ref_names; rp != NULL; rp = rp->next)
    {
        const char *mangled = RlistScalarValue(rp);
        char *demangled = xstrdup(mangled);
        DeMangleVarRefString(demangled, strlen(demangled));

        if (strchr(RlistScalarValue(rp), CF_MAPPEDLIST))
        {
            VarRef *demangled_ref = VarRefParseFromBundle(demangled, bundle);

            DataType value_type;
            const void *value = EvalContextVariableGet(ctx, demangled_ref, &value_type);
            if (!value)
            {
                ProgrammingError("Couldn't find extracted variable '%s'", mangled);
            }

            VarRef *mangled_ref = VarRefParseFromBundle(mangled, bundle);

            switch (DataTypeToRvalType(value_type))
            {
            case RVAL_TYPE_LIST:
                {
                    Rlist *list = RlistCopy(value);
                    RlistFlatten(ctx, &list);

                    EvalContextVariablePut(ctx, mangled_ref, list, value_type, "source=agent");
                    RlistDestroy(list);
                }
                break;

            case RVAL_TYPE_CONTAINER:
            case RVAL_TYPE_SCALAR:
                EvalContextVariablePut(ctx, mangled_ref, value, value_type, "source=agent");
                break;

            case RVAL_TYPE_FNCALL:
            case RVAL_TYPE_NOPROMISEE:
                ProgrammingError("Illegal rval type in switch %d", DataTypeToRvalType(value_type));
            }

            VarRefDestroy(mangled_ref);
            VarRefDestroy(demangled_ref);
        }

        free(demangled);
    }
}
Beispiel #17
0
static void test_regex_split_empty_chunks()
{
    Rlist *list = RlistFromRegexSplitNoOverflow(":one:two:three:", ":", 5);

    assert_int_equal(5, RlistLen(list));

    assert_string_equal(RlistScalarValue(list), "");
    assert_string_equal(RlistScalarValue(list->next), "one");
    assert_string_equal(RlistScalarValue(list->next->next), "two");
    assert_string_equal(RlistScalarValue(list->next->next->next), "three");
    assert_string_equal(RlistScalarValue(list->next->next->next->next), "");

    RlistDestroy(list);
}
Beispiel #18
0
Datei: expand.c Projekt: tzz/core
Rlist *ExpandList(EvalContext *ctx, const char *ns, const char *scope, const Rlist *list, int expandnaked)
{
    Rlist *start = NULL;
    Rval returnval;

    for (const Rlist *rp = list; rp != NULL; rp = rp->next)
    {
        if (!expandnaked && (rp->val.type == RVAL_TYPE_SCALAR) && IsNakedVar(RlistScalarValue(rp), '@'))
        {
            returnval = RvalNew(RlistScalarValue(rp), RVAL_TYPE_SCALAR);
        }
        else if ((rp->val.type == RVAL_TYPE_SCALAR) && IsNakedVar(RlistScalarValue(rp), '@'))
        {
            char naked[CF_MAXVARSIZE];
            GetNaked(naked, RlistScalarValue(rp));

            if (!IsExpandable(naked))
            {
                VarRef *ref = VarRefParseFromScope(naked, scope);

                DataType value_type = DATA_TYPE_NONE;
                const void *value = EvalContextVariableGet(ctx, ref, &value_type);
                if (value)
                {
                    returnval = ExpandPrivateRval(ctx, ns, scope, value, DataTypeToRvalType(value_type));
                }
                else
                {
                    returnval = ExpandPrivateRval(ctx, ns, scope, rp->val.item, rp->val.type);
                }

                VarRefDestroy(ref);
            }
            else
            {
                returnval = ExpandPrivateRval(ctx, ns, scope, rp->val.item, rp->val.type);
            }
        }
        else
        {
            returnval = ExpandPrivateRval(ctx, ns, scope, rp->val.item, rp->val.type);
        }

        RlistAppend(&start, returnval.item, returnval.type);
        RvalDestroy(returnval);
    }

    return start;
}
Beispiel #19
0
void RlistFlatten(EvalContext *ctx, Rlist **list)
{
    for (Rlist *rp = *list; rp != NULL;)
    {
        if (rp->val.type != RVAL_TYPE_SCALAR)
        {
            rp = rp->next;
            continue;
        }

        char naked[CF_BUFSIZE] = "";
        if (IsNakedVar(RlistScalarValue(rp), '@'))
        {
            GetNaked(naked, RlistScalarValue(rp));

            if (!IsExpandable(naked))
            {
                Rval rv;
                VarRef *ref = VarRefParse(naked);

                bool var_found = EvalContextVariableGet(ctx, ref, &rv, NULL);

                VarRefDestroy(ref);

                if (var_found)
                {
                    switch (rv.type)
                    {
                    case RVAL_TYPE_LIST:
                        for (const Rlist *srp = rv.item; srp != NULL; srp = srp->next)
                        {
                            RlistAppendRval(list, RvalCopy(srp->val));
                        }
                        Rlist *next = rp->next;
                        RlistDestroyEntry(list, rp);
                        rp = next;
                        continue;

                    default:
                        ProgrammingError("List variable does not resolve to a list");
                        RlistAppendRval(list, RvalCopy(rp->val));
                        break;
                    }
                }
            }
        }
        rp = rp->next;
    }
}
Beispiel #20
0
static void test_split_long(void)
{
    char buf[CF_MAXVARSIZE * 2], *tail = buf + CF_MAXVARSIZE;
    memset(buf, '$', sizeof(buf) - 1);
    buf[sizeof(buf) - 1] = '\0';
    buf[CF_MAXVARSIZE - 1] = ',';

    Rlist *list = RlistFromSplitString(buf, ',');
    assert_int_equal(2, RlistLen(list));

    assert_string_equal(tail, RlistScalarValue(list));
    assert_string_equal(tail, RlistScalarValue(list->next));

    RlistDestroy(list);
}
Beispiel #21
0
static void test_copy(void)
{
    Rlist *list = NULL, *copy = NULL;

    RlistPrepend(&list, "stuff", RVAL_TYPE_SCALAR);
    RlistPrepend(&list, "more-stuff", RVAL_TYPE_SCALAR);

    copy = RlistCopy(list);

    assert_string_equal(RlistScalarValue(list), RlistScalarValue(copy));
    assert_string_equal(RlistScalarValue(list->next), RlistScalarValue(copy->next));

    RlistDestroy(list);
    RlistDestroy(copy);
}
Beispiel #22
0
static JsonElement *FnCallToJson(const FnCall *fp)
{
    assert(fp);

    JsonElement *object = JsonObjectCreate(3);

    JsonObjectAppendString(object, "name", fp->name);
    JsonObjectAppendString(object, "type", "function-call");

    JsonElement *argsArray = JsonArrayCreate(5);

    for (Rlist *rp = fp->args; rp != NULL; rp = rp->next)
    {
        switch (rp->val.type)
        {
        case RVAL_TYPE_SCALAR:
            JsonArrayAppendString(argsArray, RlistScalarValue(rp));
            break;

        case RVAL_TYPE_FNCALL:
            JsonArrayAppendObject(argsArray, FnCallToJson(RlistFnCallValue(rp)));
            break;

        default:
            assert(false && "Unknown argument type");
            break;
        }
    }
    JsonObjectAppendArray(object, "arguments", argsArray);

    return object;
}
Beispiel #23
0
static void test_expand_list_nested(void **state)
{
    EvalContext *ctx = *state;
    {
        VarRef *lval = VarRefParse("default:bundle.i");
        EvalContextVariablePut(ctx, lval, "one", CF_DATA_TYPE_STRING, NULL);
        VarRefDestroy(lval);
    }
    {
        VarRef *lval = VarRefParse("default:bundle.inner[one]");
        Rlist *list = NULL;
        RlistAppendScalar(&list, "foo");
        EvalContextVariablePut(ctx, lval, list, CF_DATA_TYPE_STRING_LIST, NULL);
        RlistDestroy(list);
        VarRefDestroy(lval);
    }

    Rlist *outer = NULL;
    RlistAppendScalar(&outer, "@{inner[$(i)]}");

    Rlist *expanded = ExpandList(ctx, "default", "bundle", outer, true);

    assert_int_equal(1, RlistLen(expanded));
    assert_string_equal("foo", RlistScalarValue(expanded));

    RlistDestroy(outer);
    RlistDestroy(expanded);
}
Beispiel #24
0
void FnCallWrite(Writer *writer, const FnCall *call)
{
    WriterWrite(writer, call->name);
    WriterWriteChar(writer, '(');

    for (const Rlist *rp = call->args; rp != NULL; rp = rp->next)
    {
        switch (rp->val.type)
        {
        case RVAL_TYPE_SCALAR:
            ScalarWrite(writer, RlistScalarValue(rp), true);
            break;

        case RVAL_TYPE_FNCALL:
            FnCallWrite(writer, RlistFnCallValue(rp));
            break;

        default:
            WriterWrite(writer, "(** Unknown argument **)\n");
            break;
        }

        if (rp->next != NULL)
        {
            WriterWriteChar(writer, ',');
        }
    }

    WriterWriteChar(writer, ')');
}
Beispiel #25
0
static int ServicesSanityChecks(Attributes a, const Promise *pp)
{
    Rlist *dep;

    switch (a.service.service_policy)
    {
    case SERVICE_POLICY_START:
        break;

    case SERVICE_POLICY_STOP:
    case SERVICE_POLICY_DISABLE:
    case SERVICE_POLICY_RESTART:
    case SERVICE_POLICY_RELOAD:
        if (strcmp(a.service.service_autostart_policy, "none") != 0)
        {
            Log(LOG_LEVEL_ERR,
                "!! Autostart policy of service promiser '%s' needs to be 'none' when service policy is not 'start', but is '%s'",
                  pp->promiser, a.service.service_autostart_policy);
            PromiseRef(LOG_LEVEL_ERR, pp);
            return false;
        }
        break;

    default:
        Log(LOG_LEVEL_ERR, "Invalid service policy for service '%s'", pp->promiser);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

    for (dep = a.service.service_depend; dep != NULL; dep = dep->next)
    {
        if (strcmp(pp->promiser, RlistScalarValue(dep)) == 0)
        {
            Log(LOG_LEVEL_ERR, "Service promiser '%s' has itself as dependency", pp->promiser);
            PromiseRef(LOG_LEVEL_ERR, pp);
            return false;
        }
    }

    if (a.service.service_type == NULL)
    {
        Log(LOG_LEVEL_ERR, "Service type for service '%s' is not known", pp->promiser);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

#ifdef __MINGW32__

    if (strcmp(a.service.service_type, "windows") != 0)
    {
        Log(LOG_LEVEL_ERR, "Service type for promiser '%s' must be 'windows' on this system, but is '%s'",
              pp->promiser, a.service.service_type);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

#endif /* __MINGW32__ */

    return true;
}
Beispiel #26
0
static JsonElement *RlistToJson(Rlist *list)
{
    JsonElement *array = JsonArrayCreate(RlistLen(list));

    for (Rlist *rp = list; rp; rp = rp->next)
    {
        switch (rp->val.type)
        {
        case RVAL_TYPE_SCALAR:
            JsonArrayAppendString(array, RlistScalarValue(rp));
            break;

        case RVAL_TYPE_LIST:
            JsonArrayAppendArray(array, RlistToJson(RlistRlistValue(rp)));
            break;

        case RVAL_TYPE_FNCALL:
            JsonArrayAppendObject(array, FnCallToJson(RlistFnCallValue(rp)));
            break;

        default:
            assert(false && "Unsupported item type in rlist");
            break;
        }
    }

    return array;
}
Beispiel #27
0
int CompareFileHashes(const char *file1, const char *file2, struct stat *sstat, struct stat *dstat, FileCopy fc, AgentConnection *conn)
{
    unsigned char digest1[EVP_MAX_MD_SIZE + 1] = { 0 }, digest2[EVP_MAX_MD_SIZE + 1] = { 0 };
    int i;

    if (sstat->st_size != dstat->st_size)
    {
        Log(LOG_LEVEL_DEBUG, "File sizes differ, no need to compute checksum");
        return true;
    }

    if (conn == NULL)
    {
        HashFile(file1, digest1, CF_DEFAULT_DIGEST);
        HashFile(file2, digest2, CF_DEFAULT_DIGEST);

        for (i = 0; i < EVP_MAX_MD_SIZE; i++)
        {
            if (digest1[i] != digest2[i])
            {
                return true;
            }
        }

        Log(LOG_LEVEL_DEBUG, "Files were identical");
        return false;           /* only if files are identical */
    }
    else
    {
        assert(fc.servers && strcmp(RlistScalarValue(fc.servers), "localhost"));
        return CompareHashNet(file1, file2, fc.encrypt, conn);  /* client.c */
    }
}
Beispiel #28
0
static void DeleteAllClasses(EvalContext *ctx, const Rlist *list)
{
    for (const Rlist *rp = list; rp != NULL; rp = rp->next)
    {
        if (CheckParseContext((char *) rp->item, CF_IDRANGE) != SYNTAX_TYPE_MATCH_OK)
        {
            return; // TODO: interesting course of action, but why is the check there in the first place?
        }

        if (EvalContextHeapContainsHard(ctx, (char *) rp->item))
        {
            Log(LOG_LEVEL_ERR, "You cannot cancel a reserved hard class '%s' in post-condition classes",
                  RlistScalarValue(rp));
        }

        const char *string = (char *) (rp->item);

        Log(LOG_LEVEL_VERBOSE, "Cancelling class '%s'", string);

        EvalContextHeapPersistentRemove(string);

        EvalContextHeapRemoveSoft(ctx, CanonifyName(string));

        EvalContextStackFrameAddNegated(ctx, CanonifyName(string));
    }
}
Beispiel #29
0
bool RlistMatchesRegex(const Rlist *list, const char *regex)
/*
   Returns true if any of the "list" of strings matches "regex".
   Non-scalars in "list" are skipped.
*/
{
    if (regex == NULL || list == NULL)
    {
        return false;
    }

    pcre *rx = CompileRegex(regex);
    if (!rx)
    {
        return false;
    }

    for (const Rlist *rp = list; rp != NULL; rp = rp->next)
    {
        if (rp->val.type == RVAL_TYPE_SCALAR &&
            StringMatchFullWithPrecompiledRegex(rx, RlistScalarValue(rp)))
        {
            pcre_free(rx);
            return true;
        }
    }

    pcre_free(rx);
    return false;
}
Beispiel #30
0
static int ServicesSanityChecks(Attributes a, const Promise *pp)
{
    Rlist *dep;

    for (dep = a.service.service_depend; dep != NULL; dep = dep->next)
    {
        if (strcmp(pp->promiser, RlistScalarValue(dep)) == 0)
        {
            Log(LOG_LEVEL_ERR, "Service promiser '%s' has itself as dependency", pp->promiser);
            PromiseRef(LOG_LEVEL_ERR, pp);
            return false;
        }
    }

    if (a.service.service_type == NULL)
    {
        Log(LOG_LEVEL_ERR, "Service type for service '%s' is not known", pp->promiser);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

#ifdef __MINGW32__

    if (strcmp(a.service.service_type, "windows") != 0)
    {
        Log(LOG_LEVEL_ERR, "Service type for promiser '%s' must be 'windows' on this system, but is '%s'",
            pp->promiser, a.service.service_type);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

#endif /* __MINGW32__ */

    return true;
}