diff -rup shadow-4.0.17-orig/man/useradd.8.xml shadow-4.0.17/man/useradd.8.xml
--- shadow-4.0.17-orig/man/useradd.8.xml	2006-06-16 12:11:04.000000000 -0400
+++ shadow-4.0.17/man/useradd.8.xml	2006-12-19 09:26:41.000000000 -0500
@@ -238,6 +238,19 @@
       
       
 	
+	  , 
+	  SEUSER
+	
+	
+	  
+	    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.
+	  
+	
+      
+      
+	
 	  , 
 	  UID
 	
Only in shadow-4.0.17/man: useradd.8.xml.useradd
diff -rup shadow-4.0.17-orig/man/usermod.8.xml shadow-4.0.17/man/usermod.8.xml
--- shadow-4.0.17-orig/man/usermod.8.xml	2006-06-16 12:11:04.000000000 -0400
+++ shadow-4.0.17/man/usermod.8.xml	2006-12-19 09:26:41.000000000 -0500
@@ -226,6 +226,19 @@
 	  
 	
       
+       
+        
+         , 
+         SEUSER
+       
+       
+         
+           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.
+         
+       
+      
     
   
 
Only in shadow-4.0.17/man: usermod.8.xml.useradd
diff -rup shadow-4.0.17-orig/src/useradd.c shadow-4.0.17/src/useradd.c
--- shadow-4.0.17-orig/src/useradd.c	2006-11-29 18:31:43.000000000 -0500
+++ shadow-4.0.17/src/useradd.c	2006-12-19 09:27:13.000000000 -0500
@@ -45,6 +45,9 @@
 #include 
 #include 
 #include 
+#ifdef WITH_SELINUX
+#include 
+#endif
 #include "chkname.h"
 #include "defines.h"
 #include "faillog.h"
@@ -100,6 +103,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;
@@ -124,7 +128,7 @@ static int
     Gflg = 0,			/* secondary group set for new account */
     kflg = 0,			/* specify a directory to fill new user directory */
     mflg = 0,			/* create user's home directory if it doesn't exist */
-    lflg = 0;      		/* do not add user to lastlog database file */
+    lflg = 0,      		/* do not add user to lastlog database file */
     Mflg = 0,                   /* do NOT create user's home directory no matter what */
     nflg = 0,                   /* do NOT create a group having the same name as the user */
     oflg = 0,			/* permit non-unique user ID to be specified with -u */
@@ -648,7 +652,8 @@ static void usage (void)
 			   "  -p, --password PASSWORD	use encrypted password for the new user\n"
 			   "				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"
+			   "  -u, --uid UID	       		force use the UID for the new user account\n"
+			   "  -Z, --selinux-user SEUSER	use a specific SEUSER for the SELinux user mapping\n"
 			   "\n"));
 	exit (E_USAGE);
 }
@@ -1048,11 +1053,12 @@ static void process_flags (int argc, cha
 			{"non-unique", no_argument, NULL, 'o'},
 			{"password", required_argument, NULL, 'p'},
 			{"shell", required_argument, NULL, 's'},
+			{"selinux-user", required_argument, NULL, 'Z'},
 			{"uid", required_argument, NULL, 'u'},
 			{NULL, 0, NULL, '\0'}
 		};
 		while ((c =
-			getopt_long (argc, argv, "b:c:d:De:f:g:G:k:K:mlMnrop:s:u:",
+			getopt_long (argc, argv, "b:c:d:De:f:g:G:k:K:mlMnrop:s:u:Z:",
 				     long_options, NULL)) != -1) {
 			switch (c) {
 			case 'b':
@@ -1236,6 +1242,9 @@ static void process_flags (int argc, cha
                         case 'M':
                                 Mflg++;
                                 break;
+                        case 'Z':
+                                user_selinux = optarg;
+                                break;
 			default:
 				usage ();
 			}
@@ -1612,6 +1621,9 @@ static void usr_update (void)
  */
 static void create_home (void)
 {
+        mode_t mode = 0;
+
+        mode = 0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK);
 	if (access (user_home, F_OK)) {
 		/* XXX - create missing parent directories.  --marekm */
 		if (mkdir (user_home, 0)) {
@@ -1625,9 +1637,24 @@ static void create_home (void)
 #endif
 			fail_exit (E_HOMEDIR);
 		}
+#ifdef WITH_SELINUX
+                /* needs the mapping, or policy does the wrong thing */
+                if (*user_selinux) {
+                        security_context_t con = NULL;
+
+                        if (!matchpathcon (user_home, mode, &con)) {
+                                setfilecon (user_home, con);
+                                freecon (con);
+                        }
+                }
+                else if (security_getenforce ())
+			fprintf (stderr,
+				 _
+				 ("%s: cannot create directory %s with correct context\n"),
+				 Prog, user_home);                  
+#endif
 		chown (user_home, user_id, user_gid);
-		chmod (user_home,
-		       0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK));
+		chmod (user_home, mode);
 		home_added++;
 #ifdef WITH_AUDIT
 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
@@ -1840,6 +1867,24 @@ int main (int argc, char **argv)
 
 	usr_update ();
 
+        if (*user_selinux) { /* must be done before create_home() */
+                char buf[4096];
+                static const char sem_cmd[] = "semanage login -a -s %s %s";
+                int done = 0;
+                
+                if ((strlen(user_selinux) + sizeof(sem_cmd)) < sizeof(buf)) {
+                        sprintf(buf, sem_cmd, user_selinux, user_name);
+
+                        if (!system(buf))
+                                done = 1;
+                }
+                if (!done)
+			fprintf (stderr,
+				 _
+				 ("%s: warning: the user name %s could not be added as a mapping to the %s SELinux User.\n"),
+				 Prog, user_name, user_selinux);
+        }
+        
 	if (mflg) {
 		create_home ();
 		if (home_added)
Only in shadow-4.0.17/src: useradd.c.useradd
diff -rup shadow-4.0.17-orig/src/usermod.c shadow-4.0.17/src/usermod.c
--- shadow-4.0.17-orig/src/usermod.c	2006-11-29 18:31:43.000000000 -0500
+++ shadow-4.0.17/src/usermod.c	2006-12-19 09:26:41.000000000 -0500
@@ -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;
@@ -301,6 +302,7 @@ 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"
+			   "  -Z, --selinux-user	new selinux user mapping for the user account\n"
 			   "\n"));
 	exit (E_USAGE);
 }
@@ -925,13 +927,14 @@ static void process_flags (int argc, cha
 			{"move-home", no_argument, NULL, 'm'},
 			{"non-unique", no_argument, NULL, 'o'},
 			{"password", required_argument, NULL, 'p'},
+			{"selinux-user", required_argument, NULL, 'Z'},
 			{"shell", required_argument, NULL, 's'},
 			{"uid", required_argument, NULL, 'u'},
 			{"unlock", no_argument, NULL, 'U'},
 			{NULL, 0, NULL, '\0'}
 		};
 		while ((c =
-			getopt_long (argc, argv, "ac:d:e:f:g:G:hl:Lmop:s:u:U",
+			getopt_long (argc, argv, "ac:d:e:f:g:G:hl:Lmop:s:u:UZ:",
 				     long_options, NULL)) != -1) {
 			switch (c) {
 			case 'a':
@@ -1080,6 +1083,9 @@ static void process_flags (int argc, cha
 
 				Uflg++;
 				break;
+                        case 'Z':
+                                user_selinux = optarg;
+                                break;
 			default:
 				usage ();
 			}
@@ -1293,6 +1299,7 @@ static void move_home (void)
 					rmdir (user_newhome);
 					fail_exit (E_HOMEDIR);
 				}
+
 				if (copy_tree (user_home, user_newhome,
 					       uflg ? user_newid : -1,
 					       gflg ? user_newgid : -1) == 0) {
@@ -1549,6 +1556,31 @@ int main (int argc, char **argv)
 	if (Gflg || lflg)
 		grp_err = grp_update ();
 
+        if (*user_selinux) { /* should be done before move_home () */
+                char buf[4096];
+                static const char s_a_cmd[] = "semanage login -a -s %s %s";
+                static const char s_m_cmd[] = "semanage login -m -s %s %s";
+                int done = 0;
+                
+                if ((strlen (user_selinux) + sizeof (s_m_cmd)) < sizeof (buf)) {
+                        sprintf (buf, s_m_cmd, user_selinux, user_name);
+                         /* if it fails, it's probably because no mapping
+                            exists. So trying adding one. */
+                        if (!system (buf))
+                                done = 1;
+                        else {
+                                sprintf (buf, s_a_cmd, user_selinux, user_name);
+                                if (!system (buf))
+                                        done = 1;
+                        }
+                }
+                if (!done)
+			fprintf (stderr,
+				 _
+				 ("%s: warning: the user name %s could not be modified to a mapping to the %s SELinux User.\n"),
+				 Prog, user_name, user_selinux);
+        }
+        
 	if (mflg)
 		move_home ();
 
Only in shadow-4.0.17/src: usermod.c.useradd