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