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