useradd/usermod: add --selinux-range argument
Add a command line argument to useradd(8) and usermod(8) to specify the MLS range for a SELinux user mapping. Improves: #676
This commit is contained in:
		
				
					committed by
					
						 Iker Pedrosa
						Iker Pedrosa
					
				
			
			
				
	
			
			
			
						parent
						
							97f79e3b27
						
					
				
				
					commit
					c80788a3ac
				
			| @@ -385,7 +385,7 @@ extern int check_selinux_permit (const char *perm_name); | ||||
|  | ||||
| /* semanage.c */ | ||||
| #ifdef WITH_SELINUX | ||||
| extern int set_seuser(const char *login_name, const char *seuser_name); | ||||
| extern int set_seuser(const char *login_name, const char *seuser_name, const char *serange); | ||||
| extern int del_seuser(const char *login_name); | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -105,7 +105,8 @@ fail: | ||||
| static int semanage_user_mod (semanage_handle_t *handle, | ||||
|                               semanage_seuser_key_t *key, | ||||
|                               const char *login_name, | ||||
|                               const char *seuser_name) | ||||
|                               const char *seuser_name, | ||||
|                               const char *serange) | ||||
| { | ||||
| 	int ret; | ||||
| 	semanage_seuser_t *seuser = NULL; | ||||
| @@ -118,6 +119,17 @@ static int semanage_user_mod (semanage_handle_t *handle, | ||||
| 		goto done; | ||||
| 	} | ||||
|  | ||||
| 	if (serange && semanage_mls_enabled(handle)) { | ||||
| 		ret = semanage_seuser_set_mlsrange (handle, seuser, serange); | ||||
| 		if (ret != 0) { | ||||
| 			fprintf (shadow_logfd, | ||||
| 			         _("Could not set serange for %s to %s\n"), | ||||
| 			         login_name, serange); | ||||
| 			ret = 1; | ||||
| 			goto done; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	ret = semanage_seuser_set_sename (handle, seuser, seuser_name); | ||||
| 	if (ret != 0) { | ||||
| 		fprintf (shadow_logfd, | ||||
| @@ -146,7 +158,8 @@ done: | ||||
| static int semanage_user_add (semanage_handle_t *handle, | ||||
|                              semanage_seuser_key_t *key, | ||||
|                              const char *login_name, | ||||
|                              const char *seuser_name) | ||||
|                              const char *seuser_name, | ||||
|                              const char *serange) | ||||
| { | ||||
| 	int ret; | ||||
| 	semanage_seuser_t *seuser = NULL; | ||||
| @@ -167,6 +180,17 @@ static int semanage_user_add (semanage_handle_t *handle, | ||||
| 		goto done; | ||||
| 	} | ||||
|  | ||||
| 	if (serange && semanage_mls_enabled(handle)) { | ||||
| 		ret = semanage_seuser_set_mlsrange (handle, seuser, serange); | ||||
| 		if (ret != 0) { | ||||
| 			fprintf (shadow_logfd, | ||||
| 			         _("Could not set serange for %s to %s\n"), | ||||
| 			         login_name, serange); | ||||
| 			ret = 1; | ||||
| 			goto done; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	ret = semanage_seuser_set_sename (handle, seuser, seuser_name); | ||||
| 	if (ret != 0) { | ||||
| 		fprintf (shadow_logfd, | ||||
| @@ -192,7 +216,7 @@ done: | ||||
| } | ||||
|  | ||||
|  | ||||
| int set_seuser (const char *login_name, const char *seuser_name) | ||||
| int set_seuser (const char *login_name, const char *seuser_name, const char *serange) | ||||
| { | ||||
| 	semanage_handle_t *handle = NULL; | ||||
| 	semanage_seuser_key_t *key = NULL; | ||||
| @@ -226,7 +250,7 @@ int set_seuser (const char *login_name, const char *seuser_name) | ||||
| 	} | ||||
|  | ||||
| 	if (0 != seuser_exists) { | ||||
| 		ret = semanage_user_mod (handle, key, login_name, seuser_name); | ||||
| 		ret = semanage_user_mod (handle, key, login_name, seuser_name, serange); | ||||
| 		if (ret != 0) { | ||||
| 			fprintf (shadow_logfd, | ||||
| 			         _("Cannot modify SELinux user mapping\n")); | ||||
| @@ -234,7 +258,7 @@ int set_seuser (const char *login_name, const char *seuser_name) | ||||
| 			goto done; | ||||
| 		} | ||||
| 	} else { | ||||
| 		ret = semanage_user_add (handle, key, login_name, seuser_name); | ||||
| 		ret = semanage_user_add (handle, key, login_name, seuser_name, serange); | ||||
| 		if (ret != 0) { | ||||
| 			fprintf (shadow_logfd, | ||||
| 			         _("Cannot add SELinux user mapping\n")); | ||||
|   | ||||
| @@ -570,13 +570,31 @@ | ||||
| 	<listitem> | ||||
| 	  <para> | ||||
| 	    defines the SELinux user for the new account. Without this | ||||
| 	    option, a SELinux uses the default user. Note that the | ||||
| 	    option, SELinux uses the default user. Note that the | ||||
| 	    shadow system doesn't store the selinux-user, it uses | ||||
| 	    <citerefentry><refentrytitle>semanage</refentrytitle> | ||||
| 	    <manvolnum>8</manvolnum></citerefentry> for that. | ||||
| 	  </para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term> | ||||
| 	  <option>--selinux-range</option> <replaceable>SERANGE</replaceable> | ||||
| 	</term> | ||||
| 	<listitem> | ||||
| 	  <para> | ||||
| 	    defines the SELinux MLS range for the new account. Without this | ||||
| 	    option, SELinux uses the default range. Note that the | ||||
| 	    shadow system doesn't store the selinux-range, it uses | ||||
| 	    <citerefentry><refentrytitle>semanage</refentrytitle> | ||||
| 	    <manvolnum>8</manvolnum></citerefentry> for that. | ||||
| 	  </para> | ||||
| 	  <para> | ||||
| 	    This option is only valid if the <option>-Z</option> (or | ||||
| 	    <option>--selinux-user</option>) option is specified. | ||||
| 	  </para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|  | ||||
|     <refsect2 id='changing_the_default_values'> | ||||
|   | ||||
| @@ -510,6 +510,23 @@ | ||||
| 	  </para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term> | ||||
| 	  <option>--selinux-range</option> <replaceable>SERANGE</replaceable> | ||||
| 	</term> | ||||
| 	<listitem> | ||||
| 	  <para> | ||||
| 	    defines the SELinux MLS range for the new account. | ||||
| 	    Note that the shadow system doesn't store the selinux-range, | ||||
| 	    it uses <citerefentry><refentrytitle>semanage</refentrytitle> | ||||
| 	    <manvolnum>8</manvolnum></citerefentry> for that. | ||||
| 	  </para> | ||||
| 	  <para> | ||||
| 	    This option is only valid if the <option>-Z</option> (or | ||||
| 	    <option>--selinux-user</option>) option is specified. | ||||
| 	  </para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
|  | ||||
|   | ||||
| @@ -113,6 +113,7 @@ static const char *prefix_user_home = NULL; | ||||
|  | ||||
| #ifdef WITH_SELINUX | ||||
| static /*@notnull@*/const char *user_selinux = ""; | ||||
| static const char *user_selinux_range = NULL; | ||||
| #endif				/* WITH_SELINUX */ | ||||
|  | ||||
| static long user_expire = -1; | ||||
| @@ -997,6 +998,7 @@ static void usage (int status) | ||||
| 	(void) fputs (_("  -U, --user-group              create a group with the same name as the user\n"), usageout); | ||||
| #ifdef WITH_SELINUX | ||||
| 	(void) fputs (_("  -Z, --selinux-user SEUSER     use a specific SEUSER for the SELinux user mapping\n"), usageout); | ||||
| 	(void) fputs (_("      --selinux-range SERANGE   use a specific MLS range for the SELinux user mapping\n"), usageout); | ||||
| #endif				/* WITH_SELINUX */ | ||||
| 	(void) fputs ("\n", usageout); | ||||
| 	exit (status); | ||||
| @@ -1280,6 +1282,7 @@ static void process_flags (int argc, char **argv) | ||||
| 			{"user-group",     no_argument,       NULL, 'U'}, | ||||
| #ifdef WITH_SELINUX | ||||
| 			{"selinux-user",   required_argument, NULL, 'Z'}, | ||||
| 			{"selinux-range",  required_argument, NULL, 202}, | ||||
| #endif				/* WITH_SELINUX */ | ||||
| 			{NULL, 0, NULL, '\0'} | ||||
| 		}; | ||||
| @@ -1529,6 +1532,9 @@ static void process_flags (int argc, char **argv) | ||||
| 					exit (E_BAD_ARG); | ||||
| 				} | ||||
| 				break; | ||||
| 			case 202: | ||||
| 				user_selinux_range = optarg; | ||||
| 				break; | ||||
| #endif				/* WITH_SELINUX */ | ||||
| 			default: | ||||
| 				usage (E_USAGE); | ||||
| @@ -1576,6 +1582,14 @@ static void process_flags (int argc, char **argv) | ||||
| 		         Prog, "-m", "-M"); | ||||
| 		usage (E_USAGE); | ||||
| 	} | ||||
| #ifdef WITH_SELINUX | ||||
| 	if (user_selinux_range && !Zflg) { | ||||
| 		fprintf (stderr, | ||||
| 		         _("%s: %s flag is only allowed with the %s flag\n"), | ||||
| 		         Prog, "--selinux-range", "--selinux-user"); | ||||
| 		usage (E_USAGE); | ||||
| 	} | ||||
| #endif				/* WITH_SELINUX */ | ||||
|  | ||||
| 	/* | ||||
| 	 * Either -D or username is required. Defaults can be set with -D | ||||
| @@ -2760,7 +2774,7 @@ int main (int argc, char **argv) | ||||
|  | ||||
| #ifdef WITH_SELINUX | ||||
| 	if (Zflg) { | ||||
| 		if (set_seuser (user_name, user_selinux) != 0) { | ||||
| 		if (set_seuser (user_name, user_selinux, user_selinux_range) != 0) { | ||||
| 			fprintf (stderr, | ||||
| 			         _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), | ||||
| 			         Prog, user_name, user_selinux); | ||||
|   | ||||
| @@ -100,6 +100,7 @@ static char *user_newhome; | ||||
| static char *user_shell; | ||||
| #ifdef WITH_SELINUX | ||||
| static const char *user_selinux = ""; | ||||
| static const char *user_selinux_range = NULL; | ||||
| #endif				/* WITH_SELINUX */ | ||||
| static char *user_newshell; | ||||
| static long user_expire; | ||||
| @@ -405,6 +406,7 @@ usage (int status) | ||||
| #endif				/* ENABLE_SUBIDS */ | ||||
| #ifdef WITH_SELINUX | ||||
| 	(void) fputs (_("  -Z, --selinux-user SEUSER     new SELinux user mapping for the user account\n"), usageout); | ||||
| 	(void) fputs (_("      --selinux-range SERANGE   new SELinux MLS range for the user account\n"), usageout); | ||||
| #endif				/* WITH_SELINUX */ | ||||
| 	(void) fputs ("\n", usageout); | ||||
| 	exit (status); | ||||
| @@ -1004,7 +1006,8 @@ static void process_flags (int argc, char **argv) | ||||
|  			{"del-subgids",  required_argument, NULL, 'W'}, | ||||
| #endif				/* ENABLE_SUBIDS */ | ||||
| #ifdef WITH_SELINUX | ||||
| 			{"selinux-user", required_argument, NULL, 'Z'}, | ||||
| 			{"selinux-user",  required_argument, NULL, 'Z'}, | ||||
| 			{"selinux-range", required_argument, NULL, 202}, | ||||
| #endif				/* WITH_SELINUX */ | ||||
| 			{NULL, 0, NULL, '\0'} | ||||
| 		}; | ||||
| @@ -1214,6 +1217,9 @@ static void process_flags (int argc, char **argv) | ||||
| 					exit (E_BAD_ARG); | ||||
| 				} | ||||
| 				break; | ||||
| 			case 202: | ||||
| 				user_selinux_range = optarg; | ||||
| 				break; | ||||
| #endif				/* WITH_SELINUX */ | ||||
| 			default: | ||||
| 				usage (E_USAGE); | ||||
| @@ -1354,6 +1360,15 @@ static void process_flags (int argc, char **argv) | ||||
| 		usage (E_USAGE); | ||||
| 	} | ||||
|  | ||||
| #ifdef WITH_SELINUX | ||||
| 	if (user_selinux_range && !Zflg) { | ||||
| 		fprintf (stderr, | ||||
| 		         _("%s: %s flag is only allowed with the %s flag\n"), | ||||
| 		         Prog, "--selinux-range", "--selinux-user"); | ||||
| 		usage (E_USAGE); | ||||
| 	} | ||||
| #endif				/* WITH_SELINUX */ | ||||
|  | ||||
| 	if (user_newid == user_id) { | ||||
| 		uflg = false; | ||||
| 		oflg = false; | ||||
| @@ -2304,7 +2319,7 @@ int main (int argc, char **argv) | ||||
| #ifdef WITH_SELINUX | ||||
| 	if (Zflg) { | ||||
| 		if ('\0' != *user_selinux) { | ||||
| 			if (set_seuser (user_name, user_selinux) != 0) { | ||||
| 			if (set_seuser (user_name, user_selinux, user_selinux_range) != 0) { | ||||
| 				fprintf (stderr, | ||||
| 				         _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), | ||||
| 				         Prog, user_name, user_selinux); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user