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 	if (!key)
     80 		return;
     81 	free(key->name);
     82 	free(key);
     83 }
     84 
     85 int sepol_user_compare(const sepol_user_t * user, const sepol_user_key_t * key)
     86 {
     87 
     88 	return strcmp(user->name, key->name);
     89 }
     90 
     91 int sepol_user_compare2(const sepol_user_t * user, const sepol_user_t * user2)
     92 {
     93 
     94 	return strcmp(user->name, user2->name);
     95 }
     96 
     97 /* Name */
     98 const char *sepol_user_get_name(const sepol_user_t * user)
     99 {
    100 
    101 	return user->name;
    102 }
    103 
    104 int sepol_user_set_name(sepol_handle_t * handle,
    105 			sepol_user_t * user, const char *name)
    106 {
    107 
    108 	char *tmp_name = strdup(name);
    109 	if (!tmp_name) {
    110 		ERR(handle, "out of memory, could not set name");
    111 		return STATUS_ERR;
    112 	}
    113 	free(user->name);
    114 	user->name = tmp_name;
    115 	return STATUS_SUCCESS;
    116 }
    117 
    118 hidden_def(sepol_user_set_name)
    119 
    120 /* MLS */
    121 const char *sepol_user_get_mlslevel(const sepol_user_t * user)
    122 {
    123 
    124 	return user->mls_level;
    125 }
    126 
    127 hidden_def(sepol_user_get_mlslevel)
    128 
    129 int sepol_user_set_mlslevel(sepol_handle_t * handle,
    130 			    sepol_user_t * user, const char *mls_level)
    131 {
    132 
    133 	char *tmp_mls_level = strdup(mls_level);
    134 	if (!tmp_mls_level) {
    135 		ERR(handle, "out of memory, "
    136 		    "could not set MLS default level");
    137 		return STATUS_ERR;
    138 	}
    139 	free(user->mls_level);
    140 	user->mls_level = tmp_mls_level;
    141 	return STATUS_SUCCESS;
    142 }
    143 
    144 hidden_def(sepol_user_set_mlslevel)
    145 
    146 const char *sepol_user_get_mlsrange(const sepol_user_t * user)
    147 {
    148 
    149 	return user->mls_range;
    150 }
    151 
    152 hidden_def(sepol_user_get_mlsrange)
    153 
    154 int sepol_user_set_mlsrange(sepol_handle_t * handle,
    155 			    sepol_user_t * user, const char *mls_range)
    156 {
    157 
    158 	char *tmp_mls_range = strdup(mls_range);
    159 	if (!tmp_mls_range) {
    160 		ERR(handle, "out of memory, "
    161 		    "could not set MLS allowed range");
    162 		return STATUS_ERR;
    163 	}
    164 	free(user->mls_range);
    165 	user->mls_range = tmp_mls_range;
    166 	return STATUS_SUCCESS;
    167 }
    168 
    169 hidden_def(sepol_user_set_mlsrange)
    170 
    171 /* Roles */
    172 int sepol_user_get_num_roles(const sepol_user_t * user)
    173 {
    174 
    175 	return user->num_roles;
    176 }
    177 
    178 int sepol_user_add_role(sepol_handle_t * handle,
    179 			sepol_user_t * user, const char *role)
    180 {
    181 
    182 	char *role_cp;
    183 	char **roles_realloc = NULL;
    184 
    185 	if (sepol_user_has_role(user, role))
    186 		return STATUS_SUCCESS;
    187 
    188 	role_cp = strdup(role);
    189 	if (!role_cp)
    190 		goto omem;
    191 
    192 	roles_realloc = realloc(user->roles,
    193 				sizeof(char *) * (user->num_roles + 1));
    194 	if (!roles_realloc)
    195 		goto omem;
    196 
    197 	user->num_roles++;
    198 	user->roles = roles_realloc;
    199 	user->roles[user->num_roles - 1] = role_cp;
    200 
    201 	return STATUS_SUCCESS;
    202 
    203       omem:
    204 	ERR(handle, "out of memory, could not add role %s", role);
    205 	free(role_cp);
    206 	free(roles_realloc);
    207 	return STATUS_ERR;
    208 }
    209 
    210 hidden_def(sepol_user_add_role)
    211 
    212 int sepol_user_has_role(const sepol_user_t * user, const char *role)
    213 {
    214 
    215 	unsigned int i;
    216 
    217 	for (i = 0; i < user->num_roles; i++)
    218 		if (!strcmp(user->roles[i], role))
    219 			return 1;
    220 	return 0;
    221 }
    222 
    223 hidden_def(sepol_user_has_role)
    224 
    225 int sepol_user_set_roles(sepol_handle_t * handle,
    226 			 sepol_user_t * user,
    227 			 const char **roles_arr, unsigned int num_roles)
    228 {
    229 
    230 	unsigned int i;
    231 	char **tmp_roles = NULL;
    232 
    233 	if (num_roles > 0) {
    234 
    235 		/* First, make a copy */
    236 		tmp_roles = (char **)calloc(1, sizeof(char *) * num_roles);
    237 		if (!tmp_roles)
    238 			goto omem;
    239 
    240 		for (i = 0; i < num_roles; i++) {
    241 			tmp_roles[i] = strdup(roles_arr[i]);
    242 			if (!tmp_roles[i])
    243 				goto omem;
    244 		}
    245 	}
    246 
    247 	/* Apply other changes */
    248 	for (i = 0; i < user->num_roles; i++)
    249 		free(user->roles[i]);
    250 	free(user->roles);
    251 	user->roles = tmp_roles;
    252 	user->num_roles = num_roles;
    253 	return STATUS_SUCCESS;
    254 
    255       omem:
    256 	ERR(handle, "out of memory, could not allocate roles array for"
    257 	    "user %s", user->name);
    258 
    259 	if (tmp_roles) {
    260 		for (i = 0; i < num_roles; i++) {
    261 			if (!tmp_roles[i])
    262 				break;
    263 			free(tmp_roles[i]);
    264 		}
    265 	}
    266 	free(tmp_roles);
    267 	return STATUS_ERR;
    268 }
    269 
    270 int sepol_user_get_roles(sepol_handle_t * handle,
    271 			 const sepol_user_t * user,
    272 			 const char ***roles_arr, unsigned int *num_roles)
    273 {
    274 
    275 	unsigned int i;
    276 	const char **tmp_roles =
    277 	    (const char **)malloc(sizeof(char *) * user->num_roles);
    278 	if (!tmp_roles)
    279 		goto omem;
    280 
    281 	for (i = 0; i < user->num_roles; i++)
    282 		tmp_roles[i] = user->roles[i];
    283 
    284 	*roles_arr = tmp_roles;
    285 	*num_roles = user->num_roles;
    286 	return STATUS_SUCCESS;
    287 
    288       omem:
    289 	ERR(handle, "out of memory, could not "
    290 	    "allocate roles array for user %s", user->name);
    291 	free(tmp_roles);
    292 	return STATUS_ERR;
    293 }
    294 
    295 hidden_def(sepol_user_get_roles)
    296 
    297 void sepol_user_del_role(sepol_user_t * user, const char *role)
    298 {
    299 
    300 	unsigned int i;
    301 	for (i = 0; i < user->num_roles; i++) {
    302 		if (!strcmp(user->roles[i], role)) {
    303 			free(user->roles[i]);
    304 			user->roles[i] = NULL;
    305 			user->roles[i] = user->roles[user->num_roles - 1];
    306 			user->num_roles--;
    307 		}
    308 	}
    309 }
    310 
    311 /* Create */
    312 int sepol_user_create(sepol_handle_t * handle, sepol_user_t ** user_ptr)
    313 {
    314 
    315 	sepol_user_t *user = (sepol_user_t *) malloc(sizeof(sepol_user_t));
    316 
    317 	if (!user) {
    318 		ERR(handle, "out of memory, "
    319 		    "could not create selinux user record");
    320 		return STATUS_ERR;
    321 	}
    322 
    323 	user->roles = NULL;
    324 	user->num_roles = 0;
    325 	user->name = NULL;
    326 	user->mls_level = NULL;
    327 	user->mls_range = NULL;
    328 
    329 	*user_ptr = user;
    330 	return STATUS_SUCCESS;
    331 }
    332 
    333 hidden_def(sepol_user_create)
    334 
    335 /* Deep copy clone */
    336 int sepol_user_clone(sepol_handle_t * handle,
    337 		     const sepol_user_t * user, sepol_user_t ** user_ptr)
    338 {
    339 
    340 	sepol_user_t *new_user = NULL;
    341 	unsigned int i;
    342 
    343 	if (sepol_user_create(handle, &new_user) < 0)
    344 		goto err;
    345 
    346 	if (sepol_user_set_name(handle, new_user, user->name) < 0)
    347 		goto err;
    348 
    349 	for (i = 0; i < user->num_roles; i++) {
    350 		if (sepol_user_add_role(handle, new_user, user->roles[i]) < 0)
    351 			goto err;
    352 	}
    353 
    354 	if (user->mls_level &&
    355 	    (sepol_user_set_mlslevel(handle, new_user, user->mls_level) < 0))
    356 		goto err;
    357 
    358 	if (user->mls_range &&
    359 	    (sepol_user_set_mlsrange(handle, new_user, user->mls_range) < 0))
    360 		goto err;
    361 
    362 	*user_ptr = new_user;
    363 	return STATUS_SUCCESS;
    364 
    365       err:
    366 	ERR(handle, "could not clone selinux user record");
    367 	sepol_user_free(new_user);
    368 	return STATUS_ERR;
    369 }
    370 
    371 /* Destroy */
    372 void sepol_user_free(sepol_user_t * user)
    373 {
    374 
    375 	unsigned int i;
    376 
    377 	if (!user)
    378 		return;
    379 
    380 	free(user->name);
    381 	for (i = 0; i < user->num_roles; i++)
    382 		free(user->roles[i]);
    383 	free(user->roles);
    384 	free(user->mls_level);
    385 	free(user->mls_range);
    386 	free(user);
    387 }
    388 
    389 hidden_def(sepol_user_free)
    390