Esempio n. 1
0
int
prociter(int (*proch)(pid_t pid, pid_t ppid, char *tmpname, void *data),
         void *data)
{
    char *name = NULL;
    DIR *d = NULL;
    struct dirent *de = NULL;
    struct dirent scratch[2] = {
        {
            0,
        },
    };
    pid_t pid = -1;
    pid_t ppid = -1;
    int ret = 0;

    d = sys_opendir(PROC);
    if (!d)
        return -1;

    for (;;) {
        errno = 0;
        de = sys_readdir(d, scratch);
        if (!de || errno != 0)
            break;

        if (gf_string2int(de->d_name, &pid) != -1 && pid >= 0) {
            ppid = pidinfo(pid, &name);
            switch (ppid) {
                case -1:
                    continue;
                case -2:
                    break;
            }
            ret = proch(pid, ppid, name, data);
            GF_FREE(name);
            if (ret)
                break;
        }
    }
    sys_closedir(d);
    if (!de && errno) {
        fprintf(stderr, "failed to traverse " PROC " (%s)\n", strerror(errno));
        ret = -1;
    }

    return ret;
}
Esempio n. 2
0
int
prociter (int (*proch) (pid_t pid, pid_t ppid, char *tmpname, void *data),
          void *data)
{
        char *name        = NULL;
        DIR *d            = NULL;
        struct dirent *de = NULL;
        pid_t pid         = -1;
        pid_t ppid        = -1;
        int ret           = 0;

        d = opendir (PROC);
        if (!d) {
                ret = -1;
                goto out;
        }
        while (errno = 0, de = readdir (d)) {
                if (gf_string2int (de->d_name, &pid) != -1 && pid >= 0) {
                        ppid = pidinfo (pid, &name);
                        switch (ppid) {
                        case -1: continue;
                        case -2: closedir (d); return -1;
                        }
                        ret = proch (pid, ppid, name, data);
                        if (ret) {
                                goto out;
                        }
                        GF_FREE (name);
                        name = NULL;
                }
        }
        if (errno) {
                fprintf (stderr, "failed to traverse "PROC" (%s)\n",
                         strerror (errno));
                goto out;
        }

        ret = 0;
out:
        if (d)
                closedir (d);

        if (name)
                GF_FREE (name);

        return ret;
}
Esempio n. 3
0
static int
invoke_rsync (int argc, char **argv)
{
        int i                  = 0;
        char path[PATH_MAX]    = {0,};
        pid_t pid              = -1;
        pid_t ppid             = -1;
        pid_t pida[]           = {-1, -1};
        char *name             = NULL;
        char buf[PATH_MAX + 1] = {0,};
        int ret                = 0;

        assert (argv[argc] == NULL);

        if (argc < 2 || strcmp (argv[1], "--server") != 0)
                goto error;

        for (i = 2; i < argc && argv[i][0] == '-'; i++);

        if (!(i == argc - 2 && strcmp (argv[i], ".") == 0 && argv[i + 1][0] == '/')) {
                fprintf (stderr, "need an rsync invocation without protected args\n");
                goto error;
        }

        /* look up sshd we are spawned from */
        for (pid = getpid () ;; pid = ppid) {
                ppid = pidinfo (pid, &name);
                if (ppid < 0) {
                        fprintf (stderr, "sshd ancestor not found\n");
                        goto error;
                }
                if (strcmp (name, "sshd") == 0) {
                        GF_FREE (name);
                        break;
                }
                GF_FREE (name);
        }
        /* look up "ssh-sibling" gsyncd */
        pida[0] = pid;
        ret = prociter (find_gsyncd, pida);
        if (ret == -1 || pida[1] == -1) {
                fprintf (stderr, "gsyncd sibling not found\n");
                goto error;
        }
        /* check if rsync target matches gsyncd target */
        sprintf (path, PROC"/%d/cwd", pida[1]);
        ret = readlink (path, buf, sizeof (buf));
        if (ret == -1 || ret == sizeof (buf))
                goto error;
        if (strcmp (argv[argc - 1], "/") == 0 /* root dir cannot be a target */ ||
            (strcmp (argv[argc - 1], path) /* match against gluster target */ &&
             strcmp (argv[argc - 1], buf) /* match against file target */) != 0) {
                fprintf (stderr, "rsync target does not match "GEOREP" session\n");
                goto error;
        }

        argv[0] = RSYNC;

        execvp (RSYNC, argv);

        fprintf (stderr, "exec of "RSYNC" failed\n");
        return 127;

 error:
        fprintf (stderr, "disallowed "RSYNC" invocation\n");
        return 1;
}