1255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h> 2255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stddef.h> 3255e72915d4cbddceb435e13d81601755714e9fSE Android#include <string.h> 4255e72915d4cbddceb435e13d81601755714e9fSE Android 5255e72915d4cbddceb435e13d81601755714e9fSE Android#include "private.h" 6255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h" 7255e72915d4cbddceb435e13d81601755714e9fSE Android#include "handle.h" 8255e72915d4cbddceb435e13d81601755714e9fSE Android 9255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/policydb.h> 10255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/hashtab.h> 11255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/expand.h> 12255e72915d4cbddceb435e13d81601755714e9fSE Android#include "user_internal.h" 13255e72915d4cbddceb435e13d81601755714e9fSE Android#include "mls.h" 14255e72915d4cbddceb435e13d81601755714e9fSE Android 15255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int user_to_record(sepol_handle_t * handle, 16255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t * policydb, 17255e72915d4cbddceb435e13d81601755714e9fSE Android int user_idx, sepol_user_t ** record) 18255e72915d4cbddceb435e13d81601755714e9fSE Android{ 19255e72915d4cbddceb435e13d81601755714e9fSE Android 20255e72915d4cbddceb435e13d81601755714e9fSE Android const char *name = policydb->p_user_val_to_name[user_idx]; 21255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *usrdatum = policydb->user_val_to_struct[user_idx]; 22255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t *roles = &(usrdatum->roles.roles); 23255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *rnode; 24255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned bit; 25255e72915d4cbddceb435e13d81601755714e9fSE Android 26255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_user_t *tmp_record = NULL; 27255e72915d4cbddceb435e13d81601755714e9fSE Android 28255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_user_create(handle, &tmp_record) < 0) 29255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 30255e72915d4cbddceb435e13d81601755714e9fSE Android 31255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_user_set_name(handle, tmp_record, name) < 0) 32255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 33255e72915d4cbddceb435e13d81601755714e9fSE Android 34255e72915d4cbddceb435e13d81601755714e9fSE Android /* Extract roles */ 35255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(roles, rnode, bit) { 36255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(rnode, bit)) { 37255e72915d4cbddceb435e13d81601755714e9fSE Android char *role = policydb->p_role_val_to_name[bit]; 38255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_user_add_role(handle, tmp_record, role) < 0) 39255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 40255e72915d4cbddceb435e13d81601755714e9fSE Android } 41255e72915d4cbddceb435e13d81601755714e9fSE Android } 42255e72915d4cbddceb435e13d81601755714e9fSE Android 43255e72915d4cbddceb435e13d81601755714e9fSE Android /* Extract MLS info */ 44255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb->mls) { 45255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t context; 46255e72915d4cbddceb435e13d81601755714e9fSE Android char *str; 47255e72915d4cbddceb435e13d81601755714e9fSE Android 48255e72915d4cbddceb435e13d81601755714e9fSE Android context_init(&context); 49255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_level_cpy(&context.range.level[0], 50255e72915d4cbddceb435e13d81601755714e9fSE Android &usrdatum->exp_dfltlevel) < 0) { 51255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not copy MLS level"); 52255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&context); 53255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 54255e72915d4cbddceb435e13d81601755714e9fSE Android } 55255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_level_cpy(&context.range.level[1], 56255e72915d4cbddceb435e13d81601755714e9fSE Android &usrdatum->exp_dfltlevel) < 0) { 57255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not copy MLS level"); 58255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&context); 59255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 60255e72915d4cbddceb435e13d81601755714e9fSE Android } 61255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_to_string(handle, policydb, &context, &str) < 0) { 62255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&context); 63255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 64255e72915d4cbddceb435e13d81601755714e9fSE Android } 65255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&context); 66255e72915d4cbddceb435e13d81601755714e9fSE Android 67255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_user_set_mlslevel(handle, tmp_record, str) < 0) { 68255e72915d4cbddceb435e13d81601755714e9fSE Android free(str); 69255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 70255e72915d4cbddceb435e13d81601755714e9fSE Android } 71255e72915d4cbddceb435e13d81601755714e9fSE Android free(str); 72255e72915d4cbddceb435e13d81601755714e9fSE Android 73255e72915d4cbddceb435e13d81601755714e9fSE Android context_init(&context); 74255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_range_cpy(&context.range, &usrdatum->exp_range) < 0) { 75255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not copy MLS range"); 76255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&context); 77255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 78255e72915d4cbddceb435e13d81601755714e9fSE Android } 79255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_to_string(handle, policydb, &context, &str) < 0) { 80255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&context); 81255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 82255e72915d4cbddceb435e13d81601755714e9fSE Android } 83255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&context); 84255e72915d4cbddceb435e13d81601755714e9fSE Android 85255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_user_set_mlsrange(handle, tmp_record, str) < 0) { 86255e72915d4cbddceb435e13d81601755714e9fSE Android free(str); 87255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 88255e72915d4cbddceb435e13d81601755714e9fSE Android } 89255e72915d4cbddceb435e13d81601755714e9fSE Android free(str); 90255e72915d4cbddceb435e13d81601755714e9fSE Android } 91255e72915d4cbddceb435e13d81601755714e9fSE Android 92255e72915d4cbddceb435e13d81601755714e9fSE Android *record = tmp_record; 93255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 94255e72915d4cbddceb435e13d81601755714e9fSE Android 95255e72915d4cbddceb435e13d81601755714e9fSE Android err: 96255e72915d4cbddceb435e13d81601755714e9fSE Android /* FIXME: handle error */ 97255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_user_free(tmp_record); 98255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 99255e72915d4cbddceb435e13d81601755714e9fSE Android} 100255e72915d4cbddceb435e13d81601755714e9fSE Android 101255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_modify(sepol_handle_t * handle, 102255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_policydb_t * p, 103255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_user_key_t * key, const sepol_user_t * user) 104255e72915d4cbddceb435e13d81601755714e9fSE Android{ 105255e72915d4cbddceb435e13d81601755714e9fSE Android 106255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *policydb = &p->p; 107255e72915d4cbddceb435e13d81601755714e9fSE Android 108255e72915d4cbddceb435e13d81601755714e9fSE Android /* For user data */ 109255e72915d4cbddceb435e13d81601755714e9fSE Android const char *cname, *cmls_level, *cmls_range; 110255e72915d4cbddceb435e13d81601755714e9fSE Android char *name = NULL; 111255e72915d4cbddceb435e13d81601755714e9fSE Android 112255e72915d4cbddceb435e13d81601755714e9fSE Android const char **roles = NULL; 113255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int num_roles = 0; 114255e72915d4cbddceb435e13d81601755714e9fSE Android 115255e72915d4cbddceb435e13d81601755714e9fSE Android /* Low-level representation */ 116255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *usrdatum = NULL; 117255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *roldatum; 118255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 119255e72915d4cbddceb435e13d81601755714e9fSE Android 120255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t context; 121255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned bit; 122255e72915d4cbddceb435e13d81601755714e9fSE Android int new = 0; 123255e72915d4cbddceb435e13d81601755714e9fSE Android 124255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *rnode; 125255e72915d4cbddceb435e13d81601755714e9fSE Android 126255e72915d4cbddceb435e13d81601755714e9fSE Android /* First, extract all the data */ 127255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_user_key_unpack(key, &cname); 128255e72915d4cbddceb435e13d81601755714e9fSE Android 129255e72915d4cbddceb435e13d81601755714e9fSE Android cmls_level = sepol_user_get_mlslevel(user); 130255e72915d4cbddceb435e13d81601755714e9fSE Android cmls_range = sepol_user_get_mlsrange(user); 131255e72915d4cbddceb435e13d81601755714e9fSE Android 132255e72915d4cbddceb435e13d81601755714e9fSE Android /* Make sure that worked properly */ 133255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_user_get_roles(handle, user, &roles, &num_roles) < 0) 134255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 135255e72915d4cbddceb435e13d81601755714e9fSE Android 136255e72915d4cbddceb435e13d81601755714e9fSE Android /* Now, see if a user exists */ 137255e72915d4cbddceb435e13d81601755714e9fSE Android usrdatum = hashtab_search(policydb->p_users.table, 138255e72915d4cbddceb435e13d81601755714e9fSE Android (const hashtab_key_t)cname); 139255e72915d4cbddceb435e13d81601755714e9fSE Android 140255e72915d4cbddceb435e13d81601755714e9fSE Android /* If it does, we will modify it */ 141255e72915d4cbddceb435e13d81601755714e9fSE Android if (usrdatum) { 142255e72915d4cbddceb435e13d81601755714e9fSE Android 143255e72915d4cbddceb435e13d81601755714e9fSE Android int value_cp = usrdatum->s.value; 144255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_destroy(usrdatum); 145255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_init(usrdatum); 146255e72915d4cbddceb435e13d81601755714e9fSE Android usrdatum->s.value = value_cp; 147255e72915d4cbddceb435e13d81601755714e9fSE Android 148255e72915d4cbddceb435e13d81601755714e9fSE Android /* Otherwise, create a new one */ 149255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 150255e72915d4cbddceb435e13d81601755714e9fSE Android usrdatum = (user_datum_t *) malloc(sizeof(user_datum_t)); 151255e72915d4cbddceb435e13d81601755714e9fSE Android if (!usrdatum) 152255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 153255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_init(usrdatum); 154255e72915d4cbddceb435e13d81601755714e9fSE Android new = 1; 155255e72915d4cbddceb435e13d81601755714e9fSE Android } 156255e72915d4cbddceb435e13d81601755714e9fSE Android 157255e72915d4cbddceb435e13d81601755714e9fSE Android /* For every role */ 158255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < num_roles; i++) { 159255e72915d4cbddceb435e13d81601755714e9fSE Android 160255e72915d4cbddceb435e13d81601755714e9fSE Android /* Search for the role */ 161255e72915d4cbddceb435e13d81601755714e9fSE Android roldatum = hashtab_search(policydb->p_roles.table, 162255e72915d4cbddceb435e13d81601755714e9fSE Android (const hashtab_key_t)roles[i]); 163255e72915d4cbddceb435e13d81601755714e9fSE Android if (!roldatum) { 164255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "undefined role %s for user %s", 165255e72915d4cbddceb435e13d81601755714e9fSE Android roles[i], cname); 166255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 167255e72915d4cbddceb435e13d81601755714e9fSE Android } 168255e72915d4cbddceb435e13d81601755714e9fSE Android 169255e72915d4cbddceb435e13d81601755714e9fSE Android /* Set the role and every role it dominates */ 170255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&roldatum->dominates, rnode, bit) { 171255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(rnode, bit)) { 172255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit 173255e72915d4cbddceb435e13d81601755714e9fSE Android (&(usrdatum->roles.roles), bit, 1)) 174255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 175255e72915d4cbddceb435e13d81601755714e9fSE Android } 176255e72915d4cbddceb435e13d81601755714e9fSE Android } 177255e72915d4cbddceb435e13d81601755714e9fSE Android } 178255e72915d4cbddceb435e13d81601755714e9fSE Android 179255e72915d4cbddceb435e13d81601755714e9fSE Android /* For MLS systems */ 180255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb->mls) { 181255e72915d4cbddceb435e13d81601755714e9fSE Android 182255e72915d4cbddceb435e13d81601755714e9fSE Android /* MLS level */ 183255e72915d4cbddceb435e13d81601755714e9fSE Android if (cmls_level == NULL) { 184255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "MLS is enabled, but no MLS " 185255e72915d4cbddceb435e13d81601755714e9fSE Android "default level was defined for user %s", cname); 186255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 187255e72915d4cbddceb435e13d81601755714e9fSE Android } 188255e72915d4cbddceb435e13d81601755714e9fSE Android 189255e72915d4cbddceb435e13d81601755714e9fSE Android context_init(&context); 190255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_from_string(handle, policydb, cmls_level, &context) < 0) { 191255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&context); 192255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 193255e72915d4cbddceb435e13d81601755714e9fSE Android } 194255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_level_cpy(&usrdatum->exp_dfltlevel, 195255e72915d4cbddceb435e13d81601755714e9fSE Android &context.range.level[0]) < 0) { 196255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not copy MLS level %s", cmls_level); 197255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&context); 198255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 199255e72915d4cbddceb435e13d81601755714e9fSE Android } 200255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&context); 201255e72915d4cbddceb435e13d81601755714e9fSE Android 202255e72915d4cbddceb435e13d81601755714e9fSE Android /* MLS range */ 203255e72915d4cbddceb435e13d81601755714e9fSE Android if (cmls_range == NULL) { 204255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "MLS is enabled, but no MLS" 205255e72915d4cbddceb435e13d81601755714e9fSE Android "range was defined for user %s", cname); 206255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 207255e72915d4cbddceb435e13d81601755714e9fSE Android } 208255e72915d4cbddceb435e13d81601755714e9fSE Android 209255e72915d4cbddceb435e13d81601755714e9fSE Android context_init(&context); 210255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_from_string(handle, policydb, cmls_range, &context) < 0) { 211255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&context); 212255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 213255e72915d4cbddceb435e13d81601755714e9fSE Android } 214255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_range_cpy(&usrdatum->exp_range, &context.range) < 0) { 215255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not copy MLS range %s", cmls_range); 216255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&context); 217255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 218255e72915d4cbddceb435e13d81601755714e9fSE Android } 219255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&context); 220255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (cmls_level != NULL || cmls_range != NULL) { 221255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "MLS is disabled, but MLS level/range " 222255e72915d4cbddceb435e13d81601755714e9fSE Android "was found for user %s", cname); 223255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 224255e72915d4cbddceb435e13d81601755714e9fSE Android } 225255e72915d4cbddceb435e13d81601755714e9fSE Android 226255e72915d4cbddceb435e13d81601755714e9fSE Android /* If there are no errors, and this is a new user, add the user to policy */ 227255e72915d4cbddceb435e13d81601755714e9fSE Android if (new) { 228255e72915d4cbddceb435e13d81601755714e9fSE Android void *tmp_ptr; 229255e72915d4cbddceb435e13d81601755714e9fSE Android 230255e72915d4cbddceb435e13d81601755714e9fSE Android /* Ensure reverse lookup array has enough space */ 231255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_ptr = realloc(policydb->user_val_to_struct, 232255e72915d4cbddceb435e13d81601755714e9fSE Android (policydb->p_users.nprim + 233255e72915d4cbddceb435e13d81601755714e9fSE Android 1) * sizeof(user_datum_t *)); 234255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tmp_ptr) 235255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 236255e72915d4cbddceb435e13d81601755714e9fSE Android policydb->user_val_to_struct = tmp_ptr; 237255e72915d4cbddceb435e13d81601755714e9fSE Android 238255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_ptr = realloc(policydb->sym_val_to_name[SYM_USERS], 239255e72915d4cbddceb435e13d81601755714e9fSE Android (policydb->p_users.nprim + 240255e72915d4cbddceb435e13d81601755714e9fSE Android 1) * sizeof(char *)); 241255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tmp_ptr) 242255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 243255e72915d4cbddceb435e13d81601755714e9fSE Android policydb->sym_val_to_name[SYM_USERS] = tmp_ptr; 244255e72915d4cbddceb435e13d81601755714e9fSE Android 245255e72915d4cbddceb435e13d81601755714e9fSE Android /* Need to copy the user name */ 246255e72915d4cbddceb435e13d81601755714e9fSE Android name = strdup(cname); 247255e72915d4cbddceb435e13d81601755714e9fSE Android if (!name) 248255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 249255e72915d4cbddceb435e13d81601755714e9fSE Android 250255e72915d4cbddceb435e13d81601755714e9fSE Android /* Store user */ 251255e72915d4cbddceb435e13d81601755714e9fSE Android usrdatum->s.value = ++policydb->p_users.nprim; 252255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_insert(policydb->p_users.table, name, 253255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) usrdatum) < 0) 254255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 255255e72915d4cbddceb435e13d81601755714e9fSE Android 256255e72915d4cbddceb435e13d81601755714e9fSE Android /* Set up reverse entry */ 257255e72915d4cbddceb435e13d81601755714e9fSE Android policydb->p_user_val_to_name[usrdatum->s.value - 1] = name; 258255e72915d4cbddceb435e13d81601755714e9fSE Android policydb->user_val_to_struct[usrdatum->s.value - 1] = usrdatum; 259255e72915d4cbddceb435e13d81601755714e9fSE Android name = NULL; 260255e72915d4cbddceb435e13d81601755714e9fSE Android 261255e72915d4cbddceb435e13d81601755714e9fSE Android /* Expand roles */ 262255e72915d4cbddceb435e13d81601755714e9fSE Android if (role_set_expand(&usrdatum->roles, &usrdatum->cache, 263255e72915d4cbddceb435e13d81601755714e9fSE Android policydb, NULL, NULL)) { 264255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "unable to expand role set"); 265255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 266255e72915d4cbddceb435e13d81601755714e9fSE Android } 267255e72915d4cbddceb435e13d81601755714e9fSE Android } 268255e72915d4cbddceb435e13d81601755714e9fSE Android 269255e72915d4cbddceb435e13d81601755714e9fSE Android free(roles); 270255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 271255e72915d4cbddceb435e13d81601755714e9fSE Android 272255e72915d4cbddceb435e13d81601755714e9fSE Android omem: 273255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "out of memory"); 274255e72915d4cbddceb435e13d81601755714e9fSE Android 275255e72915d4cbddceb435e13d81601755714e9fSE Android err: 276255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not load %s into policy", name); 277255e72915d4cbddceb435e13d81601755714e9fSE Android 278255e72915d4cbddceb435e13d81601755714e9fSE Android free(name); 279255e72915d4cbddceb435e13d81601755714e9fSE Android free(roles); 280255e72915d4cbddceb435e13d81601755714e9fSE Android if (new && usrdatum) { 281255e72915d4cbddceb435e13d81601755714e9fSE Android role_set_destroy(&usrdatum->roles); 282255e72915d4cbddceb435e13d81601755714e9fSE Android free(usrdatum); 283255e72915d4cbddceb435e13d81601755714e9fSE Android } 284255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 285255e72915d4cbddceb435e13d81601755714e9fSE Android} 286255e72915d4cbddceb435e13d81601755714e9fSE Android 287255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_exists(sepol_handle_t * handle __attribute__ ((unused)), 288255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, 289255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_user_key_t * key, int *response) 290255e72915d4cbddceb435e13d81601755714e9fSE Android{ 291255e72915d4cbddceb435e13d81601755714e9fSE Android 292255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 293255e72915d4cbddceb435e13d81601755714e9fSE Android 294255e72915d4cbddceb435e13d81601755714e9fSE Android const char *cname; 295255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_user_key_unpack(key, &cname); 296255e72915d4cbddceb435e13d81601755714e9fSE Android 297255e72915d4cbddceb435e13d81601755714e9fSE Android *response = (hashtab_search(policydb->p_users.table, 298255e72915d4cbddceb435e13d81601755714e9fSE Android (const hashtab_key_t)cname) != NULL); 299255e72915d4cbddceb435e13d81601755714e9fSE Android 300255e72915d4cbddceb435e13d81601755714e9fSE Android handle = NULL; 301255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 302255e72915d4cbddceb435e13d81601755714e9fSE Android} 303255e72915d4cbddceb435e13d81601755714e9fSE Android 304255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_count(sepol_handle_t * handle __attribute__ ((unused)), 305255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, unsigned int *response) 306255e72915d4cbddceb435e13d81601755714e9fSE Android{ 307255e72915d4cbddceb435e13d81601755714e9fSE Android 308255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 309255e72915d4cbddceb435e13d81601755714e9fSE Android *response = policydb->p_users.nprim; 310255e72915d4cbddceb435e13d81601755714e9fSE Android 311255e72915d4cbddceb435e13d81601755714e9fSE Android handle = NULL; 312255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 313255e72915d4cbddceb435e13d81601755714e9fSE Android} 314255e72915d4cbddceb435e13d81601755714e9fSE Android 315255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_query(sepol_handle_t * handle, 316255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, 317255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_user_key_t * key, sepol_user_t ** response) 318255e72915d4cbddceb435e13d81601755714e9fSE Android{ 319255e72915d4cbddceb435e13d81601755714e9fSE Android 320255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 321255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *usrdatum = NULL; 322255e72915d4cbddceb435e13d81601755714e9fSE Android 323255e72915d4cbddceb435e13d81601755714e9fSE Android const char *cname; 324255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_user_key_unpack(key, &cname); 325255e72915d4cbddceb435e13d81601755714e9fSE Android 326255e72915d4cbddceb435e13d81601755714e9fSE Android usrdatum = hashtab_search(policydb->p_users.table, 327255e72915d4cbddceb435e13d81601755714e9fSE Android (const hashtab_key_t)cname); 328255e72915d4cbddceb435e13d81601755714e9fSE Android 329255e72915d4cbddceb435e13d81601755714e9fSE Android if (!usrdatum) { 330255e72915d4cbddceb435e13d81601755714e9fSE Android *response = NULL; 331255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 332255e72915d4cbddceb435e13d81601755714e9fSE Android } 333255e72915d4cbddceb435e13d81601755714e9fSE Android 334255e72915d4cbddceb435e13d81601755714e9fSE Android if (user_to_record(handle, policydb, usrdatum->s.value - 1, response) < 335255e72915d4cbddceb435e13d81601755714e9fSE Android 0) 336255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 337255e72915d4cbddceb435e13d81601755714e9fSE Android 338255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 339255e72915d4cbddceb435e13d81601755714e9fSE Android 340255e72915d4cbddceb435e13d81601755714e9fSE Android err: 341255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not query user %s", cname); 342255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 343255e72915d4cbddceb435e13d81601755714e9fSE Android} 344255e72915d4cbddceb435e13d81601755714e9fSE Android 345255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_user_iterate(sepol_handle_t * handle, 346255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, 347255e72915d4cbddceb435e13d81601755714e9fSE Android int (*fn) (const sepol_user_t * user, 348255e72915d4cbddceb435e13d81601755714e9fSE Android void *fn_arg), void *arg) 349255e72915d4cbddceb435e13d81601755714e9fSE Android{ 350255e72915d4cbddceb435e13d81601755714e9fSE Android 351255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 352255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int nusers = policydb->p_users.nprim; 353255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_user_t *user = NULL; 354255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 355255e72915d4cbddceb435e13d81601755714e9fSE Android 356255e72915d4cbddceb435e13d81601755714e9fSE Android /* For each user */ 357255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < nusers; i++) { 358255e72915d4cbddceb435e13d81601755714e9fSE Android 359255e72915d4cbddceb435e13d81601755714e9fSE Android int status; 360255e72915d4cbddceb435e13d81601755714e9fSE Android 361255e72915d4cbddceb435e13d81601755714e9fSE Android if (user_to_record(handle, policydb, i, &user) < 0) 362255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 363255e72915d4cbddceb435e13d81601755714e9fSE Android 364255e72915d4cbddceb435e13d81601755714e9fSE Android /* Invoke handler */ 365255e72915d4cbddceb435e13d81601755714e9fSE Android status = fn(user, arg); 366255e72915d4cbddceb435e13d81601755714e9fSE Android if (status < 0) 367255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 368255e72915d4cbddceb435e13d81601755714e9fSE Android 369255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_user_free(user); 370255e72915d4cbddceb435e13d81601755714e9fSE Android user = NULL; 371255e72915d4cbddceb435e13d81601755714e9fSE Android 372255e72915d4cbddceb435e13d81601755714e9fSE Android /* Handler requested exit */ 373255e72915d4cbddceb435e13d81601755714e9fSE Android if (status > 0) 374255e72915d4cbddceb435e13d81601755714e9fSE Android break; 375255e72915d4cbddceb435e13d81601755714e9fSE Android } 376255e72915d4cbddceb435e13d81601755714e9fSE Android 377255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 378255e72915d4cbddceb435e13d81601755714e9fSE Android 379255e72915d4cbddceb435e13d81601755714e9fSE Android err: 380255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not iterate over users"); 381255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_user_free(user); 382255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 383255e72915d4cbddceb435e13d81601755714e9fSE Android} 384