diff options
Diffstat (limited to 'modules/pam_xauth/pam_xauth.c')
-rw-r--r-- | modules/pam_xauth/pam_xauth.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/modules/pam_xauth/pam_xauth.c b/modules/pam_xauth/pam_xauth.c index 88624b1..2be4351 100644 --- a/modules/pam_xauth/pam_xauth.c +++ b/modules/pam_xauth/pam_xauth.c @@ -103,9 +103,11 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, /* Create stdio pipery. */ if (pipe(ipipe) == -1) { + pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m"); return -1; } if (pipe(opipe) == -1) { + pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m"); close(ipipe[0]); close(ipipe[1]); return -1; @@ -114,6 +116,7 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, /* Fork off a child. */ child = fork(); if (child == -1) { + pam_syslog(pamh, LOG_ERR, "Could not fork: %m"); close(ipipe[0]); close(ipipe[1]); close(opipe[0]); @@ -124,9 +127,7 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, if (child == 0) { /* We're the child. */ size_t j; - char *args[10]; - const char *tmp; - int maxopened; + const char *args[10]; /* Drop privileges. */ if (setgid(gid) == -1) { @@ -148,42 +149,48 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, (unsigned long) geteuid ()); _exit (err); } - /* Initialize the argument list. */ - memset(args, 0, sizeof(args)); /* Set the pipe descriptors up as stdin and stdout, and close * everything else, including the original values for the * descriptors. */ - dup2(ipipe[0], STDIN_FILENO); - dup2(opipe[1], STDOUT_FILENO); - maxopened = (int)sysconf(_SC_OPEN_MAX); - for (i = 0; i < maxopened; i++) { - if ((i != STDIN_FILENO) && (i != STDOUT_FILENO)) { - close(i); - } + if (dup2(ipipe[0], STDIN_FILENO) != STDIN_FILENO) { + int err = errno; + pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdin"); + _exit(err); } + if (dup2(opipe[1], STDOUT_FILENO) != STDOUT_FILENO) { + int err = errno; + pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdout"); + _exit(err); + } + if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_IGNORE_FD, + PAM_MODUTIL_IGNORE_FD, + PAM_MODUTIL_NULL_FD) < 0) { + _exit(1); + } + /* Initialize the argument list. */ + memset(args, 0, sizeof(args)); /* Convert the varargs list into a regular array of strings. */ va_start(ap, command); - args[0] = strdup(command); + args[0] = command; for (j = 1; j < ((sizeof(args) / sizeof(args[0])) - 1); j++) { - tmp = va_arg(ap, const char*); - if (tmp == NULL) { + args[j] = va_arg(ap, const char*); + if (args[j] == NULL) { break; } - args[j] = strdup(tmp); } /* Run the command. */ - execv(command, args); + execv(command, (char *const *) args); /* Never reached. */ _exit(1); } /* We're the parent, so close the other ends of the pipes. */ - close(ipipe[0]); close(opipe[1]); /* Send input to the process (if we have any), then send an EOF. */ if (input) { (void)pam_modutil_write(ipipe[1], input, strlen(input)); } + close(ipipe[0]); /* close here to avoid possible SIGPIPE above */ close(ipipe[1]); /* Read data output until we run out of stuff to read. */ |