xref: /aosp_15_r20/external/selinux/libsemanage/src/seusers_local.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker /* Copyright (C) 2005 Red Hat, Inc. */
2*2d543d20SAndroid Build Coastguard Worker 
3*2d543d20SAndroid Build Coastguard Worker struct semanage_seuser;
4*2d543d20SAndroid Build Coastguard Worker struct semanage_seuser_key;
5*2d543d20SAndroid Build Coastguard Worker typedef struct semanage_seuser_key record_key_t;
6*2d543d20SAndroid Build Coastguard Worker typedef struct semanage_seuser record_t;
7*2d543d20SAndroid Build Coastguard Worker #define DBASE_RECORD_DEFINED
8*2d543d20SAndroid Build Coastguard Worker 
9*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb.h>
10*2d543d20SAndroid Build Coastguard Worker #include <sepol/context.h>
11*2d543d20SAndroid Build Coastguard Worker #include <libaudit.h>
12*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
13*2d543d20SAndroid Build Coastguard Worker #include "user_internal.h"
14*2d543d20SAndroid Build Coastguard Worker #include "seuser_internal.h"
15*2d543d20SAndroid Build Coastguard Worker #include "handle.h"
16*2d543d20SAndroid Build Coastguard Worker #include "database.h"
17*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
18*2d543d20SAndroid Build Coastguard Worker #include "string.h"
19*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
20*2d543d20SAndroid Build Coastguard Worker 
semanage_user_roles(semanage_handle_t * handle,const char * sename)21*2d543d20SAndroid Build Coastguard Worker static char *semanage_user_roles(semanage_handle_t * handle, const char *sename) {
22*2d543d20SAndroid Build Coastguard Worker 	char *roles = NULL;
23*2d543d20SAndroid Build Coastguard Worker 	unsigned int num_roles;
24*2d543d20SAndroid Build Coastguard Worker 	size_t i;
25*2d543d20SAndroid Build Coastguard Worker 	size_t size = 0;
26*2d543d20SAndroid Build Coastguard Worker 	const char **roles_arr;
27*2d543d20SAndroid Build Coastguard Worker 	semanage_user_key_t *key = NULL;
28*2d543d20SAndroid Build Coastguard Worker 	semanage_user_t * user;
29*2d543d20SAndroid Build Coastguard Worker 	if (semanage_user_key_create(handle, sename, &key) >= 0) {
30*2d543d20SAndroid Build Coastguard Worker 		if (semanage_user_query(handle, key, &user) >= 0) {
31*2d543d20SAndroid Build Coastguard Worker 			if (semanage_user_get_roles(handle,
32*2d543d20SAndroid Build Coastguard Worker 						    user,
33*2d543d20SAndroid Build Coastguard Worker 						    &roles_arr,
34*2d543d20SAndroid Build Coastguard Worker 						    &num_roles) >= 0) {
35*2d543d20SAndroid Build Coastguard Worker 				for (i = 0; i<num_roles; i++) {
36*2d543d20SAndroid Build Coastguard Worker 					size += (strlen(roles_arr[i]) + 1);
37*2d543d20SAndroid Build Coastguard Worker 				}
38*2d543d20SAndroid Build Coastguard Worker 				if (num_roles == 0) {
39*2d543d20SAndroid Build Coastguard Worker 					roles = strdup("");
40*2d543d20SAndroid Build Coastguard Worker 				} else {
41*2d543d20SAndroid Build Coastguard Worker 					roles = malloc(size);
42*2d543d20SAndroid Build Coastguard Worker 					if (roles) {
43*2d543d20SAndroid Build Coastguard Worker 						strcpy(roles,roles_arr[0]);
44*2d543d20SAndroid Build Coastguard Worker 						for (i = 1; i<num_roles; i++) {
45*2d543d20SAndroid Build Coastguard Worker 							strcat(roles,",");
46*2d543d20SAndroid Build Coastguard Worker 							strcat(roles,roles_arr[i]);
47*2d543d20SAndroid Build Coastguard Worker 						}
48*2d543d20SAndroid Build Coastguard Worker 					}
49*2d543d20SAndroid Build Coastguard Worker 				}
50*2d543d20SAndroid Build Coastguard Worker 				free(roles_arr);
51*2d543d20SAndroid Build Coastguard Worker 			}
52*2d543d20SAndroid Build Coastguard Worker 			semanage_user_free(user);
53*2d543d20SAndroid Build Coastguard Worker 		}
54*2d543d20SAndroid Build Coastguard Worker 		semanage_user_key_free(key);
55*2d543d20SAndroid Build Coastguard Worker 	}
56*2d543d20SAndroid Build Coastguard Worker 	return roles;
57*2d543d20SAndroid Build Coastguard Worker }
58*2d543d20SAndroid Build Coastguard Worker 
semanage_seuser_audit(semanage_handle_t * handle,const semanage_seuser_t * seuser,const semanage_seuser_t * previous,int audit_type,int success)59*2d543d20SAndroid Build Coastguard Worker static int semanage_seuser_audit(semanage_handle_t * handle,
60*2d543d20SAndroid Build Coastguard Worker 			  const semanage_seuser_t * seuser,
61*2d543d20SAndroid Build Coastguard Worker 			  const semanage_seuser_t * previous,
62*2d543d20SAndroid Build Coastguard Worker 			  int audit_type,
63*2d543d20SAndroid Build Coastguard Worker 			  int success) {
64*2d543d20SAndroid Build Coastguard Worker 	const char *name = NULL;
65*2d543d20SAndroid Build Coastguard Worker 	const char *sename = NULL;
66*2d543d20SAndroid Build Coastguard Worker 	char *roles = NULL;
67*2d543d20SAndroid Build Coastguard Worker 	const char *mls = NULL;
68*2d543d20SAndroid Build Coastguard Worker 	const char *psename = NULL;
69*2d543d20SAndroid Build Coastguard Worker 	const char *pmls = NULL;
70*2d543d20SAndroid Build Coastguard Worker 	char *proles = NULL;
71*2d543d20SAndroid Build Coastguard Worker 	char msg[1024];
72*2d543d20SAndroid Build Coastguard Worker 	const char *sep = "-";
73*2d543d20SAndroid Build Coastguard Worker 	int rc = -1;
74*2d543d20SAndroid Build Coastguard Worker 	strcpy(msg, "login");
75*2d543d20SAndroid Build Coastguard Worker 	if (previous) {
76*2d543d20SAndroid Build Coastguard Worker 		name = semanage_seuser_get_name(previous);
77*2d543d20SAndroid Build Coastguard Worker 		psename = semanage_seuser_get_sename(previous);
78*2d543d20SAndroid Build Coastguard Worker 		pmls = semanage_seuser_get_mlsrange(previous);
79*2d543d20SAndroid Build Coastguard Worker 		proles = semanage_user_roles(handle, psename);
80*2d543d20SAndroid Build Coastguard Worker 	}
81*2d543d20SAndroid Build Coastguard Worker 	if (seuser) {
82*2d543d20SAndroid Build Coastguard Worker 		name = semanage_seuser_get_name(seuser);
83*2d543d20SAndroid Build Coastguard Worker 		sename = semanage_seuser_get_sename(seuser);
84*2d543d20SAndroid Build Coastguard Worker 		mls = semanage_seuser_get_mlsrange(seuser);
85*2d543d20SAndroid Build Coastguard Worker 		roles = semanage_user_roles(handle, sename);
86*2d543d20SAndroid Build Coastguard Worker 	}
87*2d543d20SAndroid Build Coastguard Worker 	if (audit_type != AUDIT_ROLE_REMOVE) {
88*2d543d20SAndroid Build Coastguard Worker 		if (sename && (!psename || strcmp(psename, sename) != 0)) {
89*2d543d20SAndroid Build Coastguard Worker 			strcat(msg,sep);
90*2d543d20SAndroid Build Coastguard Worker 			strcat(msg,"sename");
91*2d543d20SAndroid Build Coastguard Worker 			sep = ",";
92*2d543d20SAndroid Build Coastguard Worker 		}
93*2d543d20SAndroid Build Coastguard Worker 		if (roles && (!proles || strcmp(proles, roles) != 0)) {
94*2d543d20SAndroid Build Coastguard Worker 			strcat(msg,sep);
95*2d543d20SAndroid Build Coastguard Worker 			strcat(msg,"role");
96*2d543d20SAndroid Build Coastguard Worker 			sep = ",";
97*2d543d20SAndroid Build Coastguard Worker 		}
98*2d543d20SAndroid Build Coastguard Worker 		if (mls && (!pmls || strcmp(pmls, mls) != 0)) {
99*2d543d20SAndroid Build Coastguard Worker 			strcat(msg,sep);
100*2d543d20SAndroid Build Coastguard Worker 			strcat(msg,"range");
101*2d543d20SAndroid Build Coastguard Worker 		}
102*2d543d20SAndroid Build Coastguard Worker 	}
103*2d543d20SAndroid Build Coastguard Worker 
104*2d543d20SAndroid Build Coastguard Worker 	int fd = audit_open();
105*2d543d20SAndroid Build Coastguard Worker 	if (fd < 0)
106*2d543d20SAndroid Build Coastguard Worker 	{
107*2d543d20SAndroid Build Coastguard Worker 		/* If kernel doesn't support audit, bail out */
108*2d543d20SAndroid Build Coastguard Worker 		if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT) {
109*2d543d20SAndroid Build Coastguard Worker 			rc = 0;
110*2d543d20SAndroid Build Coastguard Worker 			goto err;
111*2d543d20SAndroid Build Coastguard Worker 		}
112*2d543d20SAndroid Build Coastguard Worker 		rc = fd;
113*2d543d20SAndroid Build Coastguard Worker 		goto err;
114*2d543d20SAndroid Build Coastguard Worker 	}
115*2d543d20SAndroid Build Coastguard Worker 	audit_log_semanage_message(fd, audit_type, NULL, msg, name, 0, sename, roles, mls, psename, proles, pmls, NULL, NULL,NULL, success);
116*2d543d20SAndroid Build Coastguard Worker 	rc = 0;
117*2d543d20SAndroid Build Coastguard Worker err:
118*2d543d20SAndroid Build Coastguard Worker 	audit_close(fd);
119*2d543d20SAndroid Build Coastguard Worker 	free(roles);
120*2d543d20SAndroid Build Coastguard Worker 	free(proles);
121*2d543d20SAndroid Build Coastguard Worker 	return rc;
122*2d543d20SAndroid Build Coastguard Worker }
123*2d543d20SAndroid Build Coastguard Worker 
semanage_seuser_modify_local(semanage_handle_t * handle,const semanage_seuser_key_t * key,const semanage_seuser_t * data)124*2d543d20SAndroid Build Coastguard Worker int semanage_seuser_modify_local(semanage_handle_t * handle,
125*2d543d20SAndroid Build Coastguard Worker 				 const semanage_seuser_key_t * key,
126*2d543d20SAndroid Build Coastguard Worker 				 const semanage_seuser_t * data)
127*2d543d20SAndroid Build Coastguard Worker {
128*2d543d20SAndroid Build Coastguard Worker 	int rc;
129*2d543d20SAndroid Build Coastguard Worker 	void *callback = (void *) handle->msg_callback;
130*2d543d20SAndroid Build Coastguard Worker 	dbase_config_t *dconfig = semanage_seuser_dbase_local(handle);
131*2d543d20SAndroid Build Coastguard Worker 	const char *sename = semanage_seuser_get_sename(data);
132*2d543d20SAndroid Build Coastguard Worker 	const char *mls_range = semanage_seuser_get_mlsrange(data);
133*2d543d20SAndroid Build Coastguard Worker 	semanage_seuser_t *previous = NULL;
134*2d543d20SAndroid Build Coastguard Worker 	semanage_seuser_t *new = NULL;
135*2d543d20SAndroid Build Coastguard Worker 
136*2d543d20SAndroid Build Coastguard Worker 	if (!sename) {
137*2d543d20SAndroid Build Coastguard Worker 		errno = EINVAL;
138*2d543d20SAndroid Build Coastguard Worker 		return -1;
139*2d543d20SAndroid Build Coastguard Worker 	}
140*2d543d20SAndroid Build Coastguard Worker 	rc = semanage_seuser_clone(handle, data, &new);
141*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0) {
142*2d543d20SAndroid Build Coastguard Worker 		goto err;
143*2d543d20SAndroid Build Coastguard Worker 	}
144*2d543d20SAndroid Build Coastguard Worker 
145*2d543d20SAndroid Build Coastguard Worker 	if (!mls_range && semanage_mls_enabled(handle)) {
146*2d543d20SAndroid Build Coastguard Worker 		semanage_user_key_t *ukey = NULL;
147*2d543d20SAndroid Build Coastguard Worker 		semanage_user_t *u = NULL;
148*2d543d20SAndroid Build Coastguard Worker 		rc = semanage_user_key_create(handle, sename, &ukey);
149*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
150*2d543d20SAndroid Build Coastguard Worker 			goto err;
151*2d543d20SAndroid Build Coastguard Worker 
152*2d543d20SAndroid Build Coastguard Worker 		rc = semanage_user_query(handle, ukey, &u);
153*2d543d20SAndroid Build Coastguard Worker 		semanage_user_key_free(ukey);
154*2d543d20SAndroid Build Coastguard Worker 		if (rc >= 0 ) {
155*2d543d20SAndroid Build Coastguard Worker 			mls_range = semanage_user_get_mlsrange(u);
156*2d543d20SAndroid Build Coastguard Worker 			rc = semanage_seuser_set_mlsrange(handle, new, mls_range);
157*2d543d20SAndroid Build Coastguard Worker 			semanage_user_free(u);
158*2d543d20SAndroid Build Coastguard Worker 		}
159*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
160*2d543d20SAndroid Build Coastguard Worker 			goto err;
161*2d543d20SAndroid Build Coastguard Worker 	}
162*2d543d20SAndroid Build Coastguard Worker 
163*2d543d20SAndroid Build Coastguard Worker 	handle->msg_callback = NULL;
164*2d543d20SAndroid Build Coastguard Worker 	(void) semanage_seuser_query(handle, key, &previous);
165*2d543d20SAndroid Build Coastguard Worker 	handle->msg_callback = callback;
166*2d543d20SAndroid Build Coastguard Worker 	rc = dbase_modify(handle, dconfig, key, new);
167*2d543d20SAndroid Build Coastguard Worker 	if (semanage_seuser_audit(handle, new, previous, AUDIT_ROLE_ASSIGN, rc == 0) < 0)
168*2d543d20SAndroid Build Coastguard Worker 		rc = -1;
169*2d543d20SAndroid Build Coastguard Worker err:
170*2d543d20SAndroid Build Coastguard Worker 	if (previous)
171*2d543d20SAndroid Build Coastguard Worker 		semanage_seuser_free(previous);
172*2d543d20SAndroid Build Coastguard Worker 	semanage_seuser_free(new);
173*2d543d20SAndroid Build Coastguard Worker 	return rc;
174*2d543d20SAndroid Build Coastguard Worker }
175*2d543d20SAndroid Build Coastguard Worker 
semanage_seuser_del_local(semanage_handle_t * handle,const semanage_seuser_key_t * key)176*2d543d20SAndroid Build Coastguard Worker int semanage_seuser_del_local(semanage_handle_t * handle,
177*2d543d20SAndroid Build Coastguard Worker 			      const semanage_seuser_key_t * key)
178*2d543d20SAndroid Build Coastguard Worker {
179*2d543d20SAndroid Build Coastguard Worker 	int rc;
180*2d543d20SAndroid Build Coastguard Worker 	semanage_seuser_t *seuser = NULL;
181*2d543d20SAndroid Build Coastguard Worker 	dbase_config_t *dconfig = semanage_seuser_dbase_local(handle);
182*2d543d20SAndroid Build Coastguard Worker 	rc = dbase_del(handle, dconfig, key);
183*2d543d20SAndroid Build Coastguard Worker 	semanage_seuser_query(handle, key, &seuser);
184*2d543d20SAndroid Build Coastguard Worker 	if (semanage_seuser_audit(handle, NULL, seuser, AUDIT_ROLE_REMOVE, rc == 0) < 0)
185*2d543d20SAndroid Build Coastguard Worker 		rc = -1;
186*2d543d20SAndroid Build Coastguard Worker 	if (seuser)
187*2d543d20SAndroid Build Coastguard Worker 		semanage_seuser_free(seuser);
188*2d543d20SAndroid Build Coastguard Worker 	return rc;
189*2d543d20SAndroid Build Coastguard Worker }
190*2d543d20SAndroid Build Coastguard Worker 
semanage_seuser_query_local(semanage_handle_t * handle,const semanage_seuser_key_t * key,semanage_seuser_t ** response)191*2d543d20SAndroid Build Coastguard Worker int semanage_seuser_query_local(semanage_handle_t * handle,
192*2d543d20SAndroid Build Coastguard Worker 				const semanage_seuser_key_t * key,
193*2d543d20SAndroid Build Coastguard Worker 				semanage_seuser_t ** response)
194*2d543d20SAndroid Build Coastguard Worker {
195*2d543d20SAndroid Build Coastguard Worker 
196*2d543d20SAndroid Build Coastguard Worker 	dbase_config_t *dconfig = semanage_seuser_dbase_local(handle);
197*2d543d20SAndroid Build Coastguard Worker 	return dbase_query(handle, dconfig, key, response);
198*2d543d20SAndroid Build Coastguard Worker }
199*2d543d20SAndroid Build Coastguard Worker 
semanage_seuser_exists_local(semanage_handle_t * handle,const semanage_seuser_key_t * key,int * response)200*2d543d20SAndroid Build Coastguard Worker int semanage_seuser_exists_local(semanage_handle_t * handle,
201*2d543d20SAndroid Build Coastguard Worker 				 const semanage_seuser_key_t * key,
202*2d543d20SAndroid Build Coastguard Worker 				 int *response)
203*2d543d20SAndroid Build Coastguard Worker {
204*2d543d20SAndroid Build Coastguard Worker 
205*2d543d20SAndroid Build Coastguard Worker 	dbase_config_t *dconfig = semanage_seuser_dbase_local(handle);
206*2d543d20SAndroid Build Coastguard Worker 	return dbase_exists(handle, dconfig, key, response);
207*2d543d20SAndroid Build Coastguard Worker }
208*2d543d20SAndroid Build Coastguard Worker 
semanage_seuser_count_local(semanage_handle_t * handle,unsigned int * response)209*2d543d20SAndroid Build Coastguard Worker int semanage_seuser_count_local(semanage_handle_t * handle,
210*2d543d20SAndroid Build Coastguard Worker 				unsigned int *response)
211*2d543d20SAndroid Build Coastguard Worker {
212*2d543d20SAndroid Build Coastguard Worker 
213*2d543d20SAndroid Build Coastguard Worker 	dbase_config_t *dconfig = semanage_seuser_dbase_local(handle);
214*2d543d20SAndroid Build Coastguard Worker 	return dbase_count(handle, dconfig, response);
215*2d543d20SAndroid Build Coastguard Worker }
216*2d543d20SAndroid Build Coastguard Worker 
semanage_seuser_iterate_local(semanage_handle_t * handle,int (* handler)(const semanage_seuser_t * record,void * varg),void * handler_arg)217*2d543d20SAndroid Build Coastguard Worker int semanage_seuser_iterate_local(semanage_handle_t * handle,
218*2d543d20SAndroid Build Coastguard Worker 				  int (*handler) (const semanage_seuser_t *
219*2d543d20SAndroid Build Coastguard Worker 						  record, void *varg),
220*2d543d20SAndroid Build Coastguard Worker 				  void *handler_arg)
221*2d543d20SAndroid Build Coastguard Worker {
222*2d543d20SAndroid Build Coastguard Worker 
223*2d543d20SAndroid Build Coastguard Worker 	dbase_config_t *dconfig = semanage_seuser_dbase_local(handle);
224*2d543d20SAndroid Build Coastguard Worker 	return dbase_iterate(handle, dconfig, handler, handler_arg);
225*2d543d20SAndroid Build Coastguard Worker }
226*2d543d20SAndroid Build Coastguard Worker 
227*2d543d20SAndroid Build Coastguard Worker 
semanage_seuser_list_local(semanage_handle_t * handle,semanage_seuser_t *** records,unsigned int * count)228*2d543d20SAndroid Build Coastguard Worker int semanage_seuser_list_local(semanage_handle_t * handle,
229*2d543d20SAndroid Build Coastguard Worker 			       semanage_seuser_t *** records,
230*2d543d20SAndroid Build Coastguard Worker 			       unsigned int *count)
231*2d543d20SAndroid Build Coastguard Worker {
232*2d543d20SAndroid Build Coastguard Worker 
233*2d543d20SAndroid Build Coastguard Worker 	dbase_config_t *dconfig = semanage_seuser_dbase_local(handle);
234*2d543d20SAndroid Build Coastguard Worker 	return dbase_list(handle, dconfig, records, count);
235*2d543d20SAndroid Build Coastguard Worker }
236*2d543d20SAndroid Build Coastguard Worker 
237*2d543d20SAndroid Build Coastguard Worker struct validate_handler_arg {
238*2d543d20SAndroid Build Coastguard Worker 	semanage_handle_t *handle;
239*2d543d20SAndroid Build Coastguard Worker 	const sepol_policydb_t *policydb;
240*2d543d20SAndroid Build Coastguard Worker };
241*2d543d20SAndroid Build Coastguard Worker 
validate_handler(const semanage_seuser_t * seuser,void * varg)242*2d543d20SAndroid Build Coastguard Worker static int validate_handler(const semanage_seuser_t * seuser, void *varg)
243*2d543d20SAndroid Build Coastguard Worker {
244*2d543d20SAndroid Build Coastguard Worker 
245*2d543d20SAndroid Build Coastguard Worker 	semanage_user_t *user = NULL;
246*2d543d20SAndroid Build Coastguard Worker 	semanage_user_key_t *key = NULL;
247*2d543d20SAndroid Build Coastguard Worker 	int exists, mls_ok;
248*2d543d20SAndroid Build Coastguard Worker 
249*2d543d20SAndroid Build Coastguard Worker 	/* Unpack varg */
250*2d543d20SAndroid Build Coastguard Worker 	struct validate_handler_arg *arg = (struct validate_handler_arg *)varg;
251*2d543d20SAndroid Build Coastguard Worker 	semanage_handle_t *handle = arg->handle;
252*2d543d20SAndroid Build Coastguard Worker 	const sepol_policydb_t *policydb = arg->policydb;
253*2d543d20SAndroid Build Coastguard Worker 
254*2d543d20SAndroid Build Coastguard Worker 	/* Unpack seuser */
255*2d543d20SAndroid Build Coastguard Worker 	const char *name = semanage_seuser_get_name(seuser);
256*2d543d20SAndroid Build Coastguard Worker 	const char *sename = semanage_seuser_get_sename(seuser);
257*2d543d20SAndroid Build Coastguard Worker 	const char *mls_range = semanage_seuser_get_mlsrange(seuser);
258*2d543d20SAndroid Build Coastguard Worker 	const char *user_mls_range;
259*2d543d20SAndroid Build Coastguard Worker 
260*2d543d20SAndroid Build Coastguard Worker 	/* Make sure the (SElinux) user exists */
261*2d543d20SAndroid Build Coastguard Worker 	if (semanage_user_key_create(handle, sename, &key) < 0)
262*2d543d20SAndroid Build Coastguard Worker 		goto err;
263*2d543d20SAndroid Build Coastguard Worker 	if (semanage_user_exists(handle, key, &exists) < 0)
264*2d543d20SAndroid Build Coastguard Worker 		goto err;
265*2d543d20SAndroid Build Coastguard Worker 	if (!exists) {
266*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "selinux user %s does not exist", sename);
267*2d543d20SAndroid Build Coastguard Worker 		goto invalid;
268*2d543d20SAndroid Build Coastguard Worker 	}
269*2d543d20SAndroid Build Coastguard Worker 
270*2d543d20SAndroid Build Coastguard Worker 	/* Verify that the mls range is valid, and that it's contained
271*2d543d20SAndroid Build Coastguard Worker 	 * within the (SELinux) user mls range. This range is optional */
272*2d543d20SAndroid Build Coastguard Worker 	if (mls_range && sepol_policydb_mls_enabled(policydb)) {
273*2d543d20SAndroid Build Coastguard Worker 
274*2d543d20SAndroid Build Coastguard Worker 		if (semanage_user_query(handle, key, &user) < 0)
275*2d543d20SAndroid Build Coastguard Worker 			goto err;
276*2d543d20SAndroid Build Coastguard Worker 		user_mls_range = semanage_user_get_mlsrange(user);
277*2d543d20SAndroid Build Coastguard Worker 
278*2d543d20SAndroid Build Coastguard Worker 		if (sepol_mls_check(handle->sepolh, policydb, mls_range) < 0)
279*2d543d20SAndroid Build Coastguard Worker 			goto invalid;
280*2d543d20SAndroid Build Coastguard Worker 		if (sepol_mls_contains(handle->sepolh, policydb,
281*2d543d20SAndroid Build Coastguard Worker 				       user_mls_range, mls_range, &mls_ok) < 0)
282*2d543d20SAndroid Build Coastguard Worker 			goto err;
283*2d543d20SAndroid Build Coastguard Worker 
284*2d543d20SAndroid Build Coastguard Worker 		if (!mls_ok) {
285*2d543d20SAndroid Build Coastguard Worker 			ERR(handle, "MLS range %s for Unix user %s "
286*2d543d20SAndroid Build Coastguard Worker 			    "exceeds allowed range %s for SELinux user %s",
287*2d543d20SAndroid Build Coastguard Worker 			    mls_range, name, user_mls_range, sename);
288*2d543d20SAndroid Build Coastguard Worker 			goto invalid;
289*2d543d20SAndroid Build Coastguard Worker 		}
290*2d543d20SAndroid Build Coastguard Worker 
291*2d543d20SAndroid Build Coastguard Worker 	} else if (mls_range) {
292*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "MLS is disabled, but MLS range %s "
293*2d543d20SAndroid Build Coastguard Worker 		    "was found for Unix user %s", mls_range, name);
294*2d543d20SAndroid Build Coastguard Worker 		goto invalid;
295*2d543d20SAndroid Build Coastguard Worker 	}
296*2d543d20SAndroid Build Coastguard Worker 
297*2d543d20SAndroid Build Coastguard Worker 	semanage_user_key_free(key);
298*2d543d20SAndroid Build Coastguard Worker 	semanage_user_free(user);
299*2d543d20SAndroid Build Coastguard Worker 	return 0;
300*2d543d20SAndroid Build Coastguard Worker 
301*2d543d20SAndroid Build Coastguard Worker       err:
302*2d543d20SAndroid Build Coastguard Worker 	ERR(handle, "could not check if seuser mapping for %s is valid", name);
303*2d543d20SAndroid Build Coastguard Worker 	semanage_user_key_free(key);
304*2d543d20SAndroid Build Coastguard Worker 	semanage_user_free(user);
305*2d543d20SAndroid Build Coastguard Worker 	return -1;
306*2d543d20SAndroid Build Coastguard Worker 
307*2d543d20SAndroid Build Coastguard Worker       invalid:
308*2d543d20SAndroid Build Coastguard Worker 	if (mls_range)
309*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "seuser mapping [%s -> (%s, %s)] is invalid",
310*2d543d20SAndroid Build Coastguard Worker 		    name, sename, mls_range);
311*2d543d20SAndroid Build Coastguard Worker 	else
312*2d543d20SAndroid Build Coastguard Worker 		ERR(handle, "seuser mapping [%s -> %s] is invalid",
313*2d543d20SAndroid Build Coastguard Worker 		    name, sename);
314*2d543d20SAndroid Build Coastguard Worker 	semanage_user_key_free(key);
315*2d543d20SAndroid Build Coastguard Worker 	semanage_user_free(user);
316*2d543d20SAndroid Build Coastguard Worker 	return -1;
317*2d543d20SAndroid Build Coastguard Worker }
318*2d543d20SAndroid Build Coastguard Worker 
319*2d543d20SAndroid Build Coastguard Worker /* This function may not be called outside a transaction, or
320*2d543d20SAndroid Build Coastguard Worker  * it will (1) deadlock, because iterate is not reentrant outside
321*2d543d20SAndroid Build Coastguard Worker  * a transaction, and (2) be racy, because it makes multiple dbase calls */
322*2d543d20SAndroid Build Coastguard Worker 
semanage_seuser_validate_local(semanage_handle_t * handle,const sepol_policydb_t * policydb)323*2d543d20SAndroid Build Coastguard Worker int semanage_seuser_validate_local(semanage_handle_t * handle,
324*2d543d20SAndroid Build Coastguard Worker 					  const sepol_policydb_t * policydb)
325*2d543d20SAndroid Build Coastguard Worker {
326*2d543d20SAndroid Build Coastguard Worker 
327*2d543d20SAndroid Build Coastguard Worker 	struct validate_handler_arg arg;
328*2d543d20SAndroid Build Coastguard Worker 	arg.handle = handle;
329*2d543d20SAndroid Build Coastguard Worker 	arg.policydb = policydb;
330*2d543d20SAndroid Build Coastguard Worker 	return semanage_seuser_iterate_local(handle, validate_handler, &arg);
331*2d543d20SAndroid Build Coastguard Worker }
332