diff options
author | Steve Langasek <vorlon@debian.org> | 2010-08-31 17:23:27 -0700 |
---|---|---|
committer | Steve Langasek <vorlon@debian.org> | 2019-01-08 21:47:21 -0800 |
commit | 6c6f451aff56e368041dd4076ad61d8f51635b7f (patch) | |
tree | ed1162733e6688167c56704ffbf4e63c602abf35 /modules/pam_xauth/pam_xauth.c | |
parent | 0b7e86d2422eb0ddabce5ffcd59ee31525a4e8af (diff) | |
parent | b70316c593cbc8e5c9155e5c6597497090c6eb88 (diff) | |
download | pam-6c6f451aff56e368041dd4076ad61d8f51635b7f.tar.gz pam-6c6f451aff56e368041dd4076ad61d8f51635b7f.tar.bz2 pam-6c6f451aff56e368041dd4076ad61d8f51635b7f.zip |
merge upstream version 1.1.2
Diffstat (limited to 'modules/pam_xauth/pam_xauth.c')
-rw-r--r-- | modules/pam_xauth/pam_xauth.c | 56 |
1 files changed, 47 insertions, 9 deletions
diff --git a/modules/pam_xauth/pam_xauth.c b/modules/pam_xauth/pam_xauth.c index 0a94db4f..07ece647 100644 --- a/modules/pam_xauth/pam_xauth.c +++ b/modules/pam_xauth/pam_xauth.c @@ -87,7 +87,7 @@ static const char * const xauthpaths[] = { /* Run a given command (with a NULL-terminated argument list), feeding it the * given input on stdin, and storing any output it generates. */ static int -run_coprocess(const char *input, char **output, +run_coprocess(pam_handle_t *pamh, const char *input, char **output, uid_t uid, gid_t gid, const char *command, ...) { int ipipe[2], opipe[2], i; @@ -126,9 +126,26 @@ run_coprocess(const char *input, char **output, const char *tmp; int maxopened; /* Drop privileges. */ - setgid(gid); - setgroups(0, NULL); - setuid(uid); + if (setgid(gid) == -1) + { + int err = errno; + pam_syslog (pamh, LOG_ERR, "setgid(%lu) failed: %m", + (unsigned long) getegid ()); + _exit (err); + } + if (setgroups(0, NULL) == -1) + { + int err = errno; + pam_syslog (pamh, LOG_ERR, "setgroups() failed: %m"); + _exit (err); + } + if (setuid(uid) == -1) + { + int err = errno; + pam_syslog (pamh, LOG_ERR, "setuid(%lu) failed: %m", + (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 @@ -216,7 +233,7 @@ check_acl(pam_handle_t *pamh, char path[PATH_MAX]; struct passwd *pwd; FILE *fp; - int i; + int i, save_errno; uid_t euid; /* Check this user's <sense> file. */ pwd = pam_modutil_getpwnam(pamh, this_user); @@ -236,6 +253,7 @@ check_acl(pam_handle_t *pamh, euid = geteuid(); setfsuid(pwd->pw_uid); fp = fopen(path, "r"); + save_errno = errno; setfsuid(euid); if (fp != NULL) { char buf[LINE_MAX], *tmp; @@ -268,6 +286,7 @@ check_acl(pam_handle_t *pamh, return PAM_PERM_DENIED; } else { /* Default to okay if the file doesn't exist. */ + errno = save_errno; switch (errno) { case ENOENT: if (noent_code == PAM_SUCCESS) { @@ -463,7 +482,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, xauth, "-f", cookiefile, "nlist", display, (unsigned long) getuid(), (unsigned long) getgid()); } - if (run_coprocess(NULL, &cookie, + if (run_coprocess(pamh, NULL, &cookie, getuid(), getgid(), xauth, "-f", cookiefile, "nlist", display, NULL) == 0) { @@ -521,7 +540,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, (unsigned long) getuid(), (unsigned long) getgid()); } - run_coprocess(NULL, &cookie, + run_coprocess(pamh, NULL, &cookie, getuid(), getgid(), xauth, "-f", cookiefile, "nlist", t, NULL); @@ -555,7 +574,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, /* Generate a new file to hold the data. */ euid = geteuid(); setfsuid(tpwd->pw_uid); - + #ifdef WITH_SELINUX if (is_selinux_enabled() > 0) { struct selabel_handle *ctx = selabel_open(SELABEL_CTX_FILE, NULL, 0); @@ -595,8 +614,10 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, } /* Set permissions on the new file and dispose of the * descriptor. */ + setfsuid(tpwd->pw_uid); if (fchown(fd, tpwd->pw_uid, tpwd->pw_gid) < 0) pam_syslog (pamh, LOG_ERR, "fchown: %m"); + setfsuid(euid); close(fd); /* Get a copy of the filename to save as a data item for @@ -669,7 +690,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, (unsigned long) tpwd->pw_uid, (unsigned long) tpwd->pw_gid); } - run_coprocess(cookie, &tmp, + run_coprocess(pamh, cookie, &tmp, tpwd->pw_uid, tpwd->pw_gid, xauth, "-f", cookiefile, "nmerge", "-", NULL); @@ -693,6 +714,20 @@ pam_sm_close_session (pam_handle_t *pamh, int flags UNUSED, { void *cookiefile; int i, debug = 0; + const char* user; + struct passwd *tpwd; + uid_t unlinkuid, euid; + unlinkuid = euid = geteuid (); + + if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) + pam_syslog(pamh, LOG_ERR, "error determining target user's name"); + else { + tpwd = pam_modutil_getpwnam(pamh, user); + if (!tpwd) + pam_syslog(pamh, LOG_ERR, "error determining target user's UID"); + else + unlinkuid = tpwd->pw_uid; + } /* Parse arguments. We don't understand many, so no sense in breaking * this into a separate function. */ @@ -723,7 +758,10 @@ pam_sm_close_session (pam_handle_t *pamh, int flags UNUSED, pam_syslog(pamh, LOG_DEBUG, "removing `%s'", (char*)cookiefile); } + /* NFS with root_squash requires non-root user */ + setfsuid (unlinkuid); unlink((char*)cookiefile); + setfsuid (euid); *((char*)cookiefile) = '\0'; } } |