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]