Home | History | Annotate | Download | only in src
      1 #include <errno.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 
      5 #include "user_internal.h"
      6 #include "debug.h"
      7 
      8 struct sepol_user {
      9 	/* This user's name */
     10 	char *name;
     11 
     12 	/* This user's mls level (only required for mls) */
     13 	char *mls_level;
     14 
     15 	/* This user's mls range (only required for mls) */
     16 	char *mls_range;
     17 
     18 	/* The role array */
     19 	char **roles;
     20 
     21 	/* The number of roles */
     22 	unsigned int num_roles;
     23 };
     24 
     25 struct sepol_user_key {
     26 	/* This user's name */
     27 	char *name;
     28 };
     29 
     30 int sepol_user_key_create(sepol_handle_t * handle,
     31 			  const char *name, sepol_user_key_t ** key_ptr)
     32 {
     33 
     34 	sepol_user_key_t *tmp_key =
     35 	    (sepol_user_key_t *) malloc(sizeof(sepol_user_key_t));
     36 
     37 	if (!tmp_key) {
     38 		ERR(handle, "out of memory, "
     39 		    "could not create selinux user key");
     40 		return STATUS_ERR;
     41 	}
     42 
     43 	tmp_key->name = strdup(name);
     44 	if (!tmp_key->name) {
     45 		ERR(handle, "out of memory, could not create selinux user key");
     46 		free(tmp_key);
     47 		return STATUS_ERR;
     48 	}
     49 
     50 	*key_ptr = tmp_key;
     51 	return STATUS_SUCCESS;
     52 }
     53 
     54 hidden_def(sepol_user_key_create)
     55 
     56 void sepol_user_key_unpack(const sepol_user_key_t * key, const char **name)
     57 {
     58 
     59 	*name = key->name;
     60 }
     61 
     62 hidden_def(sepol_user_key_unpack)
     63 
     64 int sepol_user_key_extract(sepol_handle_t * handle,
     65 			   const sepol_user_t * user,
     66 			   sepol_user_key_t ** key_ptr)
     67 {
     68 
     69 	if (sepol_user_key_create(handle, user->name, key_ptr) < 0) {
     70 		ERR(handle, "could not extract key from user %s", user->name);
     71 		return STATUS_ERR;
     72 	}
     73 
     74 	return STATUS_SUCCESS;
     75 }
     76 
     77 void sepol_user_key_free(sepol_user_key_t * key)
     78 {
     79 	free(key->name);
     80 	free(key);
     81 }
     82 
     83 int sepol_user_compare(const sepol_user_t * user, const sepol_user_key_t * key)
     84 {
     85 
     86 	return strcmp(user->name, key->name);
     87 }
     88 
     89 int sepol_user_compare2(const sepol_user_t * user, const sepol_user_t * user2)
     90 {
     91 
     92 	return strcmp(user->name, user2->name);
     93 }
     94 
     95 /* Name */
     96 const char *sepol_user_get_name(const sepol_user_t * user)
     97 {
     98 
     99 	return user->name;
    100 }
    101 
    102 int sepol_user_set_name(sepol_handle_t * handle,
    103 			sepol_user_t * user, const char *name)
    104 {
    105 
    106 	char *tmp_name = strdup(name);
    107 	if (!tmp_name) {
    108 		ERR(handle, "out of memory, could not set name");
    109 		return STATUS_ERR;
    110 	}
    111 	free(user->name);
    112 	user->name = tmp_name;
    113 	return STATUS_SUCCESS;
    114 }
    115 
    116 hidden_def(sepol_user_set_name)
    117 
    118 /* MLS */
    119 const char *sepol_user_get_mlslevel(const sepol_user_t * user)
    120 {
    121 
    122 	return user->mls_level;
    123 }
    124 
    125 hidden_def(sepol_user_get_mlslevel)
    126 
    127 int sepol_user_set_mlslevel(sepol_handle_t * handle,
    128 			    sepol_user_t * user, const char *mls_level)
    129 {
    130 
    131 	char *tmp_mls_level = strdup(mls_level);
    132 	if (!tmp_mls_level) {
    133 		ERR(handle, "out of memory, "
    134 		    "could not set MLS default level");
    135 		return STATUS_ERR;
    136 	}
    137 	free(user->mls_level);
    138 	user->mls_level = tmp_mls_level;
    139 	return STATUS_SUCCESS;
    140 }
    141 
    142 hidden_def(sepol_user_set_mlslevel)
    143 
    144 const char *sepol_user_get_mlsrange(const sepol_user_t * user)
    145 {
    146 
    147 	return user->mls_range;
    148 }
    149 
    150 hidden_def(sepol_user_get_mlsrange)
    151 
    152 int sepol_user_set_mlsrange(sepol_handle_t * handle,
    153 			    sepol_user_t * user, const char *mls_range)
    154 {
    155 
    156 	char *tmp_mls_range = strdup(mls_range);
    157 	if (!tmp_mls_range) {
    158 		ERR(handle, "out of memory, "
    159 		    "could not set MLS allowed range");
    160 		return STATUS_ERR;
    161 	}
    162 	free(user->mls_range);
    163 	user->mls_range = tmp_mls_range;
    164 	return STATUS_SUCCESS;
    165 }
    166 
    167 hidden_def(sepol_user_set_mlsrange)
    168 
    169 /* Roles */
    170 int sepol_user_get_num_roles(const sepol_user_t * user)
    171 {
    172 
    173 	return user->num_roles;
    174 }
    175 
    176 int sepol_user_add_role(sepol_handle_t * handle,
    177 			sepol_user_t * user, const char *role)
    178 {
    179 
    180 	char *role_cp;
    181 	char **roles_realloc;
    182 
    183 	if (sepol_user_has_role(user, role))
    184 		return STATUS_SUCCESS;
    185 
    186 	role_cp = strdup(role);
    187 	roles_realloc = realloc(user->roles,
    188 				sizeof(char *) * (user->num_roles + 1));
    189 
    190 	if (!role_cp || !roles_realloc)
    191 		goto omem;
    192 
    193 	user->num_roles++;
    194 	user->roles = roles_realloc;
    195 	user->roles[user->num_roles - 1] = role_cp;
    196 
    197 	return STATUS_SUCCESS;
    198 
    199       omem:
    200 	ERR(handle, "out of memory, could not add role %s", role);
    201 	free(role_cp);
    202 	free(roles_realloc);
    203 	return STATUS_ERR;
    204 }
    205 
    206 hidden_def(sepol_user_add_role)
    207 
    208 int sepol_user_has_role(const sepol_user_t * user, const char *role)
    209 {
    210 
    211 	unsigned int i;
    212 
    213 	for (i = 0; i < user->num_roles; i++)
    214 		if (!strcmp(user->roles[i], role))
    215 			return 1;
    216 	return 0;
    217 }
    218 
    219 hidden_def(sepol_user_has_role)
    220 
    221 int sepol_user_set_roles(sepol_handle_t * handle,
    222 			 sepol_user_t * user,
    223 			 const char **roles_arr, unsigned int num_roles)
    224 {
    225 
    226 	unsigned int i;
    227 	char **tmp_roles = NULL;
    228 
    229 	if (num_roles > 0) {
    230 
    231 		/* First, make a copy */
    232 		tmp_roles = (char **)calloc(1, sizeof(char *) * num_roles);
    233 		if (!tmp_roles)
    234 			goto omem;
    235 
    236 		for (i = 0; i < num_roles; i++) {
    237 			tmp_roles[i] = strdup(roles_arr[i]);
    238 			if (!tmp_roles[i])
    239 				goto omem;
    240 		}
    241 	}
    242 
    243 	/* Apply other changes */
    244 	for (i = 0; i < user->num_roles; i++)
    245 		free(user->roles[i]);
    246 	free(user->roles);
    247 	user->roles = tmp_roles;
    248 	user->num_roles = num_roles;
    249 	return STATUS_SUCCESS;
    250 
    251       omem:
    252 	ERR(handle, "out of memory, could not allocate roles array for"
    253 	    "user %s", user->name);
    254 
    255 	if (tmp_roles) {
    256 		for (i = 0; i < num_roles; i++) {
    257 			if (!tmp_roles[i])
    258 				break;
    259 			free(tmp_roles[i]);
    260 		}
    261 	}
    262 	free(tmp_roles);
    263 	return STATUS_ERR;
    264 }
    265 
    266 int sepol_user_get_roles(sepol_handle_t * handle,
    267 			 const sepol_user_t * user,
    268 			 const char ***roles_arr, unsigned int *num_roles)
    269 {
    270 
    271 	unsigned int i;
    272 	const char **tmp_roles =
    273 	    (const char **)malloc(sizeof(char *) * user->num_roles);
    274 	if (!tmp_roles)
    275 		goto omem;
    276 
    277 	for (i = 0; i < user->num_roles; i++)
    278 		tmp_roles[i] = user->roles[i];
    279 
    280 	*roles_arr = tmp_roles;
    281 	*num_roles = user->num_roles;
    282 	return STATUS_SUCCESS;
    283 
    284       omem:
    285 	ERR(handle, "out of memory, could not "
    286 	    "allocate roles array for user %s", user->name);
    287 	free(tmp_roles);
    288 	return STATUS_ERR;
    289 }
    290 
    291 hidden_def(sepol_user_get_roles)
    292 
    293 void sepol_user_del_role(sepol_user_t * user, const char *role)
    294 {
    295 
    296 	unsigned int i;
    297 	for (i = 0; i < user->num_roles; i++) {
    298 		if (!strcmp(user->roles[i], role)) {
    299 			free(user->roles[i]);
    300 			user->roles[i] = NULL;
    301 			user->roles[i] = user->roles[user->num_roles - 1];
    302 			user->num_roles--;
    303 		}
    304 	}
    305 }
    306 
    307 /* Create */
    308 int sepol_user_create(sepol_handle_t * handle, sepol_user_t ** user_ptr)
    309 {
    310 
    311 	sepol_user_t *user = (sepol_user_t *) malloc(sizeof(sepol_user_t));
    312 
    313 	if (!user) {
    314 		ERR(handle, "out of memory, "
    315 		    "could not create selinux user record");
    316 		return STATUS_ERR;
    317 	}
    318 
    319 	user->roles = NULL;
    320 	user->num_roles = 0;
    321 	user->name = NULL;
    322 	user->mls_level = NULL;
    323 	user->mls_range = NULL;
    324 
    325 	*user_ptr = user;
    326 	return STATUS_SUCCESS;
    327 }
    328 
    329 hidden_def(sepol_user_create)
    330 
    331 /* Deep copy clone */
    332 int sepol_user_clone(sepol_handle_t * handle,
    333 		     const sepol_user_t * user, sepol_user_t ** user_ptr)
    334 {
    335 
    336 	sepol_user_t *new_user = NULL;
    337 	unsigned int i;
    338 
    339 	if (sepol_user_create(handle, &new_user) < 0)
    340 		goto err;
    341 
    342 	if (sepol_user_set_name(handle, new_user, user->name) < 0)
    343 		goto err;
    344 
    345 	for (i = 0; i < user->num_roles; i++) {
    346 		if (sepol_user_add_role(handle, new_user, user->roles[i]) < 0)
    347 			goto err;
    348 	}
    349 
    350 	if (user->mls_level &&
    351 	    (sepol_user_set_mlslevel(handle, new_user, user->mls_level) < 0))
    352 		goto err;
    353 
    354 	if (user->mls_range &&
    355 	    (sepol_user_set_mlsrange(handle, new_user, user->mls_range) < 0))
    356 		goto err;
    357 
    358 	*user_ptr = new_user;
    359 	return STATUS_SUCCESS;
    360 
    361       err:
    362 	ERR(handle, "could not clone selinux user record");
    363 	sepol_user_free(new_user);
    364 	return STATUS_ERR;
    365 }
    366 
    367 /* Destroy */
    368 void sepol_user_free(sepol_user_t * user)
    369 {
    370 
    371 	unsigned int i;
    372 
    373 	if (!user)
    374 		return;
    375 
    376 	free(user->name);
    377 	for (i = 0; i < user->num_roles; i++)
    378 		free(user->roles[i]);
    379 	free(user->roles);
    380 	free(user->mls_level);
    381 	free(user->mls_range);
    382 	free(user);
    383 }
    384 
    385 hidden_def(sepol_user_free)
    386