summaryrefslogtreecommitdiff
path: root/modules/pam_mkhomedir/pam_mkhomedir.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/pam_mkhomedir/pam_mkhomedir.c')
-rw-r--r--modules/pam_mkhomedir/pam_mkhomedir.c49
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;
}