diff options
Diffstat (limited to 'modules/pam_mkhomedir/pam_mkhomedir.c')
-rw-r--r-- | modules/pam_mkhomedir/pam_mkhomedir.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/modules/pam_mkhomedir/pam_mkhomedir.c b/modules/pam_mkhomedir/pam_mkhomedir.c index cb773e8f..6ddcd5a8 100644 --- a/modules/pam_mkhomedir/pam_mkhomedir.c +++ b/modules/pam_mkhomedir/pam_mkhomedir.c @@ -56,6 +56,9 @@ #define MKHOMEDIR_DEBUG 020 /* be verbose about things */ #define MKHOMEDIR_QUIET 040 /* keep quiet about things */ +#define LOGIN_DEFS "/etc/login.defs" +#define UMASK_DEFAULT "0022" + struct options_t { int ctrl; const char *umask; @@ -68,7 +71,7 @@ _pam_parse (const pam_handle_t *pamh, int flags, int argc, const char **argv, options_t *opt) { opt->ctrl = 0; - opt->umask = "0022"; + opt->umask = NULL; opt->skeldir = "/etc/skel"; /* does the application require quiet? */ @@ -94,6 +97,17 @@ _pam_parse (const pam_handle_t *pamh, int flags, int argc, const char **argv, } } +static char* +_pam_conv_str_umask_to_homemode(const char *umask) +{ + unsigned int m = 0; + char tmp[5]; + + m = 0777 & ~strtoul(umask, NULL, 8); + (void) snprintf(tmp, sizeof(tmp), "0%o", m); + return strdup(tmp); +} + /* Do the actual work of creating a home dir */ static int create_homedir (pam_handle_t *pamh, options_t *opt, @@ -101,6 +115,8 @@ create_homedir (pam_handle_t *pamh, options_t *opt, { int retval, child; struct sigaction newsa, oldsa; + char *login_umask = NULL; + char *login_homemode = NULL; /* Mention what is happening, if the notification fails that is OK */ if (!(opt->ctrl & MKHOMEDIR_QUIET)) @@ -109,6 +125,25 @@ create_homedir (pam_handle_t *pamh, options_t *opt, D(("called.")); + if (opt->ctrl & MKHOMEDIR_DEBUG) { + pam_syslog(pamh, LOG_DEBUG, "Executing mkhomedir_helper."); + } + + /* fetch UMASK from /etc/login.defs if not in argv */ + if (opt->umask == NULL) { + login_umask = pam_modutil_search_key(pamh, LOGIN_DEFS, "UMASK"); + login_homemode = pam_modutil_search_key(pamh, LOGIN_DEFS, "HOME_MODE"); + if (login_homemode == NULL) { + if (login_umask != NULL) { + login_homemode = _pam_conv_str_umask_to_homemode(login_umask); + } else { + login_homemode = _pam_conv_str_umask_to_homemode(UMASK_DEFAULT); + } + } + } else { + login_homemode = _pam_conv_str_umask_to_homemode(opt->umask); + } + /* * This code arranges that the demise of the child does not cause * the application to receive a signal it is not expecting - which @@ -118,15 +153,11 @@ create_homedir (pam_handle_t *pamh, options_t *opt, newsa.sa_handler = SIG_DFL; sigaction(SIGCHLD, &newsa, &oldsa); - if (opt->ctrl & MKHOMEDIR_DEBUG) { - pam_syslog(pamh, LOG_DEBUG, "Executing mkhomedir_helper."); - } - /* fork */ child = fork(); if (child == 0) { static char *envp[] = { NULL }; - const char *args[] = { NULL, NULL, NULL, NULL, NULL }; + const char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL }; if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_PIPE_FD, PAM_MODUTIL_PIPE_FD, @@ -136,8 +167,9 @@ create_homedir (pam_handle_t *pamh, options_t *opt, /* exec the mkhomedir helper */ args[0] = MKHOMEDIR_HELPER; args[1] = user; - args[2] = opt->umask; + args[2] = opt->umask ? opt->umask : UMASK_DEFAULT; args[3] = opt->skeldir; + args[4] = login_homemode; DIAG_PUSH_IGNORE_CAST_QUAL; execve(MKHOMEDIR_HELPER, (char **)args, envp); @@ -175,6 +207,9 @@ create_homedir (pam_handle_t *pamh, options_t *opt, dir); } + free(login_umask); + free(login_homemode); + D(("returning %d", retval)); return retval; } |