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