Blob Blame History Raw
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;
 }