Ejemplo n.º 1
0
void VerifyEnvironmentsPromise(EvalContext *ctx, Promise *pp)
{
    Attributes a = { {0} };
    CfLock thislock;
    Promise *pexp;

    a = GetEnvironmentsAttributes(ctx, pp);

    if (EnvironmentsSanityChecks(a, pp))
    {
        thislock = AcquireLock(ctx, "virtual", VUQNAME, CFSTARTTIME, a.transaction, pp, false);

        if (thislock.lock == NULL)
        {
            return;
        }

        PromiseBanner(pp);
        ScopeNewSpecialScalar(ctx, "this", "promiser", pp->promiser, DATA_TYPE_STRING);

        pexp = ExpandDeRefPromise(ctx, "this", pp);
        VerifyEnvironments(ctx, a, pp);
        PromiseDestroy(pexp);
    }

    YieldCurrentLock(thislock);
}
Ejemplo n.º 2
0
void VerifyEnvironmentsPromise(Promise *pp)
{
    Attributes a = { {0} };
    CfLock thislock;
    Promise *pexp;

    a = GetEnvironmentsAttributes(pp);

    if (EnvironmentsSanityChecks(a, pp))
    {
        thislock = AcquireLock("virtual", VUQNAME, CFSTARTTIME, a, pp, false);

        if (thislock.lock == NULL)
        {
            return;
        }

        CF_OCCUR++;

        PromiseBanner(pp);
        NewScalar("this", "promiser", pp->promiser, cf_str);

        pexp = ExpandDeRefPromise("this", pp);
        VerifyEnvironments(a, pp);
        DeletePromise(pexp);
    }

    YieldCurrentLock(thislock);
}
Ejemplo n.º 3
0
PromiseResult VerifyEnvironmentsPromise(EvalContext *ctx, const Promise *pp)
{
    CfLock thislock;

    Attributes a = GetEnvironmentsAttributes(ctx, pp);

    PromiseResult result = PROMISE_RESULT_NOOP;
    if (EnvironmentsSanityChecks(a, pp))
    {
        thislock = AcquireLock(ctx, "virtual", VUQNAME, CFSTARTTIME, a.transaction, pp, false);

        if (thislock.lock == NULL)
        {
            return PROMISE_RESULT_NOOP;
        }

        PromiseBanner(ctx, pp);

        bool excluded = false;
        Promise *pexp = ExpandDeRefPromise(ctx, pp, &excluded);
        if (excluded)
        {
            result = PROMISE_RESULT_SKIPPED;
        }
        else
        {
            result = VerifyEnvironments(ctx, a, pp);
        }

        PromiseDestroy(pexp);
    }

    YieldCurrentLock(thislock);

    return result;
}
Ejemplo n.º 4
0
void LocateFilePromiserGroup(EvalContext *ctx, char *wildpath, Promise *pp, void (*fnptr) (EvalContext *ctx, char *path, Promise *ptr))
{
    Item *path, *ip, *remainder = NULL;
    char pbuffer[CF_BUFSIZE];
    struct stat statbuf;
    int count = 0, lastnode = false, expandregex = false;
    uid_t agentuid = getuid();
    int create = PromiseGetConstraintAsBoolean(ctx, "create", pp);
    char *pathtype = ConstraintGetRvalValue(ctx, "pathtype", pp, RVAL_TYPE_SCALAR);

/* Do a search for promiser objects matching wildpath */

    if ((!IsPathRegex(wildpath)) || (pathtype && (strcmp(pathtype, "literal") == 0)))
    {
        Log(LOG_LEVEL_VERBOSE, "Using literal pathtype for '%s'", wildpath);
        (*fnptr) (ctx, wildpath, pp);
        return;
    }
    else
    {
        Log(LOG_LEVEL_VERBOSE, "Using regex pathtype for '%s' (see pathtype)", wildpath);
    }

    pbuffer[0] = '\0';
    path = SplitString(wildpath, '/');  // require forward slash in regex on all platforms

    for (ip = path; ip != NULL; ip = ip->next)
    {
        if ((ip->name == NULL) || (strlen(ip->name) == 0))
        {
            continue;
        }

        if (ip->next == NULL)
        {
            lastnode = true;
        }

        /* No need to chdir as in recursive descent, since we know about the path here */

        if (IsRegex(ip->name))
        {
            remainder = ip->next;
            expandregex = true;
            break;
        }
        else
        {
            expandregex = false;
        }

        if (!JoinPath(pbuffer, ip->name))
        {
            Log(LOG_LEVEL_ERR, "Buffer has limited size in LocateFilePromiserGroup");
            return;
        }

        if (stat(pbuffer, &statbuf) != -1)
        {
            if ((S_ISDIR(statbuf.st_mode)) && ((statbuf.st_uid) != agentuid) && ((statbuf.st_uid) != 0))
            {
                Log(LOG_LEVEL_INFO,
                    "Directory '%s' in search path '%s' is controlled by another user (uid %ju) - trusting its content is potentially risky (possible race condition)",
                      pbuffer, wildpath, (uintmax_t)statbuf.st_uid);
                PromiseRef(LOG_LEVEL_INFO, pp);
            }
        }
    }

    if (expandregex)            /* Expand one regex link and hand down */
    {
        char nextbuffer[CF_BUFSIZE], nextbufferOrig[CF_BUFSIZE], regex[CF_BUFSIZE];
        const struct dirent *dirp;
        Dir *dirh;

        memset(regex, 0, CF_BUFSIZE);

        strncpy(regex, ip->name, CF_BUFSIZE - 1);

        if ((dirh = DirOpen(pbuffer)) == NULL)
        {
            // Could be a dummy directory to be created so this is not an error.
            Log(LOG_LEVEL_VERBOSE, "Using best-effort expanded (but non-existent) file base path '%s'", wildpath);
            (*fnptr) (ctx, wildpath, pp);
            DeleteItemList(path);
            return;
        }
        else
        {
            count = 0;

            for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh))
            {
                if (!ConsiderLocalFile(dirp->d_name, pbuffer))
                {
                    continue;
                }

                if ((!lastnode) && (!S_ISDIR(statbuf.st_mode)))
                {
                    Log(LOG_LEVEL_DEBUG, "Skipping non-directory '%s'", dirp->d_name);
                    continue;
                }

                if (FullTextMatch(regex, dirp->d_name))
                {
                    Log(LOG_LEVEL_DEBUG, "Link '%s' matched regex '%s'", dirp->d_name, regex);
                }
                else
                {
                    continue;
                }

                count++;

                strncpy(nextbuffer, pbuffer, CF_BUFSIZE - 1);
                AddSlash(nextbuffer);
                strcat(nextbuffer, dirp->d_name);

                for (ip = remainder; ip != NULL; ip = ip->next)
                {
                    AddSlash(nextbuffer);
                    strcat(nextbuffer, ip->name);
                }

                /* The next level might still contain regexs, so go again as long as expansion is not nullpotent */

                if ((!lastnode) && (strcmp(nextbuffer, wildpath) != 0))
                {
                    LocateFilePromiserGroup(ctx, nextbuffer, pp, fnptr);
                }
                else
                {
                    Promise *pcopy;

                    Log(LOG_LEVEL_VERBOSE, "Using expanded file base path '%s'", nextbuffer);

                    /* Now need to recompute any back references to get the complete path */

                    snprintf(nextbufferOrig, sizeof(nextbufferOrig), "%s", nextbuffer);
                    MapNameForward(nextbuffer);

                    if (!FullTextMatch(pp->promiser, nextbuffer))
                    {
                        Log(LOG_LEVEL_DEBUG, "Error recomputing references for '%s' in '%s'", pp->promiser, nextbuffer);
                    }

                    /* If there were back references there could still be match.x vars to expand */

                    pcopy = ExpandDeRefPromise(ctx, ScopeGetCurrent()->scope, pp);
                    (*fnptr) (ctx, nextbufferOrig, pcopy);
                    PromiseDestroy(pcopy);
                }
            }

            DirClose(dirh);
        }
    }
    else
    {
        Log(LOG_LEVEL_VERBOSE, "Using file base path '%s'", pbuffer);
        (*fnptr) (ctx, pbuffer, pp);
    }

    if (count == 0)
    {
        Log(LOG_LEVEL_VERBOSE, "No promiser file objects matched as regular expression '%s'", wildpath);

        if (create)
        {
            (*fnptr)(ctx, pp->promiser, pp);
        }
    }

    DeleteItemList(path);
}
Ejemplo n.º 5
0
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);
}