1 diff -urN Linux-PAM-0.99.7.1.orig/modules/pam_mkhomedir/Makefile.am Linux-PAM-0.99.7.1/modules/pam_mkhomedir/Makefile.am
2 --- Linux-PAM-0.99.7.1.orig/modules/pam_mkhomedir/Makefile.am 2006-06-01 20:53:15.000000000 +0200
3 +++ Linux-PAM-0.99.7.1/modules/pam_mkhomedir/Makefile.am 2007-02-03 22:09:37.950620500 +0100
5 securelib_LTLIBRARIES = pam_mkhomedir.la
6 pam_mkhomedir_la_SOURCES = pam_mkhomedir.c
9 + $(LN_S) pam_mkhomedir.so $(DESTDIR)$(SECUREDIR)/pam_homedir.so
10 + echo ".so pam_mkhomedir.8" > $(DESTDIR)$(man8dir)/pam_homedir.8
12 if ENABLE_REGENERATE_MAN
14 README: pam_mkhomedir.8.xml
15 diff -urN Linux-PAM-0.99.7.1.orig/modules/pam_mkhomedir/pam_mkhomedir.8 Linux-PAM-0.99.7.1/modules/pam_mkhomedir/pam_mkhomedir.8
16 --- Linux-PAM-0.99.7.1.orig/modules/pam_mkhomedir/pam_mkhomedir.8 2006-06-02 17:37:39.000000000 +0200
17 +++ Linux-PAM-0.99.7.1/modules/pam_mkhomedir/pam_mkhomedir.8 2007-02-03 22:09:37.958621000 +0100
19 pam_mkhomedir \- PAM module to create users home directory
22 -\fBpam_mkhomedir.so\fR [silent] [umask=\fImode\fR] [skel=\fIskeldir\fR]
23 +\fBpam_mkhomedir.so\fR [silent] [umask=\fImode\fR] [defmode=\fImode\fR] [minmode=\fImode\fR] [chmod] [notfound=[\fIcreate\fR|\fIdeny\fR|\fIignore\fR]] [skel=\fIskeldir\fR]
26 The pam_mkhomedir PAM module will create a users home directory if it does not exist when the session begins. This allows users to be present in central database (such as NIS, kerberos or LDAP) without using a distributed file system or pre\-creating a large number of directories. The skeleton directory (usually
28 The user file\-creation mask is set to
29 \fImask\fR. The default value of mask is 0022.
31 +\fBdefmode=\fR\fB\fImode\fR\fR
32 +Default permissions for the home directory. The default value of
36 +\fBminmode=\fR\fB\fImode\fR\fR
37 +Minimal permissions for the home directory. The default value of
42 +If this option is specified and home directory access permissions has more bits set than in minmode then do `chmod defmode $HOME`.
44 +\fBnotfound=[\fR\fB\fIcreate\fR\fR\fB|\fR\fB\fIdeny\fR\fR\fB|\fR\fB\fIignore\fR\fR\fB]\fR
45 +What to do if home directory is not found or it is not a directory.
47 +\- default, make home directory;
53 \fBskel=\fR\fB\fI/path/to/skel/directory\fR\fR
54 Indicate an alternative
56 diff -urN Linux-PAM-0.99.7.1.orig/modules/pam_mkhomedir/pam_mkhomedir.8.xml Linux-PAM-0.99.7.1/modules/pam_mkhomedir/pam_mkhomedir.8.xml
57 --- Linux-PAM-0.99.7.1.orig/modules/pam_mkhomedir/pam_mkhomedir.8.xml 2006-05-30 15:03:09.000000000 +0200
58 +++ Linux-PAM-0.99.7.1/modules/pam_mkhomedir/pam_mkhomedir.8.xml 2007-02-03 22:09:37.942620000 +0100
60 umask=<replaceable>mode</replaceable>
63 + defmode=<replaceable>mode</replaceable>
66 + minmode=<replaceable>mode</replaceable>
72 + notfound=[<replaceable>create</replaceable>|<replaceable>deny</replaceable>|<replaceable>ignore</replaceable>]
75 skel=<replaceable>skeldir</replaceable>
82 + <option>defmode=<replaceable>mode</replaceable></option>
86 + Default permissions for the home directory.
87 + The default value of <replaceable>mode</replaceable> is
95 + <option>minmode=<replaceable>mode</replaceable></option>
99 + Minimal permissions for the home directory.
100 + The default value of <replaceable>mode</replaceable> is
108 + <option>chmod</option>
112 + If this option is specified and home directory access
113 + permissions has more bits set than in minmode then
114 + do `chmod defmode $HOME`.
121 + <option>notfound=[<replaceable>create</replaceable>|<replaceable>deny</replaceable>|<replaceable>ignore</replaceable>]</option>
125 + What to do if home directory is not found or it is not a directory.
126 + <replaceable>create</replaceable> - default, make home directory;
127 + <replaceable>deny</replaceable> - deny access;
128 + <replaceable>ignore</replaceable> - do nothing
135 <option>skel=<replaceable>/path/to/skel/directory</replaceable></option>
138 diff -urN Linux-PAM-0.99.7.1.orig/modules/pam_mkhomedir/pam_mkhomedir.c Linux-PAM-0.99.7.1/modules/pam_mkhomedir/pam_mkhomedir.c
139 --- Linux-PAM-0.99.7.1.orig/modules/pam_mkhomedir/pam_mkhomedir.c 2006-12-07 13:34:26.000000000 +0100
140 +++ Linux-PAM-0.99.7.1/modules/pam_mkhomedir/pam_mkhomedir.c 2007-02-03 22:09:37.890616750 +0100
144 /* argument parsing */
145 -#define MKHOMEDIR_DEBUG 020 /* be verbose about things */
146 -#define MKHOMEDIR_QUIET 040 /* keep quiet about things */
148 -static unsigned int UMask = 0022;
149 -static char SkelDir[BUFSIZ] = "/etc/skel"; /* THIS MODULE IS NOT THREAD SAFE */
150 +#define MKHOMEDIR_DEBUG 0x10 /* keep quiet about things */
151 +#define MKHOMEDIR_QUIET 0x20 /* keep quiet about things */
152 +/* what to do, if home directory does not exist? */
153 +#define HOMEDIR_CREATE 0x40 /* create it */
154 +#define HOMEDIR_BARF 0x80 /* deny access */
156 +struct homedir_options {
157 + unsigned int home_access; /* create ~/ by default */
158 + unsigned int default_mode; /* 0755 access rights for home dir */
159 + unsigned int minimal_mode; /* 0755 but this is enough... */
160 + unsigned int umask; /* 0022 umask for ~/ files */
161 + unsigned int do_chmod; /* chmod user ~ if it has insecure permissions */
163 + char skel_dir[PATH_MAX];
165 + char skel_dir[BUFSIZ];
170 -_pam_parse (const pam_handle_t *pamh, int flags, int argc, const char **argv)
171 +_pam_parse (const pam_handle_t *pamh, struct homedir_options *opt,
172 + int flags, int argc, const char **argv)
176 + opt->home_access = HOMEDIR_CREATE;
177 + opt->default_mode = 0755;
178 + opt->minimal_mode = 0755;
181 + strncpy(opt->skel_dir, "/etc/skel", PATH_MAX-1);
182 + opt->skel_dir[PATH_MAX-1] = '\0';
184 + strncpy(opt->skel_dir, "/etc/skel", BUFSIZ-1);
185 + opt->skel_dir[BUFSIZ-1] = '\0';
188 /* does the appliction require quiet? */
189 if ((flags & PAM_SILENT) == PAM_SILENT)
190 ctrl |= MKHOMEDIR_QUIET;
192 if (!strcmp(*argv, "silent")) {
193 ctrl |= MKHOMEDIR_QUIET;
194 } else if (!strncmp(*argv,"umask=",6)) {
195 - UMask = strtol(*argv+6,0,0);
196 + opt->umask = strtol(*argv+6,0,0);
197 + opt->default_mode = opt->minimal_mode = 0777 & ~(opt->umask);
198 + } else if (!strncmp(*argv,"defmode=",8))
199 + opt->default_mode = strtol(*argv+8,0,0);
200 + else if (!strncmp(*argv,"minmode=",8))
201 + opt->minimal_mode = strtol(*argv+8,0,0);
202 + else if (!strncmp(*argv,"chmod",5))
204 + else if (!strncmp(*argv,"notfound=",9))
206 + if (!strcmp(*argv + 9, "create"))
207 + opt->home_access = HOMEDIR_CREATE;
208 + else if (!strcmp(*argv + 9, "deny"))
209 + opt->home_access = HOMEDIR_BARF;
210 + else if (!strcmp(*argv + 9, "ignore"))
211 + opt->home_access &= ~(HOMEDIR_CREATE | HOMEDIR_BARF);
214 + pam_syslog(pamh, LOG_ERR, "unknown parameter for \"create\" option: %s", *argv + 9);
215 + opt->home_access = HOMEDIR_CREATE;
217 } else if (!strncmp(*argv,"skel=",5)) {
218 - strncpy(SkelDir,*argv+5,sizeof(SkelDir));
219 - SkelDir[sizeof(SkelDir)-1] = '\0';
221 + strncpy(opt->skel_dir, *argv+5, PATH_MAX-1);
222 + opt->skel_dir[PATH_MAX-1] = '\0';
224 + strncpy(opt->skel_dir, *argv+5, BUFSIZ-1);
225 + opt->skel_dir[BUFSIZ-1] = '\0';
228 pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
231 /* Do the actual work of creating a home dir */
233 create_homedir (pam_handle_t * pamh, int ctrl,
234 - const struct passwd *pwd,
235 + const struct passwd *pwd, struct homedir_options *opt,
236 const char *source, const char *dest)
240 /* If it's a directory, recurse. */
241 if (S_ISDIR(St.st_mode))
243 - retval = create_homedir (pamh, ctrl, pwd, newsource, newdest);
244 + retval = create_homedir (pamh, ctrl, pwd, opt, newsource, newdest);
247 free(newsource); newsource = NULL;
248 @@ -372,10 +423,10 @@
249 return PAM_PERM_DENIED;
252 - /* Set the proper ownership and permissions for the module. We make
253 + /* Set the proper ownership and permissions for the file. We make
254 the file a+w and then mask it with the set mask. This preseves
256 - if (fchmod(DestFd,(St.st_mode | 0222) & (~UMask)) != 0 ||
257 + if (fchmod(DestFd,(St.st_mode | 0222) & (~opt->umask)) != 0 ||
258 fchown(DestFd,pwd->pw_uid,pwd->pw_gid) != 0)
260 pam_syslog(pamh, LOG_DEBUG,
265 - if (chmod(dest,0777 & (~UMask)) != 0 ||
266 + if (chmod(dest, opt->default_mode) != 0 ||
267 chown(dest,pwd->pw_uid,pwd->pw_gid) != 0)
269 pam_syslog(pamh, LOG_DEBUG,
274 +/* Do the actual work of creating a home dir */
275 +static int check_homedir(pam_handle_t * pamh, int ctrl,
276 + const struct passwd *pwd,
277 + struct homedir_options *opt)
281 + /* Stat the home directory, if something exists then we assume it is
282 + correct and return a success */
283 + if (stat(pwd->pw_dir, &stbuf) == 0) {
284 + if (stbuf.st_mode & ~(opt->minimal_mode | S_IFDIR)) {
285 + /* Aieee, user did something bad to his/hers home */
286 + if (!S_ISDIR(stbuf.st_mode)) {
287 + /* This user home is really broken... */
288 + pam_info(pamh, "Home directory '%s' is not a directory!", pwd->pw_dir);
290 + pam_syslog(pamh, LOG_DEBUG, "directory %s is not a directory (mode 0%o)", pwd->pw_dir, stbuf.st_mode);
291 + if (opt->home_access == HOMEDIR_BARF)
292 + return PAM_PERM_DENIED;
293 + else if (opt->home_access == HOMEDIR_CREATE) {
294 + pam_syslog(pamh, LOG_DEBUG, "trying to unlink directory %s", pwd->pw_dir);
295 + if (unlink(pwd->pw_dir) == -1) {
296 + pam_syslog(pamh, LOG_DEBUG, "failed to unlink directory %s", pwd->pw_dir);
297 + return PAM_PERM_DENIED;
300 + return PAM_SUCCESS;
302 + pam_info(pamh, "Home directory '%s' has insecure permissions 0%o.",
303 + pwd->pw_dir, stbuf.st_mode);
305 + pam_syslog(pamh, LOG_DEBUG, "directory %s has insecure permissions 0%o", pwd->pw_dir, stbuf.st_mode);
308 + if (chmod(pwd->pw_dir, opt->default_mode) < 0) {
309 + pam_syslog(pamh, LOG_DEBUG, "unable to chmod home directory %s", pwd->pw_dir);
310 + return PAM_PERM_DENIED;
312 + return PAM_SUCCESS;
315 + return PAM_SUCCESS;
318 + switch (opt->home_access) {
319 + case HOMEDIR_CREATE:
320 + return create_homedir(pamh, ctrl, pwd, opt, opt->skel_dir, pwd->pw_dir);
322 + return PAM_PERM_DENIED;
324 + return PAM_SUCCESS;
327 + /* If we ever get here sue authors of the compiler */
328 + return PAM_SERVICE_ERR;
331 /* --- authentication management functions (only) --- */
334 @@ -456,10 +572,10 @@
337 const struct passwd *pwd;
339 + struct homedir_options opt;
341 /* Parse the flag values */
342 - ctrl = _pam_parse(pamh, flags, argc, argv);
343 + ctrl = _pam_parse(pamh, &opt, flags, argc, argv);
345 /* Determine the user name so we can get the home directory */
346 retval = pam_get_item(pamh, PAM_USER, &user);
348 return PAM_CRED_INSUFFICIENT;
351 - /* Stat the home directory, if something exists then we assume it is
352 - correct and return a success*/
353 - if (stat(pwd->pw_dir,&St) == 0)
354 - return PAM_SUCCESS;
356 - return create_homedir(pamh,ctrl,pwd,SkelDir,pwd->pw_dir);
357 + return check_homedir(pamh, ctrl, pwd, &opt);