diff -up shadow-4.8/lib/commonio.c.selinux shadow-4.8/lib/commonio.c --- shadow-4.8/lib/commonio.c.selinux 2019-07-23 17:26:08.000000000 +0200 +++ shadow-4.8/lib/commonio.c 2020-01-13 10:08:53.769101131 +0100 @@ -964,7 +964,7 @@ int commonio_close (struct commonio_db * snprintf (buf, sizeof buf, "%s-", db->filename); #ifdef WITH_SELINUX - if (set_selinux_file_context (buf) != 0) { + if (set_selinux_file_context (buf, db->filename) != 0) { errors++; } #endif @@ -997,7 +997,7 @@ int commonio_close (struct commonio_db * snprintf (buf, sizeof buf, "%s+", db->filename); #ifdef WITH_SELINUX - if (set_selinux_file_context (buf) != 0) { + if (set_selinux_file_context (buf, db->filename) != 0) { errors++; } #endif diff -up shadow-4.8/libmisc/copydir.c.selinux shadow-4.8/libmisc/copydir.c --- shadow-4.8/libmisc/copydir.c.selinux 2019-07-23 17:26:08.000000000 +0200 +++ shadow-4.8/libmisc/copydir.c 2020-01-13 10:08:53.769101131 +0100 @@ -484,7 +484,7 @@ static int copy_dir (const char *src, co */ #ifdef WITH_SELINUX - if (set_selinux_file_context (dst) != 0) { + if (set_selinux_file_context (dst, NULL) != 0) { return -1; } #endif /* WITH_SELINUX */ @@ -605,7 +605,7 @@ static int copy_symlink (const char *src } #ifdef WITH_SELINUX - if (set_selinux_file_context (dst) != 0) { + if (set_selinux_file_context (dst, NULL) != 0) { free (oldlink); return -1; } @@ -684,7 +684,7 @@ static int copy_special (const char *src int err = 0; #ifdef WITH_SELINUX - if (set_selinux_file_context (dst) != 0) { + if (set_selinux_file_context (dst, NULL) != 0) { return -1; } #endif /* WITH_SELINUX */ @@ -744,7 +744,7 @@ static int copy_file (const char *src, c return -1; } #ifdef WITH_SELINUX - if (set_selinux_file_context (dst) != 0) { + if (set_selinux_file_context (dst, NULL) != 0) { return -1; } #endif /* WITH_SELINUX */ diff -up shadow-4.8/lib/prototypes.h.selinux shadow-4.8/lib/prototypes.h --- shadow-4.8/lib/prototypes.h.selinux 2020-01-13 10:08:53.769101131 +0100 +++ shadow-4.8/lib/prototypes.h 2020-01-13 10:11:20.914627399 +0100 @@ -334,7 +334,7 @@ extern /*@observer@*/const char *crypt_m /* selinux.c */ #ifdef WITH_SELINUX -extern int set_selinux_file_context (const char *dst_name); +extern int set_selinux_file_context (const char *dst_name, const char *orig_name); extern int reset_selinux_file_context (void); extern int check_selinux_permit (const char *perm_name); #endif diff -up shadow-4.8/lib/selinux.c.selinux shadow-4.8/lib/selinux.c --- shadow-4.8/lib/selinux.c.selinux 2019-11-12 01:18:25.000000000 +0100 +++ shadow-4.8/lib/selinux.c 2020-01-13 10:08:53.769101131 +0100 @@ -51,7 +51,7 @@ static bool selinux_enabled; * Callers may have to Reset SELinux to create files with default * contexts with reset_selinux_file_context */ -int set_selinux_file_context (const char *dst_name) +int set_selinux_file_context (const char *dst_name, const char *orig_name) { /*@null@*/security_context_t scontext = NULL; @@ -63,19 +63,23 @@ int set_selinux_file_context (const char if (selinux_enabled) { /* Get the default security context for this file */ if (matchpathcon (dst_name, 0, &scontext) < 0) { - if (security_getenforce () != 0) { - return 1; - } + /* We could not get the default, copy the original */ + if (orig_name == NULL) + goto error; + if (getfilecon (orig_name, &scontext) < 0) + goto error; } /* Set the security context for the next created file */ - if (setfscreatecon (scontext) < 0) { - if (security_getenforce () != 0) { - return 1; - } - } + if (setfscreatecon (scontext) < 0) + goto error; freecon (scontext); } return 0; + error: + if (security_getenforce () != 0) { + return 1; + } + return 0; } /* diff -up shadow-4.8/lib/semanage.c.selinux shadow-4.8/lib/semanage.c --- shadow-4.8/lib/semanage.c.selinux 2019-07-23 17:26:08.000000000 +0200 +++ shadow-4.8/lib/semanage.c 2020-01-13 10:08:53.766101181 +0100 @@ -294,6 +294,9 @@ int set_seuser (const char *login_name, ret = 0; + /* drop obsolete matchpathcon cache */ + matchpathcon_fini(); + done: semanage_seuser_key_free (key); semanage_handle_destroy (handle); @@ -369,6 +372,10 @@ int del_seuser (const char *login_name) } ret = 0; + + /* drop obsolete matchpathcon cache */ + matchpathcon_fini(); + done: semanage_handle_destroy (handle); return ret; diff -up shadow-4.8/src/useradd.c.selinux shadow-4.8/src/useradd.c --- shadow-4.8/src/useradd.c.selinux 2020-01-13 10:08:53.762101248 +0100 +++ shadow-4.8/src/useradd.c 2020-01-13 10:08:53.767101164 +0100 @@ -2078,7 +2078,7 @@ static void create_home (void) ++bhome; #ifdef WITH_SELINUX - if (set_selinux_file_context (prefix_user_home) != 0) { + if (set_selinux_file_context (prefix_user_home, NULL) != 0) { fprintf (stderr, _("%s: cannot set SELinux context for home directory %s\n"), Prog, user_home); @@ -2232,6 +2232,7 @@ static void create_mail (void) */ int main (int argc, char **argv) { + int rv = E_SUCCESS; #ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM pam_handle_t *pamh = NULL; @@ -2454,27 +2455,12 @@ int main (int argc, char **argv) usr_update (); - if (mflg) { - create_home (); - if (home_added) { - copy_tree (def_template, prefix_user_home, false, false, - (uid_t)-1, user_id, (gid_t)-1, user_gid); - } else { - fprintf (stderr, - _("%s: warning: the home directory %s already exists.\n" - "%s: Not copying any file from skel directory into it.\n"), - Prog, user_home, Prog); - } - - } - - /* Do not create mail directory for system accounts */ - if (!rflg) { - create_mail (); - } - close_files (); + nscd_flush_cache ("passwd"); + nscd_flush_cache ("group"); + sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); + /* * tallylog_reset needs to be able to lookup * a valid existing user name, @@ -2485,8 +2471,9 @@ int main (int argc, char **argv) } #ifdef WITH_SELINUX - if (Zflg) { - if (set_seuser (user_name, user_selinux) != 0) { + if (Zflg && *user_selinux) { + if (is_selinux_enabled () > 0) { + if (set_seuser (user_name, user_selinux) != 0) { fprintf (stderr, _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), Prog, user_name, user_selinux); @@ -2495,15 +2482,31 @@ int main (int argc, char **argv) "adding SELinux user mapping", user_name, (unsigned int) user_id, 0); #endif /* WITH_AUDIT */ - fail_exit (E_SE_UPDATE); + rv = E_SE_UPDATE; + } } } #endif /* WITH_SELINUX */ - nscd_flush_cache ("passwd"); - nscd_flush_cache ("group"); - sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); + if (mflg) { + create_home (); + if (home_added) { + copy_tree (def_template, prefix_user_home, false, true, + (uid_t)-1, user_id, (gid_t)-1, user_gid); + } else { + fprintf (stderr, + _("%s: warning: the home directory %s already exists.\n" + "%s: Not copying any file from skel directory into it.\n"), + Prog, user_home, Prog); + } + + } + + /* Do not create mail directory for system accounts */ + if (!rflg) { + create_mail (); + } - return E_SUCCESS; + return rv; }