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; }
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; }
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 */ }
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 */ }
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; }
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 */ }