diff options
author | Thorsten Kukuk <kukuk@thkukuk.de> | 2010-08-13 08:59:53 +0000 |
---|---|---|
committer | Thorsten Kukuk <kukuk@thkukuk.de> | 2010-08-13 08:59:53 +0000 |
commit | 07b5f4ce482ef22270a6c18ba01d108c065b9de2 (patch) | |
tree | 442ccb5407d52983b81a937dc83c0c035a3493eb /modules | |
parent | 660464aa88967f55ab3ec7d54cba20757d884634 (diff) | |
download | pam-07b5f4ce482ef22270a6c18ba01d108c065b9de2.tar.gz pam-07b5f4ce482ef22270a6c18ba01d108c065b9de2.tar.bz2 pam-07b5f4ce482ef22270a6c18ba01d108c065b9de2.zip |
Relevant BUGIDs:
Purpose of commit: bugfix
Commit summary:
---------------
2010-08-12 Thorsten Kukuk <kukuk@thkukuk.de>
* modules/pam_mail/pam_mail.c: Check for mail only with user
privilegs.
* modules/pam_xauth/pam_xauth.c (run_coprocess): Check return
value of setgid, setgroups and setuid.
* modules/pam_xauth/pam_xauth.c (check_acl): Save errno for
later usage.
* modules/pam_env/pam_env.c (handle_env): Check if user exists,
read local user config only with user privilegs.`
Diffstat (limited to 'modules')
-rw-r--r-- | modules/pam_env/pam_env.c | 9 | ||||
-rw-r--r-- | modules/pam_mail/pam_mail.c | 57 | ||||
-rw-r--r-- | modules/pam_xauth/pam_xauth.c | 35 |
3 files changed, 62 insertions, 39 deletions
diff --git a/modules/pam_env/pam_env.c b/modules/pam_env/pam_env.c index 84953104..4e5f6eb3 100644 --- a/modules/pam_env/pam_env.c +++ b/modules/pam_env/pam_env.c @@ -23,6 +23,7 @@ #include <string.h> #include <syslog.h> #include <sys/stat.h> +#include <sys/fsuid.h> #include <sys/types.h> #include <unistd.h> @@ -772,13 +773,14 @@ handle_env (pam_handle_t *pamh, int argc, const char **argv) if(user_readenv && retval == PAM_SUCCESS) { char *envpath = NULL; - struct passwd *user_entry; + struct passwd *user_entry = NULL; const char *username; struct stat statbuf; username = _pam_get_item_byname(pamh, "PAM_USER"); - user_entry = pam_modutil_getpwnam (pamh, username); + if (username) + user_entry = pam_modutil_getpwnam (pamh, username); if (!user_entry) { pam_syslog(pamh, LOG_ERR, "No such user!?"); } @@ -789,7 +791,10 @@ handle_env (pam_handle_t *pamh, int argc, const char **argv) return PAM_BUF_ERR; } if (stat(envpath, &statbuf) == 0) { + uid_t euid = geteuid(); + setfsuid (user_entry->pw_uid); retval = _parse_config_file(pamh, envpath); + setfsuid (euid); if (retval == PAM_IGNORE) retval = PAM_SUCCESS; } diff --git a/modules/pam_mail/pam_mail.c b/modules/pam_mail/pam_mail.c index a5473605..089c398c 100644 --- a/modules/pam_mail/pam_mail.c +++ b/modules/pam_mail/pam_mail.c @@ -17,6 +17,7 @@ #include <syslog.h> #include <sys/stat.h> #include <sys/types.h> +#include <sys/fsuid.h> #include <unistd.h> #include <dirent.h> #include <errno.h> @@ -124,29 +125,16 @@ _pam_parse (const pam_handle_t *pamh, int flags, int argc, static int get_folder(pam_handle_t *pamh, int ctrl, - const char *path_mail, char **folder_p, size_t hashcount) + const char *path_mail, char **folder_p, size_t hashcount, + const struct passwd *pwd) { int retval; - const char *user, *path; + const char *path; char *folder = NULL; - const struct passwd *pwd = NULL; - - retval = pam_get_user(pamh, &user, NULL); - if (retval != PAM_SUCCESS || user == NULL) { - pam_syslog(pamh, LOG_ERR, "cannot determine username"); - retval = PAM_USER_UNKNOWN; - goto get_folder_cleanup; - } if (ctrl & PAM_NEW_MAIL_DIR) { path = path_mail; if (*path == '~') { /* support for $HOME delivery */ - pwd = pam_modutil_getpwnam(pamh, user); - if (pwd == NULL) { - pam_syslog(pamh, LOG_ERR, "user unknown"); - retval = PAM_USER_UNKNOWN; - goto get_folder_cleanup; - } /* * "~/xxx" and "~xxx" are treated as same */ @@ -168,18 +156,11 @@ get_folder(pam_handle_t *pamh, int ctrl, /* put folder together */ - hashcount = hashcount < strlen(user) ? hashcount : strlen(user); + hashcount = hashcount < strlen(pwd->pw_name) ? + hashcount : strlen(pwd->pw_name); retval = PAM_BUF_ERR; if (ctrl & PAM_HOME_MAIL) { - if (pwd == NULL) { - pwd = pam_modutil_getpwnam(pamh, user); - if (pwd == NULL) { - pam_syslog(pamh, LOG_ERR, "user unknown"); - retval = PAM_USER_UNKNOWN; - goto get_folder_cleanup; - } - } if (asprintf(&folder, MAIL_FILE_FORMAT, pwd->pw_dir, "", path) < 0) goto get_folder_cleanup; } else { @@ -192,11 +173,11 @@ get_folder(pam_handle_t *pamh, int ctrl, for (i = 0; i < hashcount; i++) { hash[2 * i] = '/'; - hash[2 * i + 1] = user[i]; + hash[2 * i + 1] = pwd->pw_name[i]; } hash[2 * i] = '\0'; - rc = asprintf(&folder, MAIL_FILE_FORMAT, path, hash, user); + rc = asprintf(&folder, MAIL_FILE_FORMAT, path, hash, pwd->pw_name); _pam_overwrite(hash); _pam_drop(hash); if (rc < 0) @@ -208,7 +189,6 @@ get_folder(pam_handle_t *pamh, int ctrl, /* tidy up */ get_folder_cleanup: - user = NULL; path = NULL; *folder_p = folder; @@ -402,7 +382,9 @@ static int _do_mail(pam_handle_t *pamh, int flags, int argc, int retval, ctrl, type; size_t hashcount; char *folder = NULL; + const char *user; const char *path_mail = NULL; + const struct passwd *pwd = NULL; /* * this module (un)sets the MAIL environment variable, and checks if @@ -411,9 +393,21 @@ static int _do_mail(pam_handle_t *pamh, int flags, int argc, ctrl = _pam_parse(pamh, flags, argc, argv, &path_mail, &hashcount); + retval = pam_get_user(pamh, &user, NULL); + if (retval != PAM_SUCCESS || user == NULL) { + pam_syslog(pamh, LOG_ERR, "cannot determine username"); + return PAM_USER_UNKNOWN; + } + + pwd = pam_modutil_getpwnam (pamh, user); + if (pwd == NULL) { + pam_syslog(pamh, LOG_ERR, "user unknown"); + return PAM_USER_UNKNOWN; + } + /* which folder? */ - retval = get_folder(pamh, ctrl, path_mail, &folder, hashcount); + retval = get_folder(pamh, ctrl, path_mail, &folder, hashcount, pwd); if (retval != PAM_SUCCESS) { D(("failed to find folder")); return retval; @@ -450,7 +444,12 @@ static int _do_mail(pam_handle_t *pamh, int flags, int argc, if ((est && !(ctrl & PAM_NO_LOGIN)) || (!est && (ctrl & PAM_LOGOUT_TOO))) { + uid_t euid = geteuid(); + + setfsuid (pwd->pw_uid); type = get_mail_status(pamh, ctrl, folder); + setfsuid (euid); + if (type != 0) { retval = report_mail(pamh, ctrl, type, folder); type = 0; diff --git a/modules/pam_xauth/pam_xauth.c b/modules/pam_xauth/pam_xauth.c index 61bd5a91..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); @@ -671,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); |