xref: /aosp_15_r20/external/selinux/libsemanage/src/user_record.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1 /* Copyright (C) 2005 Red Hat, Inc. */
2 
3 /* Object: semanage_user_t (SELinux User/Class)
4  * Object: semanage_user_key_t (SELinux User/Class Key)
5  * Implements: record_t (Database Record)
6  * Implements: record_key_t (Database Record Key)
7  */
8 
9 #include <sepol/user_record.h>
10 
11 typedef sepol_user_key_t semanage_user_key_t;
12 #define _SEMANAGE_USER_KEY_DEFINED_
13 
14 struct semanage_user;
15 typedef struct semanage_user record_t;
16 typedef semanage_user_key_t record_key_t;
17 #define DBASE_RECORD_DEFINED
18 
19 #include <stdlib.h>
20 #include <string.h>
21 #include "user_internal.h"
22 #include "handle.h"
23 #include "database.h"
24 #include "debug.h"
25 
26 struct semanage_user {
27 	char *name;
28 	semanage_user_base_t *base;
29 	semanage_user_extra_t *extra;
30 };
31 
32 /* Key */
semanage_user_key_create(semanage_handle_t * handle,const char * name,semanage_user_key_t ** key)33 int semanage_user_key_create(semanage_handle_t * handle,
34 			     const char *name, semanage_user_key_t ** key)
35 {
36 
37 	return sepol_user_key_create(handle->sepolh, name, key);
38 }
39 
40 
semanage_user_key_extract(semanage_handle_t * handle,const semanage_user_t * user,semanage_user_key_t ** key)41 int semanage_user_key_extract(semanage_handle_t * handle,
42 			      const semanage_user_t * user,
43 			      semanage_user_key_t ** key)
44 {
45 
46 	return semanage_user_base_key_extract(handle, user->base, key);
47 }
48 
49 
semanage_user_key_free(semanage_user_key_t * key)50 void semanage_user_key_free(semanage_user_key_t * key)
51 {
52 
53 	sepol_user_key_free(key);
54 }
55 
56 
semanage_user_key_unpack(const semanage_user_key_t * key,const char ** name)57  void semanage_user_key_unpack(const semanage_user_key_t * key,
58 				     const char **name)
59 {
60 
61 	sepol_user_key_unpack(key, name);
62 }
63 
semanage_user_compare(const semanage_user_t * user,const semanage_user_key_t * key)64 int semanage_user_compare(const semanage_user_t * user,
65 			  const semanage_user_key_t * key)
66 {
67 
68 	const char *name;
69 	sepol_user_key_unpack(key, &name);
70 	return strcmp(user->name, name);
71 }
72 
73 
semanage_user_compare2(const semanage_user_t * user,const semanage_user_t * user2)74 int semanage_user_compare2(const semanage_user_t * user,
75 			   const semanage_user_t * user2)
76 {
77 
78 	return strcmp(user->name, user2->name);
79 }
80 
81 
semanage_user_compare2_qsort(const semanage_user_t ** user,const semanage_user_t ** user2)82 static int semanage_user_compare2_qsort(const semanage_user_t ** user,
83 					const semanage_user_t ** user2)
84 {
85 
86 	return strcmp((*user)->name, (*user2)->name);
87 }
88 
89 /* Name */
semanage_user_get_name(const semanage_user_t * user)90 const char *semanage_user_get_name(const semanage_user_t * user)
91 {
92 	return user->name;
93 }
94 
95 
semanage_user_set_name(semanage_handle_t * handle,semanage_user_t * user,const char * name)96 int semanage_user_set_name(semanage_handle_t * handle,
97 			   semanage_user_t * user, const char *name)
98 {
99 
100 	char *tmp_name = strdup(name);
101 	if (!tmp_name)
102 		goto omem;
103 
104 	if (semanage_user_base_set_name(handle, user->base, name) < 0)
105 		goto err;
106 
107 	if (semanage_user_extra_set_name(handle, user->extra, name) < 0)
108 		goto err;
109 
110 	free(user->name);
111 	user->name = tmp_name;
112 	return STATUS_SUCCESS;
113 
114       omem:
115 	ERR(handle, "out of memory");
116 
117       err:
118 	ERR(handle, "could not set user name to %s", name);
119 	free(tmp_name);
120 	return STATUS_ERR;
121 }
122 
123 
124 /* Labeling prefix */
semanage_user_get_prefix(const semanage_user_t * user)125 const char *semanage_user_get_prefix(const semanage_user_t * user)
126 {
127 
128 	return semanage_user_extra_get_prefix(user->extra);
129 }
130 
semanage_user_set_prefix(semanage_handle_t * handle,semanage_user_t * user,const char * name)131 int semanage_user_set_prefix(semanage_handle_t * handle,
132 			     semanage_user_t * user, const char *name)
133 {
134 
135 	return semanage_user_extra_set_prefix(handle, user->extra, name);
136 }
137 
138 /* MLS */
semanage_user_get_mlslevel(const semanage_user_t * user)139 const char *semanage_user_get_mlslevel(const semanage_user_t * user)
140 {
141 
142 	return semanage_user_base_get_mlslevel(user->base);
143 }
144 
145 
semanage_user_set_mlslevel(semanage_handle_t * handle,semanage_user_t * user,const char * mls_level)146 int semanage_user_set_mlslevel(semanage_handle_t * handle,
147 			       semanage_user_t * user, const char *mls_level)
148 {
149 
150 	return semanage_user_base_set_mlslevel(handle, user->base, mls_level);
151 }
152 
153 
semanage_user_get_mlsrange(const semanage_user_t * user)154 const char *semanage_user_get_mlsrange(const semanage_user_t * user)
155 {
156 
157 	return semanage_user_base_get_mlsrange(user->base);
158 }
159 
160 
semanage_user_set_mlsrange(semanage_handle_t * handle,semanage_user_t * user,const char * mls_range)161 int semanage_user_set_mlsrange(semanage_handle_t * handle,
162 			       semanage_user_t * user, const char *mls_range)
163 {
164 
165 	return semanage_user_base_set_mlsrange(handle, user->base, mls_range);
166 }
167 
168 
169 /* Role management */
semanage_user_get_num_roles(const semanage_user_t * user)170 int semanage_user_get_num_roles(const semanage_user_t * user)
171 {
172 
173 	return semanage_user_base_get_num_roles(user->base);
174 }
175 
semanage_user_add_role(semanage_handle_t * handle,semanage_user_t * user,const char * role)176 int semanage_user_add_role(semanage_handle_t * handle,
177 			   semanage_user_t * user, const char *role)
178 {
179 
180 	return semanage_user_base_add_role(handle, user->base, role);
181 }
182 
183 
semanage_user_del_role(semanage_user_t * user,const char * role)184 void semanage_user_del_role(semanage_user_t * user, const char *role)
185 {
186 
187 	semanage_user_base_del_role(user->base, role);
188 }
189 
semanage_user_has_role(const semanage_user_t * user,const char * role)190 int semanage_user_has_role(const semanage_user_t * user, const char *role)
191 {
192 
193 	return semanage_user_base_has_role(user->base, role);
194 }
195 
semanage_user_get_roles(semanage_handle_t * handle,const semanage_user_t * user,const char *** roles_arr,unsigned int * num_roles)196 int semanage_user_get_roles(semanage_handle_t * handle,
197 			    const semanage_user_t * user,
198 			    const char ***roles_arr, unsigned int *num_roles)
199 {
200 
201 	return semanage_user_base_get_roles(handle, user->base, roles_arr,
202 					    num_roles);
203 }
204 
205 
semanage_user_set_roles(semanage_handle_t * handle,semanage_user_t * user,const char ** roles_arr,unsigned int num_roles)206 int semanage_user_set_roles(semanage_handle_t * handle,
207 			    semanage_user_t * user,
208 			    const char **roles_arr, unsigned int num_roles)
209 {
210 
211 	return semanage_user_base_set_roles(handle, user->base, roles_arr,
212 					    num_roles);
213 }
214 
215 /* Create/Clone/Destroy */
semanage_user_create(semanage_handle_t * handle,semanage_user_t ** user_ptr)216 int semanage_user_create(semanage_handle_t * handle,
217 			 semanage_user_t ** user_ptr)
218 {
219 
220 	semanage_user_t *tmp_user = calloc(1, sizeof(semanage_user_t));
221 	if (!tmp_user)
222 		goto omem;
223 
224 	if (semanage_user_base_create(handle, &tmp_user->base) < 0)
225 		goto err;
226 	if (semanage_user_extra_create(handle, &tmp_user->extra) < 0)
227 		goto err;
228 
229 	/* Initialize the prefix for migration purposes */
230 	if (semanage_user_extra_set_prefix(handle, tmp_user->extra, "user") < 0)
231 		goto err;
232 
233 	*user_ptr = tmp_user;
234 	return STATUS_SUCCESS;
235 
236       omem:
237 	ERR(handle, "out of memory");
238 
239       err:
240 	ERR(handle, "could not create user record");
241 	semanage_user_free(tmp_user);
242 	return STATUS_ERR;
243 }
244 
245 
semanage_user_clone(semanage_handle_t * handle,const semanage_user_t * user,semanage_user_t ** user_ptr)246 int semanage_user_clone(semanage_handle_t * handle,
247 			const semanage_user_t * user,
248 			semanage_user_t ** user_ptr)
249 {
250 
251 	semanage_user_t *tmp_user = calloc(1, sizeof(semanage_user_t));
252 	if (!tmp_user)
253 		goto omem;
254 
255 	/* Clone base and extra records */
256 	if (semanage_user_base_clone(handle, user->base, &tmp_user->base) < 0)
257 		goto err;
258 	if (semanage_user_extra_clone(handle, user->extra, &tmp_user->extra) <
259 	    0)
260 		goto err;
261 
262 	/* Set the shared name */
263 	if (semanage_user_set_name(handle, tmp_user, user->name) < 0)
264 		goto err;
265 
266 	*user_ptr = tmp_user;
267 	return STATUS_SUCCESS;
268 
269       omem:
270 	ERR(handle, "out of memory");
271 
272       err:
273 	ERR(handle, "could not clone user record");
274 	semanage_user_free(tmp_user);
275 	return STATUS_ERR;
276 }
277 
278 
semanage_user_free(semanage_user_t * user)279 void semanage_user_free(semanage_user_t * user)
280 {
281 
282 	if (!user)
283 		return;
284 
285 	semanage_user_base_free(user->base);
286 	semanage_user_extra_free(user->extra);
287 	free(user->name);
288 	free(user);
289 }
290 
291 
292 /* Join properties */
semanage_user_join(semanage_handle_t * handle,const semanage_user_base_t * record1,const semanage_user_extra_t * record2,semanage_user_t ** result)293  int semanage_user_join(semanage_handle_t * handle,
294 			      const semanage_user_base_t * record1,
295 			      const semanage_user_extra_t * record2,
296 			      semanage_user_t ** result)
297 {
298 
299 	const char *name;
300 	semanage_user_t *tmp_user = calloc(1, sizeof(semanage_user_t));
301 	if (!tmp_user)
302 		goto omem;
303 
304 	/* Set the shared name from one of the records
305 	 * (at least one is available) */
306 	if (record1 == NULL)
307 		name = semanage_user_extra_get_name(record2);
308 	else
309 		name = semanage_user_base_get_name(record1);
310 
311 	/* Join base record if it exists, create a blank one otherwise */
312 	if (record1) {
313 		if (semanage_user_base_clone(handle, record1, &tmp_user->base) <
314 		    0)
315 			goto err;
316 	} else {
317 		if (semanage_user_base_create(handle, &tmp_user->base) < 0)
318 			goto err;
319 		if (semanage_user_base_set_name(handle, tmp_user->base, name) <
320 		    0)
321 			goto err;
322 	}
323 
324 	/* Join extra record if it exists, create a blank one otherwise */
325 	if (record2) {
326 		if (semanage_user_extra_clone(handle, record2, &tmp_user->extra)
327 		    < 0)
328 			goto err;
329 	} else {
330 		if (semanage_user_extra_create(handle, &tmp_user->extra) < 0)
331 			goto err;
332 		if (semanage_user_extra_set_name(handle, tmp_user->extra, name)
333 		    < 0)
334 			goto err;
335 		if (semanage_user_extra_set_prefix
336 		    (handle, tmp_user->extra, "user") < 0)
337 			goto err;
338 	}
339 
340 	if (semanage_user_set_name(handle, tmp_user, name) < 0)
341 		goto err;
342 
343 	*result = tmp_user;
344 	return STATUS_SUCCESS;
345 
346       omem:
347 	ERR(handle, "out of memory");
348 
349       err:
350 	ERR(handle, "could not join data records for user %s",
351 	    semanage_user_base_get_name(record1));
352 	semanage_user_free(tmp_user);
353 	return STATUS_ERR;
354 }
355 
semanage_user_split(semanage_handle_t * handle,const semanage_user_t * record,semanage_user_base_t ** split1,semanage_user_extra_t ** split2)356  int semanage_user_split(semanage_handle_t * handle,
357 			       const semanage_user_t * record,
358 			       semanage_user_base_t ** split1,
359 			       semanage_user_extra_t ** split2)
360 {
361 
362 	semanage_user_base_t *tmp_base_user = NULL;
363 	semanage_user_extra_t *tmp_extra_user = NULL;
364 
365 	if (semanage_user_base_clone(handle, record->base, &tmp_base_user) < 0)
366 		goto err;
367 
368 	if (semanage_user_extra_clone(handle, record->extra, &tmp_extra_user) <
369 	    0)
370 		goto err;
371 
372 	*split1 = tmp_base_user;
373 	*split2 = tmp_extra_user;
374 	return STATUS_SUCCESS;
375 
376       err:
377 	ERR(handle, "could not split data records for user %s",
378 	    semanage_user_get_name(record));
379 	semanage_user_base_free(tmp_base_user);
380 	semanage_user_extra_free(tmp_extra_user);
381 	return STATUS_ERR;
382 }
383 
384 /* Record base functions */
385 record_table_t SEMANAGE_USER_RTABLE = {
386 	.create = semanage_user_create,
387 	.key_extract = semanage_user_key_extract,
388 	.key_free = semanage_user_key_free,
389 	.clone = semanage_user_clone,
390 	.compare = semanage_user_compare,
391 	.compare2 = semanage_user_compare2,
392 	.compare2_qsort = semanage_user_compare2_qsort,
393 	.free = semanage_user_free,
394 };
395