Home | History | Annotate | Download | only in src
      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 */
     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 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 
     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 
     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 
     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 
     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 
     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 */
     95 const char *semanage_user_get_name(const semanage_user_t * user)
     96 {
     97 	return user->name;
     98 }
     99 
    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 
    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 
    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 */
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 */
    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 
    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 
    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 
    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 
    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