]> granicus.if.org Git - linux-pam/commitdiff
Relevant BUGIDs:
authorThorsten Kukuk <kukuk@thkukuk.de>
Fri, 13 Aug 2010 08:59:53 +0000 (08:59 +0000)
committerThorsten Kukuk <kukuk@thkukuk.de>
Fri, 13 Aug 2010 08:59:53 +0000 (08:59 +0000)
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.`

ChangeLog
modules/pam_env/pam_env.c
modules/pam_mail/pam_mail.c
modules/pam_xauth/pam_xauth.c

index 86e3ae1342bdbd030e96f5a5055f1332bca2793e..da8193ddecc76f5458e86b11a2a1753f32988486 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+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.`
+
 2010-08-09  Thorsten Kukuk  <kukuk@thkukuk.de>
 
        * modules/pam_tally/pam_tally.8.xml: Document that pam_tally is
index 849531049cc2d28612d995ac8076586891f52701..4e5f6eb373a3ae6d428a9ea1b3a1c88587264681 100644 (file)
@@ -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;
       }
index a5473605533ef68cd71372f150ff06418ed0ebb5..089c398c8b40f9e164ed8b6c03773e33bd30a6d3 100644 (file)
@@ -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;
index 61bd5a91bffaab781b3f4d774ccfa6786308678d..07ece6472f9a8e048cfad3a99247bf1c6dffdced 100644 (file)
@@ -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);