here's my patch.

sorry it's large because i think that per-user umask should be optional, 
so i've done most of the work to make that happen... now you have to 
specify "user" as an argument to pam_umask.so... as it happens it has to 
be the first argument, because arguments are processed left-to-right.

in theory i really think it should be user=~/.pam_umask or somethign like 
that (so that different pam configurations can use different umasks) but 
really i think this is total feeping creaturism.  personally i'd do 
without the per-user stuff entirely... but at least this patch makes it 
stop segfaulting.

-dean

diff -ru pam-umask-0.02/README pam-umask-0.02.dg1/README
--- pam-umask-0.02/README       2005-07-17 06:26:31.000000000 -0700
+++ pam-umask-0.02.dg1/README   2005-07-18 16:02:36.214696259 -0700
@@ -12,14 +12,22 @@
 
 session    optional     pam_umask.so umask=002
 
-to the services where you want to set the umask to 002
+to the services where you want to set the umask to 002.  (For example
+in /etc/pam.d/common-session.)
 
 Note that using "optional" instead of "required" will allow users to
 login even if pam_umask fails to parse the umask line.  Using
 "required" will deny login if an error occurs while setting the umask,
 which is clearly a non-desireable situation.
 
-The module also supports per-user umasks.  If a user has a .pam_umask
-in his home directory, the contents will be used to set the umask.
-Note that strtol is used for parsing, so making sure to have a leading
-zero (like 022 or 002) is recommended.
+The module also supports per-user umasks.  To enable per-user umasks
+use a line like so:
+
+session    optional     pam_umask.so user umask=002
+
+In this case, if a user has a .pam_umask in his home directory, the
+contents will be used to set the umask.  Note that strtol is used
+for parsing, so making sure to have a leading zero (like 022 or 002)
+is recommended.  Otherwise the "umask=002" argument will be used.
+
+(Note that the ordering of arguments is important.)
diff -ru pam-umask-0.02/pam_umask.c pam-umask-0.02.dg1/pam_umask.c
--- pam-umask-0.02/pam_umask.c  2005-07-17 06:34:53.000000000 -0700
+++ pam-umask-0.02.dg1/pam_umask.c      2005-07-18 15:56:04.955805118 -0700
@@ -48,54 +48,17 @@
 PAM_EXTERN
 int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, 
                         const char **argv) {
-  const char **user;
-  int ret;
-  struct passwd *puser;
-  FILE *umask_file;
-  char *umask_file_path, *user_umask;
   mode_t um;
+  int i;
 
-  ret = pam_get_item(pamh, PAM_USER, user);
-  if (ret != PAM_SUCCESS) {
-    _log_err(LOG_ERR, "Can't get user");
+  if (argc == 0) {
+    _log_err(LOG_ERR, "at least one of \"umask=NNN\" or \"user\" must be 
supplied");
     return PAM_SESSION_ERR;
   }
 
-  puser = getpwnam(*user);
-  if (!puser) {
-    _log_err(LOG_ERR, "User %s not found using getpwent", *user);
-    return PAM_SESSION_ERR;
-  }
-  _log_err(LOG_ERR, "User is %s", *user);
-
-  umask_file_path = xmalloc(strlen(puser->pw_dir) + 
-                            strlen(PAM_UMASK_FILE_NAME) +
-                            1);
-  sprintf(umask_file_path, "%s/%s", puser->pw_dir, PAM_UMASK_FILE_NAME);
-
-  umask_file = fopen(umask_file_path, "r");
-
-  if (umask_file != NULL) {
-    user_umask = freadline(umask_file);
-    um = strtol(user_umask, NULL, 0);
-    if (um == LONG_MIN || um == LONG_MAX) {
-      _log_err(LOG_ERR, "illegal umask specified for user: %s", 
puser->pw_name);
-      return PAM_SESSION_ERR;
-    }
-    fclose(umask_file);
-    umask(um);
-    return PAM_SUCCESS;
-  }
-
-  _log_err(LOG_ERR, ".pam file not found", *user);
-
-
-  /* Ok, either no file, unreadable or something else. Ignore and go on with
-     the system umask. */
-
-  if (argc-- > 0) {
-    if (strncmp(argv[argc], "umask=", 6) == 0) {
-      um = strtol((argv[argc])+6, NULL, 0);
+  for (i = 0; i < argc; ++i) {
+    if (strncmp(argv[i], "umask=", 6) == 0) {
+      um = strtol((argv[i])+6, NULL, 0);
       if (um == LONG_MIN || um == LONG_MAX) {
         _log_err(LOG_ERR, "illegal umask specified");
         return PAM_SESSION_ERR;
@@ -103,8 +66,57 @@
       umask(um);
       return PAM_SUCCESS;
     }
+    // TODO:  this really should be user=~/.pam_umask ... so that different
+    // pam config files could specify different per-user umask files... but
+    // damn this is really feeping creaturism.
+    else if (strcmp(argv[i], "user") == 0) {
+      const void *v_user;
+      const char *user;
+      int ret;
+      struct passwd *puser;
+      FILE *umask_file;
+      char *umask_file_path, *user_umask;
+
+      ret = pam_get_item(pamh, PAM_USER, &v_user);
+      if (ret != PAM_SUCCESS) {
+       _log_err(LOG_ERR, "Can't get user");
+       return PAM_SESSION_ERR;
+      }
+      user = v_user;
+
+      puser = getpwnam(user);
+      if (!puser) {
+       _log_err(LOG_ERR, "User %s not found using getpwent", user);
+       return PAM_SESSION_ERR;
+      }
+
+      umask_file_path = xmalloc(strlen(puser->pw_dir) + 
+                               strlen(PAM_UMASK_FILE_NAME) +
+                               2);
+      sprintf(umask_file_path, "%s/%s", puser->pw_dir, PAM_UMASK_FILE_NAME);
+      umask_file = fopen(umask_file_path, "r");
+      if (umask_file != NULL) {
+       user_umask = freadline(umask_file);
+       um = strtol(user_umask, NULL, 0);
+       if (um == LONG_MIN || um == LONG_MAX) {
+         _log_err(LOG_ERR, "illegal umask specified for user: %s", 
puser->pw_name);
+         return PAM_SESSION_ERR;
+       }
+       fclose(umask_file);
+       umask(um);
+       return PAM_SUCCESS;
+      }
+      if (errno != ENOENT) {
+       /* we'll log these errors, but we won't fail when they occur */
+       _log_err(LOG_ERR, "error opening '%s' for reading: %s", 
umask_file_path, strerror(errno));
+      }
+    }
+    else {
+      _log_err(LOG_ERR, "unrecognized argument");
+      return PAM_SESSION_ERR;
+    }
   }
-  return PAM_SESSION_ERR;
+  return PAM_SUCCESS;
 }
 
 


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to