Example #1
0
static Auth *GetAuthPath(const char *path, Auth *list)
{
    size_t path_len = strlen(path);
    char unslashed_path[path_len + 1];
    memcpy(unslashed_path, path, path_len + 1);

#ifdef __MINGW32__
    ToLowerStrInplace(unslashed_path);
#endif

    if (path_len != 1)
    {
        DeleteSlash(unslashed_path);
    }

    for (Auth *ap = list; ap != NULL; ap = ap->next)
    {
        if (strcmp(ap->path, unslashed_path) == 0)
        {
            return ap;
        }
    }

    return NULL;
}
Example #2
0
static Auth *GetAuthPath(const char *path, Auth *list)
{
    Auth *ap;

    char *unslashed_path = xstrdup(path);

#ifdef __MINGW32__
    int i;

    for (i = 0; unslashed_path[i] != '\0'; i++)
    {
        unslashed_path[i] = ToLower(unslashed_path[i]);
    }
#endif /* __MINGW32__ */    

    if (strlen(unslashed_path) != 1)
    {
        DeleteSlash(unslashed_path);
    }

    for (ap = list; ap != NULL; ap = ap->next)
    {
        if (strcmp(ap->path, unslashed_path) == 0)
        {
            free(unslashed_path);
            return ap;
        }
    }

    free(unslashed_path);
    return NULL;
}
Example #3
0
Auth *GetAuthPath(char *path, Auth *list)
{
    Auth *ap;

#ifdef MINGW
    int i;

    for (i = 0; path[i] != '\0'; i++)
    {
        path[i] = ToLower(path[i]);
    }
#endif /* MINGW */

    if (strlen(path) != 1)
    {
        DeleteSlash(path);
    }

    for (ap = list; ap != NULL; ap = ap->next)
    {
        if (strcmp(ap->path, path) == 0)
        {
            return ap;
        }
    }

    return NULL;
}
Example #4
0
static void VerifyOccurrenceGroup(char *file, Promise *pp)
{
    Attributes a = { {0} };
    struct stat sb;
    char *sp, url[CF_BUFSIZE];
    Rval retval;

    a = GetOccurrenceAttributes(pp);

    if (cfstat(file, &sb) == -1)
    {
        CfOut(cf_verbose, "", " !! File %s matched but could not be read", file);
        return;
    }

    if (a.path_root == NULL || a.web_root == NULL)
    {
        CfOut(cf_error, "", " !! No pathroot/webroot defined in representation");
        PromiseRef(cf_error, pp);
        return;
    }

    Chop(a.path_root);
    DeleteSlash(a.path_root);
    sp = file + strlen(a.path_root) + 1;

    FullTextMatch(pp->promiser, sp);
    retval = ExpandPrivateRval("this", (Rval) {a.represents, CF_LIST});
    DeleteScope("match");

    if (strlen(a.web_root) > 0)
    {
        snprintf(url, CF_BUFSIZE - 1, "%s/%s", a.web_root, sp);
    }
    else
    {
        snprintf(url, CF_BUFSIZE - 1, "%s", sp);
    }

    AddOccurrence(&OCCURRENCES, url, retval.item, cfk_url, pp->classes);
    CfOut(cf_verbose, "", " -> File %s matched and being logged at %s", file, url);

    DeleteRlist((Rlist *) retval.item);
}
Example #5
0
/**
 * @TODO fix the dangerous path lengths
 */
char *JoinSuffix(char *path, const char *leaf)
{
    int len = strlen(leaf);

    if (Chop(path, CF_EXPANDSIZE) == -1)
    {
        Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator");
    }
    DeleteSlash(path);

    if ((strlen(path) + len) > (CF_BUFSIZE - CF_BUFFERMARGIN))
    {
        Log(LOG_LEVEL_ERR, "Internal limit 2: Buffer ran out of space constructing string. Tried to add %s to %s",
              leaf, path);
        return NULL;
    }

    strcat(path, leaf);
    return path;
}
Example #6
0
char *JoinSuffix(char *path, size_t path_size, const char *leaf)
{
    int len = strlen(leaf);

    if (Chop(path, path_size) == -1)
    {
        Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator");
    }
    DeleteSlash(path);

    if (strlen(path) + len + 1 > path_size)
    {
        Log(LOG_LEVEL_ERR, "JoinSuffix: Internal limit reached. Tried to add %s to %s",
              leaf, path);
        return NULL;
    }

    strlcat(path, leaf, path_size);
    return path;
}
Example #7
0
int ExpandLinks(char *dest, const char *from, int level)
{
    char buff[CF_BUFSIZE];
    char node[CF_MAXLINKSIZE];
    struct stat statbuf;
    int lastnode = false;

    memset(dest, 0, CF_BUFSIZE);

    if (level >= CF_MAXLINKLEVEL)
    {
        Log(LOG_LEVEL_ERR, "Too many levels of symbolic links to evaluate absolute path");
        return false;
    }

    const char *sp = from;

    while (*sp != '\0')
    {
        if (*sp == FILE_SEPARATOR)
        {
            sp++;
            continue;
        }

        sscanf(sp, "%[^/]", node);
        sp += strlen(node);

        if (*sp == '\0')
        {
            lastnode = true;
        }

        if (strcmp(node, ".") == 0)
        {
            continue;
        }

        if (strcmp(node, "..") == 0)
        {
            continue;
        }
        else
        {
            strcat(dest, "/");
        }

        strcat(dest, node);

        if (lstat(dest, &statbuf) == -1)        /* File doesn't exist so we can stop here */
        {
            Log(LOG_LEVEL_ERR, "Can't stat '%s' in ExpandLinks. (lstat: %s)", dest, GetErrorStr());
            return false;
        }

        if (S_ISLNK(statbuf.st_mode))
        {
            memset(buff, 0, CF_BUFSIZE);

            if (readlink(dest, buff, CF_BUFSIZE - 1) == -1)
            {
                Log(LOG_LEVEL_ERR, "Expand links can't stat '%s'. (readlink: %s)", dest, GetErrorStr());
                return false;
            }
            else
            {
                if (buff[0] == '.')
                {
                    ChopLastNode(dest);

                    AddSlash(dest);

                    if (!JoinPath(dest, buff))
                    {
                        return false;
                    }
                }
                else if (IsAbsoluteFileName(buff))
                {
                    strcpy(dest, buff);
                    DeleteSlash(dest);

                    if (strcmp(dest, from) == 0)
                    {
                        Log(LOG_LEVEL_DEBUG, "No links to be expanded");
                        return true;
                    }

                    if ((!lastnode) && (!ExpandLinks(buff, dest, level + 1)))
                    {
                        return false;
                    }
                }
                else
                {
                    ChopLastNode(dest);
                    AddSlash(dest);
                    strcat(dest, buff);
                    DeleteSlash(dest);

                    if (strcmp(dest, from) == 0)
                    {
                        Log(LOG_LEVEL_DEBUG, "No links to be expanded");
                        return true;
                    }

                    memset(buff, 0, CF_BUFSIZE);

                    if ((!lastnode) && (!ExpandLinks(buff, dest, level + 1)))
                    {
                        return false;
                    }
                }
            }
        }
    }

    return true;
}
Example #8
0
static void KeepFileAccessPromise(const EvalContext *ctx, const Promise *pp)
{
    char path[PATH_MAX];
    size_t path_len = strlen(pp->promiser);
    if (path_len > sizeof(path) - 1)
    {
        goto err_too_long;
    }
    memcpy(path, pp->promiser, path_len + 1);

    /* Resolve symlinks and canonicalise access_rules path. */
    size_t ret2 = PreprocessRequestPath(path, sizeof(path));

    if (ret2 == (size_t) -1)
    {
        if (errno != ENOENT)                        /* something went wrong */
        {
            Log(LOG_LEVEL_ERR,
                "Failed to canonicalize path '%s' in access_rules, ignoring!",
                pp->promiser);
            return;
        }
        else                      /* file does not exist, it doesn't matter */
        {
            Log(LOG_LEVEL_INFO,
                "Path does not exist, it's added as-is in access rules: %s",
                path);
            Log(LOG_LEVEL_INFO,
                "WARNING: this means that (not) having a trailing slash defines if it's (not) a directory!");
            /* Legacy: convert trailing "/." to "/" */
            if (path_len >= 2 &&
                path[path_len - 1] == '.' &&
                path[path_len - 2] == '/')
            {
                path[path_len - 1] = '\0';
                path_len--;
            }
        }
    }
    else                                 /* file exists, path canonicalised */
    {
        /* If it's a directory append trailing '/' */
        path_len = ret2;
        int is_dir = IsDirReal(path);
        if (is_dir == 1 && path[path_len - 1] != FILE_SEPARATOR)
        {
            if (path_len + 2 > sizeof(path))
            {
                goto err_too_long;
            }
            PathAppendTrailingSlash(path, path_len);
            path_len++;
        }
    }

    size_t pos = acl_SortedInsert(&paths_acl, path);
    if (pos == (size_t) -1)
    {
        /* Should never happen, besides when allocation fails. */
        Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr());
        exit(255);
    }

    /* Legacy code */
    if (path_len != 1)
    {
        DeleteSlash(path);
    }
    Auth *ap = GetOrCreateAuth(path, &SV.admit, &SV.admittail);
    Auth *dp = GetOrCreateAuth(path, &SV.deny, &SV.denytail);

    AccessPromise_AddAccessConstraints(ctx, pp, &paths_acl->acls[pos],
                                       ap, dp);
    return;

  err_too_long:
    Log(LOG_LEVEL_ERR,
        "Path '%s' in access_rules is too long (%zu > %d), ignoring!",
        pp->promiser, strlen(pp->promiser), PATH_MAX);
    return;
}
Example #9
0
bool MakeParentDirectory(const char *parentandchild, bool force)
{
    char *spc, *sp;
    char currentpath[CF_BUFSIZE];
    char pathbuf[CF_BUFSIZE];
    struct stat statbuf;
    mode_t mask;
    int rootlen;
    char Path_File_Separator;

#ifdef __APPLE__
/* Keeps track of if dealing w. resource fork */
    int rsrcfork;

    rsrcfork = 0;

    char *tmpstr;
#endif

    Log(LOG_LEVEL_DEBUG, "Trying to create a parent directory for '%s%s'", parentandchild, force ? " (force applied)" : "");

    if (!IsAbsoluteFileName(parentandchild))
    {
        Log(LOG_LEVEL_ERR, "Will not create directories for a relative filename '%s'. Has no invariant meaning",
              parentandchild);
        return false;
    }

    strncpy(pathbuf, parentandchild, CF_BUFSIZE - 1);   /* local copy */

#ifdef __APPLE__
    if (strstr(pathbuf, _PATH_RSRCFORKSPEC) != NULL)
    {
        rsrcfork = 1;
    }
#endif

/* skip link name */
/* This cast is necessary, as  you can't have (char* -> char*)
   and (const char* -> const char*) functions in C */
    sp = (char *) LastFileSeparator(pathbuf);

    if (sp == NULL)
    {
        sp = pathbuf;
    }
    *sp = '\0';

    DeleteSlash(pathbuf);

    if (lstat(pathbuf, &statbuf) != -1)
    {
        if (S_ISLNK(statbuf.st_mode))
        {
            Log(LOG_LEVEL_VERBOSE, "INFO: %s is a symbolic link, not a true directory!", pathbuf);
        }

        if (force)              /* force in-the-way directories aside */
        {
            struct stat dir;

            stat(pathbuf, &dir);

            if (!S_ISDIR(dir.st_mode))  /* if the dir exists - no problem */
            {
                struct stat sbuf;

                if (DONTDO)
                {
                    return true;
                }

                strcpy(currentpath, pathbuf);
                DeleteSlash(currentpath);
                strcat(currentpath, ".cf-moved");
                Log(LOG_LEVEL_INFO, "Moving obstructing file/link %s to %s to make directory", pathbuf, currentpath);

                /* If cfagent, remove an obstructing backup object */

                if (lstat(currentpath, &sbuf) != -1)
                {
                    if (S_ISDIR(sbuf.st_mode))
                    {
                        DeleteDirectoryTree(currentpath);
                    }
                    else
                    {
                        if (unlink(currentpath) == -1)
                        {
                            Log(LOG_LEVEL_INFO, "Couldn't remove file/link '%s' while trying to remove a backup. (unlink: %s)",
                                  currentpath, GetErrorStr());
                        }
                    }
                }

                /* And then move the current object out of the way... */

                if (rename(pathbuf, currentpath) == -1)
                {
                    Log(LOG_LEVEL_INFO, "Warning: The object '%s' is not a directory. (rename: %s)", pathbuf, GetErrorStr());
                    return false;
                }
            }
        }
        else
        {
            if (!S_ISLNK(statbuf.st_mode) && !S_ISDIR(statbuf.st_mode))
            {
                Log(LOG_LEVEL_INFO,
                      "The object %s is not a directory. Cannot make a new directory without deleting it.", pathbuf);
                return false;
            }
        }
    }

/* Now we can make a new directory .. */

    currentpath[0] = '\0';

    rootlen = RootDirLength(parentandchild);
    strncpy(currentpath, parentandchild, rootlen);

    for (sp = (char*) parentandchild + rootlen, spc = currentpath + rootlen; *sp != '\0'; sp++)
    {
        if (!IsFileSep(*sp) && *sp != '\0')
        {
            *spc = *sp;
            spc++;
        }
        else
        {
            Path_File_Separator = *sp;
            *spc = '\0';

            if (strlen(currentpath) == 0)
            {
            }
            else if (stat(currentpath, &statbuf) == -1)
            {
                if (!DONTDO)
                {
                    mask = umask(0);

                    if (mkdir(currentpath, DEFAULTMODE) == -1)
                    {
                        Log(LOG_LEVEL_ERR, "Unable to make directories to '%s'. (mkdir: %s)", parentandchild, GetErrorStr());
                        umask(mask);
                        return false;
                    }
                    umask(mask);
                }
            }
            else
            {
                if (!S_ISDIR(statbuf.st_mode))
                {
#ifdef __APPLE__
                    /* Ck if rsrc fork */
                    if (rsrcfork)
                    {
                        tmpstr = xmalloc(CF_BUFSIZE);
                        strncpy(tmpstr, currentpath, CF_BUFSIZE);
                        strncat(tmpstr, _PATH_FORKSPECIFIER, CF_BUFSIZE);

                        /* CFEngine removed terminating slashes */
                        DeleteSlash(tmpstr);

                        if (strncmp(tmpstr, pathbuf, CF_BUFSIZE) == 0)
                        {
                            free(tmpstr);
                            return true;
                        }
                        free(tmpstr);
                    }
#endif

                    Log(LOG_LEVEL_ERR, "Cannot make %s - %s is not a directory! (use forcedirs=true)", pathbuf,
                          currentpath);
                    return false;
                }
            }

            /* *spc = FILE_SEPARATOR; */
            *spc = Path_File_Separator;
            spc++;
        }
    }

    Log(LOG_LEVEL_DEBUG, "Directory for '%s' exists. Okay", parentandchild);
    return true;
}
Example #10
0
void KeepFileAccessPromise(EvalContext *ctx, Promise *pp)
{
    Rlist *rp;
    Auth *ap, *dp;

    if (strlen(pp->promiser) != 1)
    {
        DeleteSlash(pp->promiser);
    }

    if (!GetAuthPath(pp->promiser, SV.admit))
    {
        InstallServerAuthPath(pp->promiser, &SV.admit, &SV.admittop);
    }

    if (!GetAuthPath(pp->promiser, SV.deny))
    {
        InstallServerAuthPath(pp->promiser, &SV.deny, &SV.denytop);
    }

    ap = GetAuthPath(pp->promiser, SV.admit);
    dp = GetAuthPath(pp->promiser, SV.deny);

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

        if (!IsDefinedClass(ctx, cp->classes, PromiseGetNamespace(pp)))
        {
            continue;
        }

        switch (cp->rval.type)
        {
        case RVAL_TYPE_SCALAR:

            if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_ENCRYPTED].lval) == 0)
            {
                ap->encrypt = true;
            }

            break;

        case RVAL_TYPE_LIST:

            for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next)
            {
                if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_ADMIT].lval) == 0)
                {
                    PrependItem(&(ap->accesslist), rp->item, NULL);
                    continue;
                }

                if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_DENY].lval) == 0)
                {
                    PrependItem(&(dp->accesslist), rp->item, NULL);
                    continue;
                }

                if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_MAPROOT].lval) == 0)
                {
                    PrependItem(&(ap->maproot), rp->item, NULL);
                    continue;
                }
            }
            break;

        default:
            /* Shouldn't happen */
            break;
        }
    }
}
Example #11
0
File: link.c Project: kbarber/cfng
/* should return true if 'to' found */
int
LinkFiles(char *from,char *to_tmp,
        struct Item *inclusions,struct Item *exclusions,struct Item *copy,
        short nofile,struct Link *ptr)
{
    struct stat buf,savebuf;
    char to[CF_BUFSIZE], linkbuf[CF_BUFSIZE];
    char saved[CF_BUFSIZE],absto[CF_BUFSIZE],*lastnode;
    struct UidList fakeuid;
    struct Image ip;
    char stamp[CF_BUFSIZE];
    time_t STAMPNOW;
    STAMPNOW = time((time_t *)NULL);

    memset(to,0,CF_BUFSIZE);
    memset(&ip,0, sizeof(ip));

    /* links without a directory reference */
    if ((*to_tmp != '/') && (*to_tmp != '.')) {
        strcpy(to,"./");
    }

    if (strlen(to_tmp)+3 > CF_BUFSIZE) {
        printf("%s: CF_BUFSIZE boundaries exceeded in LinkFiles(%s->%s)\n",
                g_vprefix,from,to_tmp);
        return false;
    }

    strcat(to,to_tmp);

    Debug2("Linkfiles(%s,%s)\n",from,to);

    for (lastnode = from+strlen(from); *lastnode != '/'; lastnode--) { }

    lastnode++;

    if (IgnoredOrExcluded(links,lastnode,inclusions,exclusions)) {
        Verbose("%s: Skipping non-included pattern %s\n",g_vprefix,from);
        return true;
    }

    if (IsWildItemIn(g_vcopylinks,lastnode) || IsWildItemIn(copy,lastnode)) {
        fakeuid.uid = CF_SAME_OWNER;
        fakeuid.next = NULL;
        ip.plus = CF_SAMEMODE;
        ip.minus = CF_SAMEMODE;
        ip.uid = &fakeuid;
        ip.gid = (struct GidList *) &fakeuid;
        ip.action = "do";
        ip.recurse = 0;
        ip.type = 't';
        ip.defines = ptr->defines;
        ip.elsedef = ptr->elsedef;
        ip.backup = true;
        ip.exclusions = NULL;
        ip.inclusions = NULL;
        ip.symlink = NULL;
        ip.classes = NULL;
        ip.plus_flags = 0;
        ip.size = CF_NOSIZE;
        ip.linktype = 's';
        ip.minus_flags = 0;
        ip.server = strdup("localhost");
        Verbose("%s: Link item %s marked for copying instead\n", 
                g_vprefix, from);
        MakeDirectoriesFor(to,'n');
        CheckImage(to,from,&ip);
        free(ip.server);
        return true;
    }

    /* relative path, must still check if exists */
    if (*to != '/') {
        Debug("Relative link destination detected: %s\n",to);
        strcpy(absto,AbsLinkPath(from,to));
        Debug("Absolute path to relative link = %s, from %s\n",absto,from);
    } else {
        strcpy(absto,to);
    }

    if (!nofile) {
        if (stat(absto,&buf) == -1) {
            /* no error warning, since the higher level routine uses this */
            return(false);
        }
    }

    Debug2("Trying to link %s -> %s (%s)\n",from,to,absto);

    if (lstat(from,&buf) == 0) {
        if (! S_ISLNK(buf.st_mode) && ! g_enforcelinks) {
            snprintf(g_output,CF_BUFSIZE*2,"Error linking %s -> %s\n",from,to);
            CfLog(cfsilent,g_output,"");

            snprintf(g_output, CF_BUFSIZE*2,
                    "Cannot make link: %s exists and is not a link! "
                    "(uid %d)\n", from, buf.st_uid);

            CfLog(cfsilent,g_output,"");
            return(true);
        }

        if (S_ISREG(buf.st_mode) && g_enforcelinks) {
            snprintf(g_output, CF_BUFSIZE*2, "Moving %s to %s%s\n",
                    from, from, CF_SAVED);
            CfLog(cfsilent,g_output,"");

            if (g_dontdo) {
                return true;
            }

            saved[0] = '\0';
            strcpy(saved,from);

            sprintf(stamp, "_%d_%s",
                    g_cfstarttime, CanonifyName(ctime(&STAMPNOW)));
            strcat(saved,stamp);

            strcat(saved,CF_SAVED);

            if (rename(from,saved) == -1) {
                snprintf(g_output, CF_BUFSIZE*2,
                        "Can't rename %s to %s\n", from,saved);
                CfLog(cferror,g_output,"rename");
                return(true);
            }

            if (Repository(saved,g_vrepository)) {
                unlink(saved);
            }
        }

        if (S_ISDIR(buf.st_mode) && g_enforcelinks) {
            snprintf(g_output,CF_BUFSIZE*2,"Moving directory %s to %s%s.dir\n",
                    from,from,CF_SAVED);
            CfLog(cfsilent,g_output,"");

            if (g_dontdo) {
                return true;
            }

            saved[0] = '\0';
            strcpy(saved,from);

            sprintf(stamp, "_%d_%s",
                    g_cfstarttime, CanonifyName(ctime(&STAMPNOW)));
            strcat(saved,stamp);

            strcat(saved,CF_SAVED);
            strcat(saved,".dir");

            if (stat(saved,&savebuf) != -1) {

                snprintf(g_output,CF_BUFSIZE*2,
                        "Couldn't save directory %s, "
                        "since %s exists already\n",
                        from,saved);

                CfLog(cferror,g_output,"");

                snprintf(g_output,CF_BUFSIZE*2,
                        "Unable to force link to "
                        "existing directory %s\n",from);

                CfLog(cferror,g_output,"");
                return true;
            }

            if (rename(from,saved) == -1) {
                snprintf(g_output, CF_BUFSIZE*2, 
                        "Can't rename %s to %s\n", from,saved);
                CfLog(cferror,g_output,"rename");
                return(true);
            }
        }
    }

    memset(linkbuf,0,CF_BUFSIZE);

    if (readlink(from,linkbuf,CF_BUFSIZE-1) == -1) {
        /* link doesn't exist */
        if (! MakeDirectoriesFor(from,'n')) {

            snprintf(g_output,CF_BUFSIZE*2,
                    "Couldn't build directory tree up to %s!\n",from);

            CfLog(cfsilent,g_output,"");

            snprintf(g_output,CF_BUFSIZE*2,
                    "One element was a plain file, not a directory!\n");

            CfLog(cfsilent,g_output,"");
            return(true);
        }
    } else {
        int off1 = 0, off2 = 0;

        DeleteSlash(linkbuf);

        /* Ignore ./ at beginning */
        if (strncmp(linkbuf,"./",2) == 0) {
            off1 = 2;
        }

        if (strncmp(to,"./",2) == 0) {
            off2 = 2;
        }

        if (strcmp(linkbuf+off1,to+off2) != 0) {
            if (g_enforcelinks) {
                snprintf(g_output,CF_BUFSIZE*2,"Removing link %s\n",from);
                CfLog(cfinform,g_output,"");

                if (!g_dontdo) {
                    if (unlink(from) == -1) {
                        perror("unlink");
                        return true;
                    }

                    return DoLink(from,to,ptr->defines);
                }
            } else {

                snprintf(g_output,CF_BUFSIZE*2,
                        "Old link %s points somewhere else. Doing nothing!\n",
                        from);

                CfLog(cfsilent,g_output,"");

                snprintf(g_output, CF_BUFSIZE*2,
                        "(Link points to %s not %s)\n\n",
                        linkbuf,to);

                CfLog(cfsilent,g_output,"");
                return(true);
            }
        } else {
            snprintf(g_output, CF_BUFSIZE*2,
                    "Link (%s->%s) exists.\n", from, to_tmp);
            CfLog(cfverbose,g_output,"");

            if (!nofile) {

                /* Check whether link points somewhere */
                KillOldLink(from,ptr->defines);

                return true;
            }

            AddMultipleClasses(ptr->elsedef);
            return(true);
        }
    }

    return DoLink(from,to,ptr->defines);
}
Example #12
0
File: link.c Project: kbarber/cfng
int
ExpandLinks(char *dest, char *from, int level)
{
    char *sp, buff[CF_BUFSIZE];
    char node[CF_MAXLINKSIZE];
    struct stat statbuf;
    int lastnode = false;

    memset(dest,0,CF_BUFSIZE);

    Debug2("ExpandLinks(%s,%d)\n",from,level);

    if (level >= CF_MAXLINKLEVEL) {

        CfLog(cferror,
            "Too many levels of symbolic links to evaluate "
            "absolute path\n","");

        return false;
    }

    for (sp = from; *sp != '\0'; sp++) {
        if (*sp == '/') {
            continue;
        }

        sscanf(sp,"%[^/]",node);
        sp += strlen(node);

        if (*sp == '\0') {
            lastnode = true;
            }

        if (strcmp(node,".") == 0) {
            continue;
        }

        if (strcmp(node,"..") == 0) {
            if (! ChopLastNode(g_linkto)) {
                Debug("cfagent: used .. beyond top of filesystem!\n");
                return false;
            }
            continue;
        } else {
            strcat(dest,"/");
        }
        strcat(dest,node);

        /* File doesn't exist so we can stop here */
        if (lstat(dest,&statbuf) == -1) {
            snprintf(g_output, CF_BUFSIZE*2,
                    "Can't stat %s in ExpandLinks\n", dest);
            CfLog(cferror,g_output,"stat");
            return false;
        }

        if (S_ISLNK(statbuf.st_mode)) {
            memset(buff,0,CF_BUFSIZE);

            if (readlink(dest,buff,CF_BUFSIZE-1) == -1) {
                snprintf(g_output, CF_BUFSIZE*2,
                        "Expand links can't stat %s\n", dest);
                CfLog(cferror,g_output,"readlink");
                return false;
            } else {
                if (buff[0] == '.') {

                    ChopLastNode(dest);
                    AddSlash(dest);

                    if (BufferOverflow(dest,buff)) {
                        return false;
                    }
                    strcat(dest,buff);
                }
                else if (buff[0] == '/') {
                    strcpy(dest,buff);
                    DeleteSlash(dest);

                    if (strcmp(dest,from) == 0) {
                        Debug2("No links to be expanded\n");
                        return true;
                    }

                    if (!lastnode && !ExpandLinks(buff,dest,level+1)) {
                        return false;
                    }
                } else {
                    ChopLastNode(dest);
                    AddSlash(dest);
                    strcat(dest,buff);
                    DeleteSlash(dest);

                    if (strcmp(dest,from) == 0) {
                        Debug2("No links to be expanded\n");
                        return true;
                    }

                    memset(buff,0,CF_BUFSIZE);

                    if (!lastnode && !ExpandLinks(buff,dest,level+1)) {
                        return false;
                    }
                }
            }
        }
    }
    return true;
}
Example #13
0
int MakeDirectoriesFor(char *file,char force)  /* Make all directories which underpin file */

{ char *sp,*spc;
  char currentpath[CF_BUFSIZE];
  char pathbuf[CF_BUFSIZE];
  struct stat statbuf;
  mode_t mask;
  int rootlen;
  char Path_File_Separator;
    
#ifdef DARWIN
/* Keeps track of if dealing w. resource fork */
int rsrcfork;
rsrcfork = 0;

char * tmpstr;
#endif    
    
if (!IsAbsoluteFileName(file))
   {
   snprintf(OUTPUT,CF_BUFSIZE*2,"Will not create directories for a relative filename (%s). Has no invariant meaning\n",file);
   CfLog(cferror,OUTPUT,"");
   return false;
   }

strncpy(pathbuf,file,CF_BUFSIZE-1);                                      /* local copy */


#ifdef DARWIN
/* Dealing w. a rsrc fork? */
if (strstr(pathbuf, _PATH_RSRCFORKSPEC) != NULL)
   {
   rsrcfork = 1;
   }
#endif

/* skip link name */
 sp = LastFileSeparator(pathbuf);
 if (sp == NULL)
    {
    sp = pathbuf;
    }
 *sp = '\0';
 
 DeleteSlash(pathbuf); 
 
 if (lstat(pathbuf,&statbuf) != -1)
    {
    if (S_ISLNK(statbuf.st_mode))
       {
       Verbose("%s: INFO: %s is a symbolic link, not a true directory!\n",VPREFIX,pathbuf);
       }
    
    if (force == 'y')   /* force in-the-way directories aside */
       {
       if (!S_ISDIR(statbuf.st_mode))  /* if the dir exists - no problem */
          {
          if (ISCFENGINE)
             {
             struct Tidy tp;
             struct TidyPattern tpat;
             struct stat sbuf;

             if (DONTDO)
                {
                return true;
                }
             
             strcpy(currentpath,pathbuf);
             DeleteSlash(currentpath);
             strcat(currentpath,".cf-moved");
             snprintf(OUTPUT,CF_BUFSIZE,"Moving obstructing file/link %s to %s to make directory",pathbuf,currentpath);
             CfLog(cferror,OUTPUT,"");
             
             /* If cfagent, remove an obstructing backup object */
             
             if (lstat(currentpath,&sbuf) != -1)
                {
                if (S_ISDIR(sbuf.st_mode))
                   {
                   tp.maxrecurse = 2;
                   tp.tidylist = &tpat;
                   tp.next = NULL;
                   tp.path = currentpath;
                   
                   tpat.recurse = CF_INF_RECURSE;
                   tpat.age = 0;
                   tpat.size = 0;
                   tpat.pattern = strdup("*");
                   tpat.classes = strdup("any");
                   tpat.defines = NULL;
                   tpat.elsedef = NULL;
                   tpat.dirlinks = 'y';
                   tpat.travlinks = 'n';
                   tpat.rmdirs = 'y';
                   tpat.searchtype = 'a';
                   tpat.log = 'd';
                   tpat.inform = 'd';
                   tpat.next = NULL;
//                   RecursiveTidySpecialArea(currentpath,&tp,CF_INF_RECURSE,&sbuf);
                   free(tpat.pattern);
                   free(tpat.classes);
                   
                   if (rmdir(currentpath) == -1)
                      {
                      snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't remove directory %s while trying to remove a backup\n",currentpath);
                      CfLog(cfinform,OUTPUT,"rmdir");
                      }
                   }
                else
                   {
                   if (unlink(currentpath) == -1)
                      {
                      snprintf(OUTPUT,CF_BUFSIZE*2,"Couldn't remove file/link %s while trying to remove a backup\n",currentpath);
                      CfLog(cfinform,OUTPUT,"rmdir");
                      }
                   }
                }
             
             /* And then move the current object out of the way...*/
             
             if (rename(pathbuf,currentpath) == -1)
                {
                snprintf(OUTPUT,CF_BUFSIZE*2,"Warning. The object %s is not a directory.\n",pathbuf);
                CfLog(cfinform,OUTPUT,"");
                CfLog(cfinform,"Could not make a new directory or move the block","rename");
                return(false);
                }
             }
          }
       else
          {
          if (! S_ISLNK(statbuf.st_mode) && ! S_ISDIR(statbuf.st_mode))
             {
             snprintf(OUTPUT,CF_BUFSIZE*2,"Warning. The object %s is not a directory.\n",pathbuf);
             CfLog(cfinform,OUTPUT,"");
             CfLog(cfinform,"Cannot make a new directory without deleting it!\n\n","");
             return(false);
             }
          }
       }
    }
 
/* Now we can make a new directory .. */ 
 
 currentpath[0] = '\0';
 
 rootlen = RootDirLength(sp);
 strncpy(currentpath, file, rootlen);

 for (sp = file+rootlen, spc = currentpath+rootlen; *sp != '\0'; sp++)
    {
    if (!IsFileSep(*sp) && *sp != '\0')
       {
       *spc = *sp;
       spc++;
       }
    else
       {
       Path_File_Separator = *sp;
       *spc = '\0';
       
       if (strlen(currentpath) == 0)
          {
          }
       else if (stat(currentpath,&statbuf) == -1)
          {
          Debug2("cfengine: Making directory %s, mode %o\n",currentpath,DEFAULTMODE);
          
          if (! DONTDO)
             {
             mask = umask(0);
             
             if (mkdir(currentpath,DEFAULTMODE) == -1)
                {
                snprintf(OUTPUT,CF_BUFSIZE*2,"Unable to make directories to %s\n",file);
                CfLog(cferror,OUTPUT,"mkdir");
                umask(mask);
                return(false);
                }
             umask(mask);
             }
          }
       else
          {
          if (! S_ISDIR(statbuf.st_mode))
             {
#ifdef DARWIN
             /* Ck if rsrc fork */
             if (rsrcfork)
                {
                tmpstr = malloc(CF_BUFSIZE);
                strncpy(tmpstr, currentpath, CF_BUFSIZE);
                strncat(tmpstr, _PATH_FORKSPECIFIER, CF_BUFSIZE);
                
                /* Cfengine removed terminating slashes */
                DeleteSlash(tmpstr);
                
                if (strncmp(tmpstr, pathbuf, CF_BUFSIZE) == 0)
                   {
                   free(tmpstr);
                   return(true);
                   }
                free(tmpstr);
                }
#endif
             
             snprintf(OUTPUT,CF_BUFSIZE*2,"Cannot make %s - %s is not a directory! (use forcedirs=true)\n",pathbuf,currentpath);
             CfLog(cferror,OUTPUT,"");
             return(false);
             }
          }
       
       /* *spc = FILE_SEPARATOR; */
       *spc = Path_File_Separator;
       spc++;
       }
    }
 
 Debug("Directory for %s exists. Okay\n",file);
 return(true);
}
Example #14
0
void KeepFileAccessPromise(Promise *pp)
{
    Constraint *cp;
    Rlist *rp;
    Auth *ap, *dp;

    if (strlen(pp->promiser) != 1)
    {
        DeleteSlash(pp->promiser);
    }

    if (!GetAuthPath(pp->promiser, VADMIT))
    {
        InstallServerAuthPath(pp->promiser, &VADMIT, &VADMITTOP);
    }

    if (!GetAuthPath(pp->promiser, VDENY))
    {
        InstallServerAuthPath(pp->promiser, &VDENY, &VDENYTOP);
    }

    ap = GetAuthPath(pp->promiser, VADMIT);
    dp = GetAuthPath(pp->promiser, VDENY);

    for (cp = pp->conlist; cp != NULL; cp = cp->next)
    {
        if (!IsDefinedClass(cp->classes))
        {
            continue;
        }

        switch (cp->rval.rtype)
        {
        case CF_SCALAR:

            if (strcmp(cp->lval, CF_REMACCESS_BODIES[cfs_encrypted].lval) == 0)
            {
                ap->encrypt = true;
            }

            break;

        case CF_LIST:

            for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next)
            {
                if (strcmp(cp->lval, CF_REMACCESS_BODIES[cfs_admit].lval) == 0)
                {
                    PrependItem(&(ap->accesslist), rp->item, NULL);
                    continue;
                }

                if (strcmp(cp->lval, CF_REMACCESS_BODIES[cfs_deny].lval) == 0)
                {
                    PrependItem(&(dp->accesslist), rp->item, NULL);
                    continue;
                }

                if (strcmp(cp->lval, CF_REMACCESS_BODIES[cfs_maproot].lval) == 0)
                {
                    PrependItem(&(ap->maproot), rp->item, NULL);
                    continue;
                }
            }
            break;

        case CF_FNCALL:
            /* Shouldn't happen */
            break;
        }
    }
}
Example #15
0
bool MakeParentDirectory(const char *parentandchild, bool force)
{
    char *sp;
    char currentpath[CF_BUFSIZE];
    char pathbuf[CF_BUFSIZE];
    struct stat statbuf;
    mode_t mask;
    int rootlen;

#ifdef __APPLE__
/* Keeps track of if dealing w. resource fork */
    int rsrcfork;

    rsrcfork = 0;

    char *tmpstr;
#endif

    Log(LOG_LEVEL_DEBUG, "Trying to create a parent directory%s for: %s",
        force ? " (force applied)" : "",
        parentandchild);

    if (!IsAbsoluteFileName(parentandchild))
    {
        Log(LOG_LEVEL_ERR,
            "Will not create directories for a relative filename: %s",
            parentandchild);
        return false;
    }

    strlcpy(pathbuf, parentandchild, CF_BUFSIZE);   /* local copy */

#ifdef __APPLE__
    if (strstr(pathbuf, _PATH_RSRCFORKSPEC) != NULL)
    {
        rsrcfork = 1;
    }
#endif

/* skip link name */

    sp = (char *) LastFileSeparator(pathbuf);                /* de-constify */

    if (sp == NULL)
    {
        sp = pathbuf;
    }
    *sp = '\0';

    DeleteSlash(pathbuf);

    if (lstat(pathbuf, &statbuf) != -1)
    {
        if (S_ISLNK(statbuf.st_mode))
        {
            Log(LOG_LEVEL_VERBOSE, "'%s' is a symbolic link, not a directory",
                pathbuf);
        }

        if (force)              /* force in-the-way directories aside */
        {
            struct stat dir;
            stat(pathbuf, &dir);

            /* If the target directory exists as a directory, no problem. */
            /* If the target directory exists but is not a directory, then
             * rename it to ".cf-moved": */
            if (!S_ISDIR(dir.st_mode))
            {
                struct stat sbuf;

                if (DONTDO)
                {
                    return true;
                }

                strcpy(currentpath, pathbuf);
                DeleteSlash(currentpath);
                /* TODO overflow check! */
                strlcat(currentpath, ".cf-moved", sizeof(currentpath));
                Log(LOG_LEVEL_INFO,
                    "Moving obstructing file/link %s to %s to make directory",
                    pathbuf, currentpath);

                /* Remove possibly pre-existing ".cf-moved" backup object. */
                if (lstat(currentpath, &sbuf) != -1)
                {
                    if (S_ISDIR(sbuf.st_mode))                 /* directory */
                    {
                        DeleteDirectoryTree(currentpath);
                    }
                    else                                 /* not a directory */
                    {
                        if (unlink(currentpath) == -1)
                        {
                            Log(LOG_LEVEL_INFO, "Couldn't remove file/link"
                                " '%s' while trying to remove a backup"
                                " (unlink: %s)",
                                currentpath, GetErrorStr());
                        }
                    }
                }

                /* And then rename the current object to ".cf-moved". */
                if (rename(pathbuf, currentpath) == -1)
                {
                    Log(LOG_LEVEL_INFO,
                        "Couldn't rename '%s' to .cf-moved"
                        " (rename: %s)", pathbuf, GetErrorStr());
                    return false;
                }
            }
        }
        else
        {
            if (!S_ISLNK(statbuf.st_mode) && !S_ISDIR(statbuf.st_mode))
            {
                Log(LOG_LEVEL_INFO, "The object '%s' is not a directory."
                    " Cannot make a new directory without deleting it.",
                    pathbuf);
                return false;
            }
        }
    }

/* Now we make directories descending from the root folder down to the leaf */

    currentpath[0] = '\0';

    rootlen = RootDirLength(parentandchild);
    /* currentpath is not NULL terminated on purpose! */
    strncpy(currentpath, parentandchild, rootlen);

    for (size_t z = rootlen; parentandchild[z] != '\0'; z++)
    {
        const char c = parentandchild[z];

        /* Copy up to the next separator. */
        if (!IsFileSep(c))
        {
            currentpath[z] = c;
            continue;
        }

        const char path_file_separator = c;
        currentpath[z]                 = '\0';

        /* currentpath is complete path for each of the parent directories.  */

        if (currentpath[0] == '\0')
        {
            /* We are at dir "/" of an absolute path, no need to create. */
        }
        /* WARNING: on Windows stat() fails if path has a trailing slash! */
        else if (stat(currentpath, &statbuf) == -1)
        {
            if (!DONTDO)
            {
                mask = umask(0);

                if (mkdir(currentpath, DEFAULTMODE) == -1)
                {
                    Log(LOG_LEVEL_ERR,
                        "Unable to make directory: %s (mkdir: %s)",
                        currentpath, GetErrorStr());
                    umask(mask);
                    return false;
                }
                umask(mask);
            }
        }
        else
        {
            if (!S_ISDIR(statbuf.st_mode))
            {
#ifdef __APPLE__
                /* Ck if rsrc fork */
                if (rsrcfork)
                {
                    tmpstr = xmalloc(CF_BUFSIZE);
                    strlcpy(tmpstr, currentpath, CF_BUFSIZE);
                    strncat(tmpstr, _PATH_FORKSPECIFIER, CF_BUFSIZE);

                    /* CFEngine removed terminating slashes */
                    DeleteSlash(tmpstr);

                    if (strncmp(tmpstr, pathbuf, CF_BUFSIZE) == 0)
                    {
                        free(tmpstr);
                        return true;
                    }
                    free(tmpstr);
                }
#endif

                Log(LOG_LEVEL_ERR,
                    "Cannot make %s - %s is not a directory!"
                    " (use forcedirs=true)", pathbuf, currentpath);
                return false;
            }
        }

        currentpath[z] = path_file_separator;
    }

    Log(LOG_LEVEL_DEBUG, "Directory for '%s' exists. Okay", parentandchild);
    return true;
}