Example #1
0
static PromiseResult FindFilePromiserObjects(EvalContext *ctx, const Promise *pp)
{
    char *val = PromiseGetConstraintAsRval(pp, "pathtype", RVAL_TYPE_SCALAR);
    int literal = (PromiseGetConstraintAsBoolean(ctx, "copy_from", pp)) || ((val != NULL) && (strcmp(val, "literal") == 0));

/* Check if we are searching over a regular expression */

    PromiseResult result = PROMISE_RESULT_SKIPPED;
    if (literal)
    {
        // Prime the promiser temporarily, may override later
        result = PromiseResultUpdate(result, VerifyFilePromise(ctx, pp->promiser, pp));
    }
    else                        // Default is to expand regex paths
    {
        result = PromiseResultUpdate(result, LocateFilePromiserGroup(ctx, pp->promiser, pp, VerifyFilePromise));
    }

    return result;
}
Example #2
0
static PromiseResult FindFilePromiserObjects(EvalContext *ctx, Promise *pp)
{
    char *val = ConstraintGetRvalValue(ctx, "pathtype", pp, RVAL_TYPE_SCALAR);
    int literal = (PromiseGetConstraintAsBoolean(ctx, "copy_from", pp)) || ((val != NULL) && (strcmp(val, "literal") == 0));

/* Check if we are searching over a regular expression */

    PromiseResult result = PROMISE_RESULT_NOOP;
    if (literal)
    {
        // Prime the promiser temporarily, may override later
        EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser", pp->promiser, DATA_TYPE_STRING);
        result = PromiseResultUpdate(result, VerifyFilePromise(ctx, pp->promiser, pp));
    }
    else                        // Default is to expand regex paths
    {
        result = PromiseResultUpdate(result, LocateFilePromiserGroup(ctx, pp->promiser, pp, VerifyFilePromise));
    }

    return result;
}
Example #3
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);
}
Example #4
0
static PromiseResult FindStoragePromiserObjects(EvalContext *ctx, Promise *pp)
{
/* Check if we are searching over a regular expression */

    return LocateFilePromiserGroup(ctx, pp->promiser, pp, VerifyStoragePromise);
}
Example #5
0
static void FindStoragePromiserObjects(EvalContext *ctx, Promise *pp, const ReportContext *report_context)
{
/* Check if we are searching over a regular expression */

    LocateFilePromiserGroup(ctx, pp->promiser, pp, VerifyStoragePromise, report_context);
}
Example #6
0
static void VerifyOccurrencePromises(Promise *pp)
{
    Attributes a = { {0} };
    char name[CF_BUFSIZE];
    enum representations rep_type;
    Rlist *contexts, *rp;

    a = GetOccurrenceAttributes(pp);

    if (a.rep_type)
    {
        rep_type = String2Representation(a.rep_type);
    }
    else
    {
        rep_type = cfk_url;
    }

    if (a.represents == NULL)
    {
        if (rep_type == cfk_literal)
        {
            CfOut(cf_error, "", " ! Occurrence of text information \"%s\" does not promise any topics to represent",
                  pp->promiser);
        }
        else
        {
            CfOut(cf_error, "",
                  " ! Occurrence or reference to information \"%s\" does not promise any topics to represent",
                  pp->promiser);
        }
        return;
    }

    contexts = SplitContextExpression(pp->classes, pp);

    for (rp = contexts; rp != NULL; rp = rp->next)
    {
        CfOut(cf_verbose, "", " -> New occurrence promise for \"%s\" about context \"%s\"", pp->promiser,
              ScalarValue(rp));

        switch (rep_type)
        {
        case cfk_file:

            if (a.web_root == NULL || a.path_root == NULL)
            {
                CfOut(cf_error, "", " !! File pattern but no complete url mapping path_root -> web_root");
                return;
            }

            strncpy(name, a.path_root, CF_BUFSIZE - 1);

            if (!JoinPath(name, pp->promiser))
            {
                CfOut(cf_error, "", " !! Unable to form pathname in search for local files");
                return;
            }

            // FIXME - this should pass rp->item instead of pp->classes if we want to keep this

            LocateFilePromiserGroup(name, pp, VerifyOccurrenceGroup);
            break;

        default:

            AddOccurrence(&OCCURRENCES, pp->promiser, a.represents, rep_type, rp->item);
            break;
        }
    }

    DeleteRlist(contexts);
}