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