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 pam_mkhomedir_la_SOURCES = pam_mkhomedir.c
6 pam_mkhomedir_la_LIBADD = -L$(top_builddir)/libpam -lpam
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.xml Linux-PAM-0.99.7.1/modules/pam_mkhomedir/pam_mkhomedir.8.xml
16 --- Linux-PAM-0.99.7.1.orig/modules/pam_mkhomedir/pam_mkhomedir.8.xml 2006-05-30 15:03:09.000000000 +0200
17 +++ Linux-PAM-0.99.7.1/modules/pam_mkhomedir/pam_mkhomedir.8.xml 2007-02-03 22:09:37.942620000 +0100
19 umask=<replaceable>mode</replaceable>
22 + defmode=<replaceable>mode</replaceable>
25 + minmode=<replaceable>mode</replaceable>
31 + notfound=[<replaceable>create</replaceable>|<replaceable>deny</replaceable>|<replaceable>ignore</replaceable>]
34 skel=<replaceable>skeldir</replaceable>
41 + <option>defmode=<replaceable>mode</replaceable></option>
45 + Default permissions for the home directory.
46 + The default value of <replaceable>mode</replaceable> is
54 + <option>minmode=<replaceable>mode</replaceable></option>
58 + Minimal permissions for the home directory.
59 + The default value of <replaceable>mode</replaceable> is
67 + <option>chmod</option>
71 + If this option is specified and home directory access
72 + permissions has more bits set than in minmode then
73 + do `chmod defmode $HOME`.
80 + <option>notfound=[<replaceable>create</replaceable>|<replaceable>deny</replaceable>|<replaceable>ignore</replaceable>]</option>
84 + What to do if home directory is not found or it is not a directory.
85 + <replaceable>create</replaceable> - default, make home directory;
86 + <replaceable>deny</replaceable> - deny access;
87 + <replaceable>ignore</replaceable> - do nothing
94 <option>skel=<replaceable>/path/to/skel/directory</replaceable></option>
97 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
98 --- Linux-PAM-0.99.7.1.orig/modules/pam_mkhomedir/pam_mkhomedir.c 2006-12-07 13:34:26.000000000 +0100
99 +++ Linux-PAM-0.99.7.1/modules/pam_mkhomedir/pam_mkhomedir.c 2007-02-03 22:09:37.890616750 +0100
103 /* argument parsing */
104 -#define MKHOMEDIR_DEBUG 020 /* be verbose about things */
105 -#define MKHOMEDIR_QUIET 040 /* keep quiet about things */
107 -static unsigned int UMask = 0022;
108 -static char SkelDir[BUFSIZ] = "/etc/skel"; /* THIS MODULE IS NOT THREAD SAFE */
109 +#define MKHOMEDIR_DEBUG 0x10 /* keep quiet about things */
110 +#define MKHOMEDIR_QUIET 0x20 /* keep quiet about things */
111 +/* what to do, if home directory does not exist? */
112 +#define HOMEDIR_CREATE 0x40 /* create it */
113 +#define HOMEDIR_BARF 0x80 /* deny access */
115 +struct homedir_options {
116 + unsigned int home_access; /* create ~/ by default */
117 + unsigned int default_mode; /* 0755 access rights for home dir */
118 + unsigned int minimal_mode; /* 0755 but this is enough... */
119 + unsigned int umask; /* 0022 umask for ~/ files */
120 + unsigned int do_chmod; /* chmod user ~ if it has insecure permissions */
122 + char skel_dir[PATH_MAX];
124 + char skel_dir[BUFSIZ];
129 -_pam_parse (const pam_handle_t *pamh, int flags, int argc, const char **argv)
130 +_pam_parse (const pam_handle_t *pamh, struct homedir_options *opt,
131 + int flags, int argc, const char **argv)
135 + opt->home_access = HOMEDIR_CREATE;
136 + opt->default_mode = 0755;
137 + opt->minimal_mode = 0755;
140 + strncpy(opt->skel_dir, "/etc/skel", PATH_MAX-1);
141 + opt->skel_dir[PATH_MAX-1] = '\0';
143 + strncpy(opt->skel_dir, "/etc/skel", BUFSIZ-1);
144 + opt->skel_dir[BUFSIZ-1] = '\0';
147 /* does the appliction require quiet? */
148 if ((flags & PAM_SILENT) == PAM_SILENT)
149 ctrl |= MKHOMEDIR_QUIET;
151 } else if (!strcmp(*argv, "debug")) {
152 ctrl |= MKHOMEDIR_DEBUG;
153 } else if (!strncmp(*argv,"umask=",6)) {
154 - UMask = strtol(*argv+6,0,0);
155 + opt->umask = strtol(*argv+6,0,0);
156 + opt->default_mode = opt->minimal_mode = 0777 & ~(opt->umask);
157 + } else if (!strncmp(*argv,"defmode=",8))
158 + opt->default_mode = strtol(*argv+8,0,0);
159 + else if (!strncmp(*argv,"minmode=",8))
160 + opt->minimal_mode = strtol(*argv+8,0,0);
161 + else if (!strncmp(*argv,"chmod",5))
163 + else if (!strncmp(*argv,"notfound=",9))
165 + if (!strcmp(*argv + 9, "create"))
166 + opt->home_access = HOMEDIR_CREATE;
167 + else if (!strcmp(*argv + 9, "deny"))
168 + opt->home_access = HOMEDIR_BARF;
169 + else if (!strcmp(*argv + 9, "ignore"))
170 + opt->home_access &= ~(HOMEDIR_CREATE | HOMEDIR_BARF);
173 + pam_syslog(pamh, LOG_ERR, "unknown parameter for \"create\" option: %s", *argv + 9);
174 + opt->home_access = HOMEDIR_CREATE;
176 } else if (!strncmp(*argv,"skel=",5)) {
177 - strncpy(SkelDir,*argv+5,sizeof(SkelDir));
178 - SkelDir[sizeof(SkelDir)-1] = '\0';
180 + strncpy(opt->skel_dir, *argv+5, PATH_MAX-1);
181 + opt->skel_dir[PATH_MAX-1] = '\0';
183 + strncpy(opt->skel_dir, *argv+5, BUFSIZ-1);
184 + opt->skel_dir[BUFSIZ-1] = '\0';
187 pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
190 /* Do the actual work of creating a home dir */
192 create_homedir (pam_handle_t * pamh, int ctrl,
193 - const struct passwd *pwd,
194 + const struct passwd *pwd, struct homedir_options *opt,
195 const char *source, const char *dest)
199 /* If it's a directory, recurse. */
200 if (S_ISDIR(St.st_mode))
202 - retval = create_homedir (pamh, ctrl, pwd, newsource, newdest);
203 + retval = create_homedir (pamh, ctrl, pwd, opt, newsource, newdest);
206 free(newsource); newsource = NULL;
207 @@ -372,10 +423,10 @@
208 return PAM_PERM_DENIED;
211 - /* Set the proper ownership and permissions for the module. We make
212 + /* Set the proper ownership and permissions for the file. We make
213 the file a+w and then mask it with the set mask. This preseves
215 - if (fchmod(DestFd,(St.st_mode | 0222) & (~UMask)) != 0 ||
216 + if (fchmod(DestFd,(St.st_mode | 0222) & (~opt->umask)) != 0 ||
217 fchown(DestFd,pwd->pw_uid,pwd->pw_gid) != 0)
219 pam_syslog(pamh, LOG_DEBUG,
224 - if (chmod(dest,0777 & (~UMask)) != 0 ||
225 + if (chmod(dest, opt->default_mode) != 0 ||
226 chown(dest,pwd->pw_uid,pwd->pw_gid) != 0)
228 pam_syslog(pamh, LOG_DEBUG,
233 +/* Do the actual work of creating a home dir */
234 +static int check_homedir(pam_handle_t * pamh, int ctrl,
235 + const struct passwd *pwd,
236 + struct homedir_options *opt)
240 + /* Stat the home directory, if something exists then we assume it is
241 + correct and return a success */
242 + if (stat(pwd->pw_dir, &stbuf) == 0) {
243 + if (stbuf.st_mode & ~(opt->minimal_mode | S_IFDIR)) {
244 + /* Aieee, user did something bad to his/hers home */
245 + if (!S_ISDIR(stbuf.st_mode)) {
246 + /* This user home is really broken... */
247 + pam_info(pamh, "Home directory '%s' is not a directory!", pwd->pw_dir);
249 + pam_syslog(pamh, LOG_DEBUG, "directory %s is not a directory (mode 0%o)", pwd->pw_dir, stbuf.st_mode);
250 + if (opt->home_access == HOMEDIR_BARF)
251 + return PAM_PERM_DENIED;
252 + else if (opt->home_access == HOMEDIR_CREATE) {
253 + pam_syslog(pamh, LOG_DEBUG, "trying to unlink directory %s", pwd->pw_dir);
254 + if (unlink(pwd->pw_dir) == -1) {
255 + pam_syslog(pamh, LOG_DEBUG, "failed to unlink directory %s", pwd->pw_dir);
256 + return PAM_PERM_DENIED;
259 + return PAM_SUCCESS;
261 + pam_info(pamh, "Home directory '%s' has insecure permissions 0%o.",
262 + pwd->pw_dir, stbuf.st_mode);
264 + pam_syslog(pamh, LOG_DEBUG, "directory %s has insecure permissions 0%o", pwd->pw_dir, stbuf.st_mode);
267 + if (chmod(pwd->pw_dir, opt->default_mode) < 0) {
268 + pam_syslog(pamh, LOG_DEBUG, "unable to chmod home directory %s", pwd->pw_dir);
269 + return PAM_PERM_DENIED;
271 + return PAM_SUCCESS;
274 + return PAM_SUCCESS;
277 + switch (opt->home_access) {
278 + case HOMEDIR_CREATE:
279 + return create_homedir(pamh, ctrl, pwd, opt, opt->skel_dir, pwd->pw_dir);
281 + return PAM_PERM_DENIED;
283 + return PAM_SUCCESS;
286 + /* If we ever get here sue authors of the compiler */
287 + return PAM_SERVICE_ERR;
290 /* --- authentication management functions (only) --- */
293 @@ -456,10 +572,10 @@
296 const struct passwd *pwd;
298 + struct homedir_options opt;
300 /* Parse the flag values */
301 - ctrl = _pam_parse(pamh, flags, argc, argv);
302 + ctrl = _pam_parse(pamh, &opt, flags, argc, argv);
304 /* Determine the user name so we can get the home directory */
305 retval = pam_get_item(pamh, PAM_USER, &user);
307 return PAM_CRED_INSUFFICIENT;
310 - /* Stat the home directory, if something exists then we assume it is
311 - correct and return a success*/
312 - if (stat(pwd->pw_dir,&St) == 0)
313 - return PAM_SUCCESS;
315 - return create_homedir(pamh,ctrl,pwd,SkelDir,pwd->pw_dir);
316 + return check_homedir(pamh, ctrl, pwd, &opt);