Example #1
0
static int Unix_cf_pclose(FILE *pp)
{
    int fd;
    pid_t pid;

    CfDebug("Unix_cf_pclose(pp)\n");

    if (!ThreadLock(cft_count))
    {
        return -1;
    }

    if (CHILDREN == NULL)       /* popen hasn't been called */
    {
        ThreadUnlock(cft_count);
        return -1;
    }

    ThreadUnlock(cft_count);

    ALARM_PID = -1;
    fd = fileno(pp);

    if (fd >= MAX_FD)
    {
        CfOut(cf_error, "",
              "File descriptor %d of child higher than MAX_FD in Unix_cf_pclose, check for defunct children", fd);
        pid = -1;
    }
    else
    {
        if ((pid = CHILDREN[fd]) == 0)
        {
            return -1;
        }

        ThreadLock(cft_count);
        CHILDREN[fd] = 0;
        ThreadUnlock(cft_count);
    }

    if (fclose(pp) == EOF)
    {
        return -1;
    }

    return cf_pwait(pid);
}
Example #2
0
int cf_pclose(FILE *pp)
{
    int fd = fileno(pp);
    pid_t pid;

    if (!ThreadLock(cft_count))
    {
        fclose(pp);
        return -1;
    }

    if (CHILDREN == NULL)       /* popen hasn't been called */
    {
        ThreadUnlock(cft_count);
        fclose(pp);
        return -1;
    }

    ALARM_PID = -1;

    if (fd >= MAX_FD)
    {
        ThreadUnlock(cft_count);
        Log(LOG_LEVEL_ERR,
            "File descriptor %d of child higher than MAX_FD in cf_pclose!",
            fd);
        pid = 0;
    }
    else
    {
        pid = CHILDREN[fd];
        CHILDREN[fd] = 0;
        ThreadUnlock(cft_count);
    }

    if (fclose(pp) == EOF || pid == 0)
    {
        return -1;
    }

    return cf_pwait(pid);
}
Example #3
0
static FILE *Unix_cf_popen_shsetuid(char *command, char *type, uid_t uid, gid_t gid, char *chdirv, char *chrootv)
{
    int i, pd[2];
    pid_t pid;
    FILE *pp = NULL;

    CfDebug("Unix_cf_popen_shsetuid(%s,%s,%d,%d)\n", command, type, uid, gid);

    if ((*type != 'r' && *type != 'w') || (type[1] != '\0'))
    {
        errno = EINVAL;
        return NULL;
    }

    if (!ThreadLock(cft_count))
    {
        return NULL;
    }

    if (CHILDREN == NULL)       /* first time */
    {
        CHILDREN = xcalloc(MAX_FD, sizeof(pid_t));
    }

    ThreadUnlock(cft_count);

    if (pipe(pd) < 0)           /* Create a pair of descriptors to this process */
    {
        return NULL;
    }

    if ((pid = fork()) == -1)
    {
        close(pd[0]);
        close(pd[1]);
        return NULL;
    }

    signal(SIGCHLD, SIG_DFL);
    ALARM_PID = (pid != 0 ? pid : -1);

    if (pid == 0)
    {
        switch (*type)
        {
        case 'r':

            close(pd[0]);       /* Don't need output from parent */

            if (pd[1] != 1)
            {
                dup2(pd[1], 1); /* Attach pp=pd[1] to our stdout */
                dup2(pd[1], 2); /* Merge stdout/stderr */
                close(pd[1]);
            }

            break;

        case 'w':

            close(pd[1]);

            if (pd[0] != 0)
            {
                dup2(pd[0], 0);
                close(pd[0]);
            }
        }

        for (i = 0; i < MAX_FD; i++)
        {
            if (CHILDREN[i] > 0)
            {
                close(i);
            }
        }

        if (chrootv && strlen(chrootv) != 0)
        {
            if (chroot(chrootv) == -1)
            {
                CfOut(cf_error, "chroot", "Couldn't chroot to %s\n", chrootv);
                return NULL;
            }
        }

        if (chdirv && strlen(chdirv) != 0)
        {
            if (chdir(chdirv) == -1)
            {
                CfOut(cf_error, "chdir", "Couldn't chdir to %s\n", chdirv);
                return NULL;
            }
        }

        if (!CfSetuid(uid, gid))
        {
            _exit(1);
        }

        execl(SHELL_PATH, "sh", "-c", command, NULL);
        _exit(1);
    }
    else
    {
        switch (*type)
        {
        case 'r':

            close(pd[1]);

            if ((pp = fdopen(pd[0], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
            break;

        case 'w':

            close(pd[0]);

            if ((pp = fdopen(pd[1], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
        }

        if (fileno(pp) >= MAX_FD)
        {
            CfOut(cf_error, "",
                  "File descriptor %d of child %d higher than MAX_FD in Unix_cf_popen_shsetuid, check for defunct children",
                  fileno(pp), pid);
            cf_pwait(pid);
            return NULL;
        }
        else
        {
            ThreadLock(cft_count);
            CHILDREN[fileno(pp)] = pid;
            ThreadUnlock(cft_count);
        }
        return pp;
    }

    return NULL;
}
Example #4
0
static FILE *Unix_cf_popen(char *command, char *type)
{
    int i, pd[2];
    char **argv;
    pid_t pid;
    FILE *pp = NULL;

    CfDebug("Unix_cf_popen(%s)\n", command);

    if ((*type != 'r' && *type != 'w') || (type[1] != '\0'))
    {
        errno = EINVAL;
        return NULL;
    }

    if (!ThreadLock(cft_count))
    {
        return NULL;
    }

    if (CHILDREN == NULL)       /* first time */
    {
        CHILDREN = xcalloc(MAX_FD, sizeof(pid_t));
    }

    ThreadUnlock(cft_count);

    if (pipe(pd) < 0)           /* Create a pair of descriptors to this process */
    {
        return NULL;
    }

    if ((pid = fork()) == -1)
    {
        close(pd[0]);
        close(pd[1]);
        return NULL;
    }

    signal(SIGCHLD, SIG_DFL);

    ALARM_PID = (pid != 0 ? pid : -1);

    if (pid == 0)
    {
        switch (*type)
        {
        case 'r':

            close(pd[0]);       /* Don't need output from parent */

            if (pd[1] != 1)
            {
                dup2(pd[1], 1); /* Attach pp=pd[1] to our stdout */
                dup2(pd[1], 2); /* Merge stdout/stderr */
                close(pd[1]);
            }

            break;

        case 'w':

            close(pd[1]);

            if (pd[0] != 0)
            {
                dup2(pd[0], 0);
                close(pd[0]);
            }
        }

        for (i = 0; i < MAX_FD; i++)
        {
            if (CHILDREN[i] > 0)
            {
                close(i);
            }
        }

        argv = ArgSplitCommand(command);

        if (execv(argv[0], argv) == -1)
        {
            CfOut(cf_error, "execv", "Couldn't run %s", argv[0]);
        }

        _exit(1);
    }
    else
    {
        switch (*type)
        {
        case 'r':

            close(pd[1]);

            if ((pp = fdopen(pd[0], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
            break;

        case 'w':

            close(pd[0]);

            if ((pp = fdopen(pd[1], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
        }

        if (fileno(pp) >= MAX_FD)
        {
            CfOut(cf_error, "",
                  "File descriptor %d of child %d higher than MAX_FD in Unix_cf_popen, check for defunct children",
                  fileno(pp), pid);
        }
        else
        {
            ThreadLock(cft_count);
            CHILDREN[fileno(pp)] = pid;
            ThreadUnlock(cft_count);
        }

        return pp;
    }

    return NULL;                /* Cannot reach here */
}
Example #5
0
FILE *cf_popen_shsetuid(const char *command, char *type, uid_t uid, gid_t gid, char *chdirv, char *chrootv, int background)
{
    int pd[2];
    pid_t pid;
    FILE *pp = NULL;

    CfDebug("cf_popen_shsetuid(%s,%s,%" PRIuMAX ",%" PRIuMAX ")\n", command, type, (uintmax_t)uid, (uintmax_t)gid);

    pid = CreatePipeAndFork(type, pd);
    if (pid == -1) {
        return NULL;
    }

    if (pid == 0)
    {
        switch (*type)
        {
        case 'r':

            close(pd[0]);       /* Don't need output from parent */

            if (pd[1] != 1)
            {
                dup2(pd[1], 1); /* Attach pp=pd[1] to our stdout */
                dup2(pd[1], 2); /* Merge stdout/stderr */
                close(pd[1]);
            }

            break;

        case 'w':

            close(pd[1]);

            if (pd[0] != 0)
            {
                dup2(pd[0], 0);
                close(pd[0]);
            }
        }

        CloseChildrenFD();

        if (chrootv && (strlen(chrootv) != 0))
        {
            if (chroot(chrootv) == -1)
            {
                CfOut(cf_error, "chroot", "Couldn't chroot to %s\n", chrootv);
                return NULL;
            }
        }

        if (chdirv && (strlen(chdirv) != 0))
        {
            if (chdir(chdirv) == -1)
            {
                CfOut(cf_error, "chdir", "Couldn't chdir to %s\n", chdirv);
                return NULL;
            }
        }

        if (!CfSetuid(uid, gid))
        {
            _exit(1);
        }

        execl(SHELL_PATH, "sh", "-c", command, NULL);
        _exit(1);
    }
    else
    {
        switch (*type)
        {
        case 'r':

            close(pd[1]);

            if ((pp = fdopen(pd[0], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
            break;

        case 'w':

            close(pd[0]);

            if ((pp = fdopen(pd[1], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
        }

        SetChildFD(fileno(pp), pid);
        return pp;
    }

    return NULL;
}
Example #6
0
FILE *cf_popen_sh(const char *command, char *type)
{
    int pd[2];
    pid_t pid;
    FILE *pp = NULL;

    CfDebug("cf_popen_sh(%s)\n", command);

    pid = CreatePipeAndFork(type, pd);
    if (pid == -1) {
        return NULL;
    }

    if (pid == 0)
    {
        switch (*type)
        {
        case 'r':

            close(pd[0]);       /* Don't need output from parent */

            if (pd[1] != 1)
            {
                dup2(pd[1], 1); /* Attach pp=pd[1] to our stdout */
                dup2(pd[1], 2); /* Merge stdout/stderr */
                close(pd[1]);
            }

            break;

        case 'w':

            close(pd[1]);

            if (pd[0] != 0)
            {
                dup2(pd[0], 0);
                close(pd[0]);
            }
        }

        CloseChildrenFD();

        execl(SHELL_PATH, "sh", "-c", command, NULL);
        _exit(1);
    }
    else
    {
        switch (*type)
        {
        case 'r':

            close(pd[1]);

            if ((pp = fdopen(pd[0], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
            break;

        case 'w':

            close(pd[0]);

            if ((pp = fdopen(pd[1], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
        }

        SetChildFD(fileno(pp), pid);
        return pp;
    }

    return NULL;
}
Example #7
0
FILE *cf_popen(const char *command, char *type)
{
    int pd[2];
    char **argv;
    pid_t pid;
    FILE *pp = NULL;

    CfDebug("cf_popen(%s)\n", command);

    pid = CreatePipeAndFork(type, pd);
    if (pid == -1) {
        return NULL;
    }

    if (pid == 0)
    {
        switch (*type)
        {
        case 'r':

            close(pd[0]);       /* Don't need output from parent */

            if (pd[1] != 1)
            {
                dup2(pd[1], 1); /* Attach pp=pd[1] to our stdout */
                dup2(pd[1], 2); /* Merge stdout/stderr */
                close(pd[1]);
            }

            break;

        case 'w':

            close(pd[1]);

            if (pd[0] != 0)
            {
                dup2(pd[0], 0);
                close(pd[0]);
            }
        }

        CloseChildrenFD();

        argv = ArgSplitCommand(command);

        if (execv(argv[0], argv) == -1)
        {
            CfOut(cf_error, "execv", "Couldn't run %s", argv[0]);
        }

        _exit(1);
    }
    else
    {
        switch (*type)
        {
        case 'r':

            close(pd[1]);

            if ((pp = fdopen(pd[0], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
            break;

        case 'w':

            close(pd[0]);

            if ((pp = fdopen(pd[1], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
        }

        SetChildFD(fileno(pp), pid);
        return pp;
    }

    return NULL;                /* Cannot reach here */
}
Example #8
0
FILE *cf_popensetuid(const char *command, char *type, uid_t uid, gid_t gid, char *chdirv, char *chrootv, int background)
{
    int i, pd[2];
    char **argv;
    pid_t pid;
    FILE *pp = NULL;

    CfDebug("cf_popensetuid(%s,%s,%" PRIuMAX ",%" PRIuMAX ")\n", command, type, (uintmax_t)uid, (uintmax_t)gid);

    if (((*type != 'r') && (*type != 'w')) || (type[1] != '\0'))
    {
        errno = EINVAL;
        return NULL;
    }

    if (!ThreadLock(cft_count))
    {
        return NULL;
    }

    if (CHILDREN == NULL)       /* first time */
    {
        CHILDREN = xcalloc(MAX_FD, sizeof(pid_t));
    }

    ThreadUnlock(cft_count);

    if (pipe(pd) < 0)           /* Create a pair of descriptors to this process */
    {
        return NULL;
    }

    if ((pid = fork()) == -1)
    {
        close(pd[0]);
        close(pd[1]);
        return NULL;
    }

    signal(SIGCHLD, SIG_DFL);
    ALARM_PID = (pid != 0 ? pid : -1);

    if (pid == 0)
    {
        switch (*type)
        {
        case 'r':

            close(pd[0]);       /* Don't need output from parent */

            if (pd[1] != 1)
            {
                dup2(pd[1], 1); /* Attach pp=pd[1] to our stdout */
                dup2(pd[1], 2); /* Merge stdout/stderr */
                close(pd[1]);
            }

            break;

        case 'w':

            close(pd[1]);

            if (pd[0] != 0)
            {
                dup2(pd[0], 0);
                close(pd[0]);
            }
        }

        for (i = 0; i < MAX_FD; i++)
        {
            if (CHILDREN[i] > 0)
            {
                close(i);
            }
        }

        argv = ArgSplitCommand(command);

        if (chrootv && (strlen(chrootv) != 0))
        {
            if (chroot(chrootv) == -1)
            {
                CfOut(cf_error, "chroot", "Couldn't chroot to %s\n", chrootv);
                ArgFree(argv);
                return NULL;
            }
        }

        if (chdirv && (strlen(chdirv) != 0))
        {
            if (chdir(chdirv) == -1)
            {
                CfOut(cf_error, "chdir", "Couldn't chdir to %s\n", chdirv);
                ArgFree(argv);
                return NULL;
            }
        }

        if (!CfSetuid(uid, gid))
        {
            _exit(1);
        }

        if (execv(argv[0], argv) == -1)
        {
            CfOut(cf_error, "execv", "Couldn't run %s", argv[0]);
        }

        _exit(1);
    }
    else
    {
        switch (*type)
        {
        case 'r':

            close(pd[1]);

            if ((pp = fdopen(pd[0], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
            break;

        case 'w':

            close(pd[0]);

            if ((pp = fdopen(pd[1], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
        }

        if (fileno(pp) >= MAX_FD)
        {
            CfOut(cf_error, "",
                  "File descriptor %d of child %jd higher than MAX_FD in cf_popensetuid, check for defunct children",
                  fileno(pp), (intmax_t)pid);
        }
        else
        {
            ThreadLock(cft_count);
            CHILDREN[fileno(pp)] = pid;
            ThreadUnlock(cft_count);
        }

        return pp;
    }

    return NULL;                /* cannot reach here */
}
Example #9
0
FILE *cf_popensetuid(const char *command, char *type, uid_t uid, gid_t gid, char *chdirv, char *chrootv, int background)
{
    int pd[2];
    char **argv;
    pid_t pid;
    FILE *pp = NULL;

    CfDebug("cf_popensetuid(%s,%s,%" PRIuMAX ",%" PRIuMAX ")\n", command, type, (uintmax_t)uid, (uintmax_t)gid);

    pid = CreatePipeAndFork(type, pd);
    if (pid == -1) {
        return NULL;
    }

    if (pid == 0)
    {
        switch (*type)
        {
        case 'r':

            close(pd[0]);       /* Don't need output from parent */

            if (pd[1] != 1)
            {
                dup2(pd[1], 1); /* Attach pp=pd[1] to our stdout */
                dup2(pd[1], 2); /* Merge stdout/stderr */
                close(pd[1]);
            }

            break;

        case 'w':

            close(pd[1]);

            if (pd[0] != 0)
            {
                dup2(pd[0], 0);
                close(pd[0]);
            }
        }

        CloseChildrenFD();

        argv = ArgSplitCommand(command);

        if (chrootv && (strlen(chrootv) != 0))
        {
            if (chroot(chrootv) == -1)
            {
                CfOut(OUTPUT_LEVEL_ERROR, "chroot", "Couldn't chroot to %s\n", chrootv);
                ArgFree(argv);
                return NULL;
            }
        }

        if (chdirv && (strlen(chdirv) != 0))
        {
            if (chdir(chdirv) == -1)
            {
                CfOut(OUTPUT_LEVEL_ERROR, "chdir", "Couldn't chdir to %s\n", chdirv);
                ArgFree(argv);
                return NULL;
            }
        }

        if (!CfSetuid(uid, gid))
        {
            _exit(1);
        }

        if (execv(argv[0], argv) == -1)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "execv", "Couldn't run %s", argv[0]);
        }

        _exit(1);
    }
    else
    {
        switch (*type)
        {
        case 'r':

            close(pd[1]);

            if ((pp = fdopen(pd[0], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
            break;

        case 'w':

            close(pd[0]);

            if ((pp = fdopen(pd[1], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
        }

        SetChildFD(fileno(pp), pid);
        return pp;
    }

    return NULL;                /* cannot reach here */
}
Example #10
0
FILE *cf_popen_shsetuid(const char *command, const char *type, uid_t uid, gid_t gid, char *chdirv, char *chrootv, ARG_UNUSED int background)
{
    int pd[2];
    pid_t pid;
    FILE *pp = NULL;

    pid = CreatePipeAndFork(type, pd);
    if (pid == -1) {
        return NULL;
    }

    if (pid == 0)
    {
        switch (*type)
        {
        case 'r':

            close(pd[0]);       /* Don't need output from parent */

            if (pd[1] != 1)
            {
                dup2(pd[1], 1); /* Attach pp=pd[1] to our stdout */
                dup2(pd[1], 2); /* Merge stdout/stderr */
                close(pd[1]);
            }

            break;

        case 'w':

            close(pd[1]);

            if (pd[0] != 0)
            {
                dup2(pd[0], 0);
                close(pd[0]);
            }
        }

        CloseChildrenFD();

        if (chrootv && (strlen(chrootv) != 0))
        {
            if (chroot(chrootv) == -1)
            {
                Log(LOG_LEVEL_ERR, "Couldn't chroot to '%s'. (chroot: %s)", chrootv, GetErrorStr());
                return NULL;
            }
        }

        if (chdirv && (strlen(chdirv) != 0))
        {
            if (safe_chdir(chdirv) == -1)
            {
                Log(LOG_LEVEL_ERR, "Couldn't chdir to '%s'. (chdir: %s)", chdirv, GetErrorStr());
                return NULL;
            }
        }

        if (!CfSetuid(uid, gid))
        {
            _exit(EXIT_FAILURE);
        }

        execl(SHELL_PATH, "sh", "-c", command, NULL);
        _exit(EXIT_FAILURE);
    }
    else
    {
        switch (*type)
        {
        case 'r':

            close(pd[1]);

            if ((pp = fdopen(pd[0], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
            break;

        case 'w':

            close(pd[0]);

            if ((pp = fdopen(pd[1], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
        }

        SetChildFD(fileno(pp), pid);
        return pp;
    }

    return NULL;
}
Example #11
0
FILE *cf_popen(const char *command, const char *type, bool capture_stderr)
{
    int pd[2];
    char **argv;
    pid_t pid;
    FILE *pp = NULL;

    pid = CreatePipeAndFork(type, pd);
    if (pid == -1) {
        return NULL;
    }

    if (pid == 0)
    {
        switch (*type)
        {
        case 'r':

            close(pd[0]);       /* Don't need output from parent */

            if (pd[1] != 1)
            {
                dup2(pd[1], 1); /* Attach pp=pd[1] to our stdout */

                if (capture_stderr)
                {
                    dup2(pd[1], 2); /* Merge stdout/stderr */
                }
                else
                {
                    int nullfd = open(NULLFILE, O_WRONLY);
                    dup2(nullfd, 2);
                    close(nullfd);
                }

                close(pd[1]);
            }

            break;

        case 'w':

            close(pd[1]);

            if (pd[0] != 0)
            {
                dup2(pd[0], 0);
                close(pd[0]);
            }
        }

        CloseChildrenFD();

        argv = ArgSplitCommand(command);

        if (execv(argv[0], argv) == -1)
        {
            Log(LOG_LEVEL_ERR, "Couldn't run '%s'. (execv: %s)", argv[0], GetErrorStr());
        }

        _exit(EXIT_FAILURE);
    }
    else
    {
        switch (*type)
        {
        case 'r':

            close(pd[1]);

            if ((pp = fdopen(pd[0], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
            break;

        case 'w':

            close(pd[0]);

            if ((pp = fdopen(pd[1], type)) == NULL)
            {
                cf_pwait(pid);
                return NULL;
            }
        }

        SetChildFD(fileno(pp), pid);
        return pp;
    }

    return NULL;                /* Cannot reach here */
}