Blob Blame History Raw
diff -upb shadow-4.1.0/libmisc/system.c.selinux shadow-4.1.0/libmisc/system.c
--- shadow-4.1.0/libmisc/system.c.selinux	2008-03-03 14:18:17.000000000 +0100
+++ shadow-4.1.0/libmisc/system.c	2008-03-03 14:18:17.000000000 +0100
@@ -0,0 +1,37 @@
+#include <config.h>
+
+#ident "$Id: shell.c,v 1.13 2006/01/18 19:38:27 kloczek Exp $"
+
+#include <stdio.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include "prototypes.h"
+#include "defines.h"
+
+int safe_system(const char *command, const char *argv[], const char *env[], int ignore_stderr)
+{
+	int status = -1;
+	int fd;
+	pid_t pid;
+	
+	pid = fork();
+	if (pid < 0) 
+		return -1;
+
+	if (pid) {       /* Parent */
+		waitpid(pid, &status, 0);
+		return status;
+	}
+
+	fd = open("/dev/null", O_RDWR);
+	/* Child */
+	dup2(fd,0);	// Close Stdin
+	if (ignore_stderr)
+		dup2(fd,2);	// Close Stderr
+	
+	execve(command, (char *const *) argv, (char *const *) env);
+	fprintf (stderr,
+		 _("Failed to exec '%s'\n"), argv[0]);
+	exit (-1);
+}
+
diff -upb shadow-4.1.0/libmisc/Makefile.am.selinux shadow-4.1.0/libmisc/Makefile.am
--- shadow-4.1.0/libmisc/Makefile.am.selinux	2007-11-23 10:15:48.000000000 +0100
+++ shadow-4.1.0/libmisc/Makefile.am	2008-03-03 14:18:17.000000000 +0100
@@ -42,6 +42,7 @@ libmisc_a_SOURCES = \
 	setugid.c \
 	setupenv.c \
 	shell.c \
+	system.c \
 	strtoday.c \
 	sub.c \
 	sulog.c \
diff -upb shadow-4.1.0/libmisc/copydir.c.selinux shadow-4.1.0/libmisc/copydir.c
--- shadow-4.1.0/libmisc/copydir.c.selinux	2007-11-11 00:45:59.000000000 +0100
+++ shadow-4.1.0/libmisc/copydir.c	2008-03-03 14:19:01.000000000 +0100
@@ -54,7 +54,7 @@ struct link_name {
 static struct link_name *links;
 
 #ifdef WITH_SELINUX
-static int selinux_file_context (const char *dst_name)
+int selinux_file_context (const char *dst_name)
 {
 	security_context_t scontext = NULL;
 
@@ -199,7 +199,7 @@ int copy_tree (const char *src_root, con
 		if (strlen (src_root) + strlen (ent->d_name) + 2 >
 		    sizeof src_name) {
 			err++;
-			break;
+			break;
 		}
 		snprintf (src_name, sizeof src_name, "%s/%s", src_root,
 			  ent->d_name);
@@ -207,7 +207,7 @@ int copy_tree (const char *src_root, con
 		if (strlen (dst_root) + strlen (ent->d_name) + 2 >
 		    sizeof dst_name) {
 			err++;
-			break;
+			break;
 		}
 		snprintf (dst_name, sizeof dst_name, "%s/%s", dst_root,
 			  ent->d_name);
@@ -313,7 +313,7 @@ int copy_tree (const char *src_root, con
 			if (mknod (dst_name, sb.st_mode & ~07777, sb.st_rdev)
 			    || chown (dst_name,
 				      uid == (uid_t) - 1 ? sb.st_uid : uid,
-				      gid == (gid_t) - 1 ? sb.st_gid : gid)
+				      gid == (gid_t) - 1 ? sb.st_gid : gid)
 			    || chmod (dst_name, sb.st_mode & 07777)) {
 				err++;
 				break;
@@ -363,6 +363,10 @@ int copy_tree (const char *src_root, con
 		src_orig = 0;
 		dst_orig = 0;
 	}
+#ifdef WITH_SELINUX
+	/* Reset SELinux to create files with default contexts */
+	setfscreatecon (NULL);
+#endif
 	return err ? -1 : 0;
 }
 
diff -upb shadow-4.1.0/man/usermod.8.xml.selinux shadow-4.1.0/man/usermod.8.xml
--- shadow-4.1.0/man/usermod.8.xml.selinux	2007-12-09 00:24:36.000000000 +0100
+++ shadow-4.1.0/man/usermod.8.xml	2008-03-03 14:18:17.000000000 +0100
@@ -245,6 +245,19 @@
 	  </para>
 	</listitem>
       </varlistentry>
+       <varlistentry>
+        <term>
+         <option>-Z</option>, <option>--selinux-user</option>
+         <replaceable>SEUSER</replaceable>
+       </term>
+       <listitem>
+         <para>
+           The SELinux user for the user's login. The default is to leave this
+           field the blank, which causes the system to select the default
+           SELinux user.
+         </para>
+       </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
diff -upb shadow-4.1.0/man/useradd.8.selinux shadow-4.1.0/man/useradd.8
--- shadow-4.1.0/man/useradd.8.selinux	2008-03-03 14:14:45.000000000 +0100
+++ shadow-4.1.0/man/useradd.8	2008-03-03 14:18:17.000000000 +0100
@@ -163,6 +163,11 @@ doesn\'t work yet\.
 Allow the creation of a user account with a duplicate (non\-unique) UID\.
 .RE
 .PP
+\fB\-Z\fR, \fB\-\-selinux-user\fR \fISEUSER\fR
+.RS 4
+The SELinux user for the user\'s login\. The default is to leave this field blank, which causes the system to select the default SELinux user\.
+.RE
+.PP
 \fB\-p\fR, \fB\-\-password\fR \fIPASSWORD\fR
 .RS 4
 The encrypted password, as returned by
diff -upb shadow-4.1.0/man/usermod.8.selinux shadow-4.1.0/man/usermod.8
--- shadow-4.1.0/man/usermod.8.selinux	2007-12-10 00:07:16.000000000 +0100
+++ shadow-4.1.0/man/usermod.8	2008-03-03 14:18:17.000000000 +0100
@@ -133,6 +133,11 @@ Note: if you wish to unlock the account 
 value from
 \fI/etc/default/useradd\fR)\.
 .RE
+.PP
+\fB\-Z\fR, \fB\-\-selinux-user\fR \fISEUSER\fR
+.RS 4
+The SELinux user for the user\'s login\. The default is to leave this field blank, which causes the system to select the default SELinux user.
+.RE
 .SH "CAVEATS"
 .PP
 
diff -upb shadow-4.1.0/man/useradd.8.xml.selinux shadow-4.1.0/man/useradd.8.xml
--- shadow-4.1.0/man/useradd.8.xml.selinux	2007-12-09 00:24:36.000000000 +0100
+++ shadow-4.1.0/man/useradd.8.xml	2008-03-03 14:18:17.000000000 +0100
@@ -273,6 +273,19 @@
 	    between 0 and 999 are typically reserved for system accounts.
 	  </para>
 	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term>
+	  <option>-Z</option>, <option>--selinux-user</option>
+	  <replaceable>SEUSER</replaceable>
+	</term>
+	<listitem>
+	  <para>
+	    The SELinux user for the user's login. The default is to leave this
+	    field blank, which causes the system to select the default SELinux
+            user.
+	  </para>
+	</listitem>
       </varlistentry>
     </variablelist>
 
@@ -346,7 +359,7 @@
 	    </para>
 	  </listitem>
 	</varlistentry>
-      </variablelist>
+      </variablelist>
 
     </refsect2>
   </refsect1>
@@ -399,7 +412,7 @@
 
   <refsect1 id='files'>
     <title>FILES</title>
-    <variablelist>
+    <variablelist>
       <varlistentry>
 	<term><filename>/etc/passwd</filename></term>
 	<listitem>
diff -upb shadow-4.1.0/lib/prototypes.h.selinux shadow-4.1.0/lib/prototypes.h
--- shadow-4.1.0/lib/prototypes.h.selinux	2007-11-23 21:10:52.000000000 +0100
+++ shadow-4.1.0/lib/prototypes.h	2008-03-03 14:18:17.000000000 +0100
@@ -53,6 +53,9 @@ extern int is_listed (const char *, cons
 /* copydir.c */
 extern int copy_tree (const char *, const char *, uid_t, gid_t);
 extern int remove_tree (const char *);
+#ifdef WITH_SELINUX
+extern int selinux_file_context (const char *dst_name);
+#endif
 
 /* encrypt.c */
 extern char *pw_encrypt (const char *, const char *);
@@ -151,6 +154,9 @@ extern void setup_env (struct passwd *);
 /* shell.c */
 extern int shell (const char *, const char *, char *const *);
 
+/* system.c */
+extern int safe_system(const char *command, const char *argv[], const char *env[], int ignore_stderr);
+
 /* strtoday.c */
 extern long strtoday (const char *);
 
diff -upb shadow-4.1.0/lib/defines.h.selinux shadow-4.1.0/lib/defines.h
--- shadow-4.1.0/lib/defines.h.selinux	2007-11-24 12:18:35.000000000 +0100
+++ shadow-4.1.0/lib/defines.h	2008-03-03 14:18:17.000000000 +0100
@@ -342,4 +342,7 @@ extern char *strerror ();
 #include <libaudit.h>
 #endif
 
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#endif
 #endif				/* _DEFINES_H_ */
diff -upb shadow-4.1.0/src/userdel.c.selinux shadow-4.1.0/src/userdel.c
--- shadow-4.1.0/src/userdel.c.selinux	2007-11-24 23:41:19.000000000 +0100
+++ shadow-4.1.0/src/userdel.c	2008-03-03 14:18:17.000000000 +0100
@@ -809,6 +809,17 @@ int main (int argc, char **argv)
 #endif
 	}
 
+#ifdef WITH_SELINUX
+	if (is_selinux_enabled() > 0) { 
+		const char *argv[5];
+		argv[0] = "/usr/sbin/semanage";
+		argv[1] = "login";
+		argv[2] = "-d";
+		argv[3] = user_name;
+		argv[4] = NULL;
+                safe_system(argv[0], argv, NULL, 1);
+        }
+#endif        
 	/*
 	 * Cancel any crontabs or at jobs. Have to do this before we remove
 	 * the entry from /etc/passwd.
diff -upb shadow-4.1.0/src/usermod.c.selinux shadow-4.1.0/src/usermod.c
--- shadow-4.1.0/src/usermod.c.selinux	2007-11-24 23:41:19.000000000 +0100
+++ shadow-4.1.0/src/usermod.c	2008-03-03 14:18:17.000000000 +0100
@@ -90,6 +90,7 @@ static char *user_comment;
 static char *user_home;
 static char *user_newhome;
 static char *user_shell;
+static const char *user_selinux = "";
 static long user_expire;
 static long user_inactive;
 static long sys_ngroups;
@@ -139,6 +140,7 @@ static int sgr_locked = 0;
 static int get_groups (char *);
 static void usage (void);
 static void new_pwent (struct passwd *);
+static void selinux_update_mapping (void);
 
 static void new_spent (struct spwd *);
 static void fail_exit (int);
@@ -250,12 +252,12 @@ static int get_groups (char *list)
 #endif
 
 		if (ngroups == sys_ngroups) {
-			fprintf (stderr,
+			fprintf (stderr,
 				 _
 				 ("%s: too many groups specified (max %d).\n"),
 				 Prog, ngroups);
 			break;
-		}
+		}
 
 		/*
 		 * Add the group name to the user's list of groups.
@@ -302,6 +304,9 @@ static void usage (void)
 			   "  -s, --shell SHELL             new login shell for the user account\n"
 			   "  -u, --uid UID                 new UID for the user account\n"
 			   "  -U, --unlock                  unlock the user account\n"
+#ifdef WITH_SELINUX
+                           "  -Z, --selinux-user            new selinux user mapping for the user account\n"
+#endif
 			   "\n"));
 	exit (E_USAGE);
 }
@@ -332,7 +337,7 @@ static char *new_pw_passwd (char *pw_pas
 				   "You should set a password with usermod -p to unlock this user account.\n"),
 				 Prog);
 			return pw_pass;
-		}
+		}
 
 #ifdef WITH_AUDIT
 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "updating password",
@@ -405,7 +410,7 @@ static void new_pwent (struct passwd *pw
 #else
 		pwent->pw_gecos = user_comment;
 #endif
-	}
+	}
 
 	if (dflg) {
 #ifdef WITH_AUDIT
@@ -826,7 +831,7 @@ static void process_flags (int argc, cha
 		user_comment = xstrdup (pwd->pw_gecos);
 		user_home = xstrdup (pwd->pw_dir);
 		user_shell = xstrdup (pwd->pw_shell);
-	}
+	}
 #ifdef WITH_AUDIT
 	user_newname = user_name;
 	user_newid = user_id;
@@ -888,13 +893,20 @@ static void process_flags (int argc, cha
 			{"move-home", no_argument, NULL, 'm'},
 			{"non-unique", no_argument, NULL, 'o'},
 			{"password", required_argument, NULL, 'p'},
+#ifdef WITH_SELINUX
+			{"selinux-user", required_argument, NULL, 'Z'},
+#endif
 			{"shell", required_argument, NULL, 's'},
 			{"uid", required_argument, NULL, 'u'},
 			{"unlock", no_argument, NULL, 'U'},
 			{NULL, 0, NULL, '\0'}
 		};
 		while ((c =
+#ifdef WITH_SELINUX
+			getopt_long (argc, argv, "ac:d:e:f:g:G:hl:Lmop:s:u:UZ:",
+#else
 			getopt_long (argc, argv, "ac:d:e:f:g:G:hl:Lmop:s:u:U",
+#endif
 				     long_options, NULL)) != -1) {
 			switch (c) {
 			case 'a':
@@ -966,7 +978,7 @@ static void process_flags (int argc, cha
 					fprintf (stderr,
 						 _("%s: unknown group %s\n"),
 						 Prog, optarg);
-					exit (E_NOTFOUND);
+					exit (E_NOTFOUND);
 				}
 				user_newgid = grp->gr_gid;
 				gflg++;
@@ -1028,6 +1040,16 @@ static void process_flags (int argc, cha
 			case 'U':
 				Uflg++;
 				break;
+#ifdef WITH_SELINUX
+                        case 'Z':
+				if (is_selinux_enabled() > 0)
+					user_selinux = optarg;
+				else {
+					fprintf (stderr, _("%s: -Z requires SELinux enabled kernel\n"), Prog);
+					exit (E_BAD_ARG);
+				}
+                                break;
+#endif
 			default:
 				usage ();
 			}
@@ -1040,7 +1062,7 @@ static void process_flags (int argc, cha
 		exit (E_USAGE);
 	}
 	if (!is_shadow_pwd && (eflg || fflg)) {
-		fprintf (stderr,
+		fprintf (stderr,
 			 _
 			 ("%s: shadow passwords required for -e and -f\n"),
 			 Prog);
@@ -1575,6 +1597,8 @@ int main (int argc, char **argv)
 	nscd_flush_cache ("passwd");
 	nscd_flush_cache ("group");
 
+	selinux_update_mapping();
+
 	if (mflg)
 		move_home ();
 
@@ -1603,3 +1627,62 @@ int main (int argc, char **argv)
 	exit (E_SUCCESS);
 	/* NOT REACHED */
 }
+
+static void selinux_update_mapping () {
+#ifdef WITH_SELINUX
+	const char *argv[7];
+
+	if (is_selinux_enabled() <= 0) return;
+
+        if (*user_selinux) { 
+		argv[0] = "/usr/sbin/semanage";
+		argv[1] = "login";
+		argv[2] = "-m";
+		argv[3] = "-s";
+		argv[4] = user_selinux;
+		argv[5] = user_name;
+		argv[6] = NULL;
+                if (safe_system(argv[0], argv, NULL, 1)) {
+			argv[2] = "-a";
+			if (safe_system(argv[0], argv, NULL, 0)) {
+				fprintf (stderr,
+					 _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"),
+					 Prog, user_name, user_selinux);
+#ifdef WITH_AUDIT
+				audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+					      "modifying User mapping ", user_name, user_id, 0);
+#endif        
+			}
+		}
+        }
+        
+	if (dflg || *user_selinux) {
+		argv[0] = "/usr/sbin/genhomedircon";
+		argv[1] = NULL;
+		if(safe_system(argv[0], argv, NULL,0)) {
+			fprintf (stderr,
+				 _("%s: warning: unable to relabel the homedir %s for %s.\n"),
+				 Prog, user_home, user_name);
+#ifdef WITH_AUDIT
+			audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+			      "relabeling home directory", user_name, user_id, 0);
+#endif
+		}
+
+		argv[0] = "/sbin/restorecon";
+		argv[1] = "-F";
+		argv[2] = "-R";
+		argv[3] = user_home;
+		argv[4] = NULL;
+                if (safe_system(argv[0], argv, NULL, 0)) {
+			fprintf (stderr,
+				 _("%s: warning: unable to relabel the homedir %s for %s.\n"),
+				 Prog, user_home, user_name);
+#ifdef WITH_AUDIT
+			audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+				      "relabeling home directory", user_name, user_id, 0);
+#endif        
+		}
+	}
+#endif
+}
diff -upb shadow-4.1.0/src/useradd.c.selinux shadow-4.1.0/src/useradd.c
--- shadow-4.1.0/src/useradd.c.selinux	2008-03-03 14:14:45.000000000 +0100
+++ shadow-4.1.0/src/useradd.c	2008-03-03 14:19:01.000000000 +0100
@@ -100,6 +100,7 @@ static const char *user_comment = "";
 static const char *user_home = "";
 static const char *user_shell = "";
 static const char *create_mail_spool = "";
+static const char *user_selinux = "";
 
 static long user_expire = -1;
 static int is_shadow_pwd;
@@ -170,6 +171,7 @@ static int set_defaults (void);
 static int get_groups (char *);
 static void usage (void);
 static void new_pwent (struct passwd *);
+static void selinux_update_mapping (void);
 
 static long scale_age (long);
 static void new_spent (struct spwd *);
@@ -356,6 +358,7 @@ static void get_defaults (void)
 			def_create_mail_spool = xstrdup (cp);
 		}
 	}
+	fclose(fp);
 }
 
 /*
@@ -586,7 +589,7 @@ static int get_groups (char *list)
 #endif
 
 		if (ngroups == sys_ngroups) {
-			fprintf (stderr,
+			fprintf (stderr,
 				 _
 				 ("%s: too many groups specified (max %d).\n"),
 				 Prog, ngroups);
@@ -644,6 +647,10 @@ static void usage (void)
 			   "                                account\n"
 			   "  -s, --shell SHELL             the login shell for the new user account\n"
 			   "  -u, --uid UID                 force use the UID for the new user account\n"
+#ifdef WITH_SELINUX
+                           "  -Z, --selinux-user SEUSER     use a specific SEUSER for the SELinux user mapping\n"
+#endif
+
 			   "\n"));
 	exit (E_USAGE);
 }
@@ -696,7 +703,7 @@ static void new_spent (struct spwd *spen
 		spent->sp_warn = scale_age (getdef_num ("PASS_WARN_AGE", -1));
 		spent->sp_inact = scale_age (def_inactive);
 		spent->sp_expire = scale_age (user_expire);
-	}
+	}
 	else {
 		spent->sp_min = scale_age(-1);
                 spent->sp_max = scale_age(-1);
@@ -1030,32 +1037,39 @@ static void process_flags (int argc, cha
 			{"non-unique", no_argument, NULL, 'o'},
 			{"password", required_argument, NULL, 'p'},
 			{"shell", required_argument, NULL, 's'},
+#ifdef WITH_SELINUX
+			{"selinux-user", required_argument, NULL, 'Z'},
+#endif
 			{"uid", required_argument, NULL, 'u'},
 			{NULL, 0, NULL, '\0'}
 		};
 		while ((c =
+#ifdef WITH_SELINUX
+			getopt_long (argc, argv, "b:c:d:De:f:g:G:k:K:mlMnrop:s:u:Z:",
+#else
 			getopt_long (argc, argv, "b:c:d:De:f:g:G:k:K:mlMnrop:s:u:",
+#endif
 				     long_options, NULL)) != -1) {
 			switch (c) {
 			case 'b':
 				if (!VALID (optarg)
 				    || optarg[0] != '/') {
-					fprintf (stderr,
+					fprintf (stderr,
 						 _
 						 ("%s: invalid base directory '%s'\n"),
 						 Prog, optarg);
-					exit (E_BAD_ARG);
+					exit (E_BAD_ARG);
 				}
 				def_home = optarg;
 				bflg++;
 				break;
 			case 'c':
 				if (!VALID (optarg)) {
-					fprintf (stderr,
+					fprintf (stderr,
 						 _
 						 ("%s: invalid comment '%s'\n"),
 						 Prog, optarg);
-					exit (E_BAD_ARG);
+					exit (E_BAD_ARG);
 				}
 				user_comment = optarg;
 				cflg++;
@@ -1063,11 +1077,11 @@ static void process_flags (int argc, cha
 			case 'd':
 				if (!VALID (optarg)
 				    || optarg[0] != '/') {
-					fprintf (stderr,
+					fprintf (stderr,
 						 _
 						 ("%s: invalid home directory '%s'\n"),
 						 Prog, optarg);
-					exit (E_BAD_ARG);
+					exit (E_BAD_ARG);
 				}
 				user_home = optarg;
 				dflg++;
@@ -1161,7 +1175,7 @@ static void process_flags (int argc, cha
 						 _
 						 ("%s: -K requires KEY=VALUE\n"),
 						 Prog);
-					exit (E_BAD_ARG);
+					exit (E_BAD_ARG);
 				}
 				/* terminate name, point to value */
 				*cp++ = '\0';
@@ -1215,6 +1229,17 @@ static void process_flags (int argc, cha
                         case 'M':
                                 Mflg++;
                                 break;
+#ifdef WITH_SELINUX
+                        case 'Z':
+				if (is_selinux_enabled() > 0)
+					user_selinux = optarg;
+				else {
+					fprintf (stderr,_("%s: -Z requires SELinux enabled kernel\n"), Prog);
+
+					exit (E_BAD_ARG);
+				}
+                                break;
+#endif
 			default:
 				usage ();
 			}
@@ -1238,7 +1263,7 @@ static void process_flags (int argc, cha
 	 */
 	if (Dflg) {
 		if (optind != argc)
-			usage ();
+			usage ();
 
 		if (uflg || oflg || Gflg || dflg || cflg || mflg)
 			usage ();
@@ -1253,7 +1278,7 @@ static void process_flags (int argc, cha
 				 ("%s: invalid user name '%s'\n"),
 				 Prog, user_name);
 #ifdef WITH_AUDIT
-			audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user",
+			audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user",
 				      user_name, -1, 0);
 #endif
 			exit (E_BAD_ARG);
@@ -1583,6 +1608,33 @@ static void usr_update (void)
 		grp_update ();
 }
 
+static void selinux_update_mapping () {
+
+#ifdef WITH_SELINUX
+	if (is_selinux_enabled() <= 0) return;
+
+        if (*user_selinux) { /* must be done after passwd write() */
+		const char *argv[7];
+		argv[0] = "/usr/sbin/semanage";
+		argv[1] = "login";
+		argv[2] = "-a";
+		argv[3] = "-s";
+		argv[4] = user_selinux;
+		argv[5] = user_name;
+		argv[6] = NULL;
+                if (safe_system(argv[0], argv, NULL, 0)) {
+			fprintf (stderr,
+				 _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"),
+				 Prog, user_name, user_selinux);
+#ifdef WITH_AUDIT
+			audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+				      "adding SELinux user mapping", user_name, user_id, 0);
+#endif        
+		}
+	}
+#endif
+
+}
 /*
  * create_home - create the user's home directory
  *
@@ -1592,7 +1644,11 @@ static void usr_update (void)
  */
 static void create_home (void)
 {
+
 	if (access (user_home, F_OK)) {
+#ifdef WITH_SELINUX
+		selinux_file_context (user_home);
+#endif
 		/* XXX - create missing parent directories.  --marekm */
 		if (mkdir (user_home, 0)) {
 			fprintf (stderr,
@@ -1614,6 +1670,10 @@ static void create_home (void)
 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
 			      "adding home directory", user_name, user_id, 1);
 #endif
+#ifdef WITH_SELINUX
+	/* Reset SELinux to create files with default contexts */
+		setfscreatecon (NULL);
+#endif
 	}
 }
 
@@ -1847,6 +1907,8 @@ int main (int argc, char **argv)
 
 	close_files ();
 
+	selinux_update_mapping();
+
 	nscd_flush_cache ("passwd");
 	nscd_flush_cache ("group");