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