1/* Copyright (C) 2005 Red Hat, Inc. */ 2 3/* Object: semanage_user_t (SELinux User/Class) 4 * Object: semanage_user_key_t (SELinux User/Class Key) 5 * Implements: record_t (Database Record) 6 * Implements: record_key_t (Database Record Key) 7 */ 8 9#include <sepol/user_record.h> 10 11typedef sepol_user_key_t semanage_user_key_t; 12#define _SEMANAGE_USER_KEY_DEFINED_ 13 14struct semanage_user; 15typedef struct semanage_user record_t; 16typedef semanage_user_key_t record_key_t; 17#define DBASE_RECORD_DEFINED 18 19#include <stdlib.h> 20#include <string.h> 21#include "user_internal.h" 22#include "handle.h" 23#include "database.h" 24#include "debug.h" 25 26struct semanage_user { 27 char *name; 28 semanage_user_base_t *base; 29 semanage_user_extra_t *extra; 30}; 31 32/* Key */ 33int semanage_user_key_create(semanage_handle_t * handle, 34 const char *name, semanage_user_key_t ** key) 35{ 36 37 return sepol_user_key_create(handle->sepolh, name, key); 38} 39 40hidden_def(semanage_user_key_create) 41 42int semanage_user_key_extract(semanage_handle_t * handle, 43 const semanage_user_t * user, 44 semanage_user_key_t ** key) 45{ 46 47 return semanage_user_base_key_extract(handle, user->base, key); 48} 49 50hidden_def(semanage_user_key_extract) 51 52void semanage_user_key_free(semanage_user_key_t * key) 53{ 54 55 sepol_user_key_free(key); 56} 57 58hidden_def(semanage_user_key_free) 59 60hidden void semanage_user_key_unpack(const semanage_user_key_t * key, 61 const char **name) 62{ 63 64 sepol_user_key_unpack(key, name); 65} 66 67int semanage_user_compare(const semanage_user_t * user, 68 const semanage_user_key_t * key) 69{ 70 71 const char *name; 72 sepol_user_key_unpack(key, &name); 73 return strcmp(user->name, name); 74} 75 76hidden_def(semanage_user_compare) 77 78int semanage_user_compare2(const semanage_user_t * user, 79 const semanage_user_t * user2) 80{ 81 82 return strcmp(user->name, user2->name); 83} 84 85hidden_def(semanage_user_compare2) 86 87static int semanage_user_compare2_qsort(const semanage_user_t ** user, 88 const semanage_user_t ** user2) 89{ 90 91 return strcmp((*user)->name, (*user2)->name); 92} 93 94/* Name */ 95const char *semanage_user_get_name(const semanage_user_t * user) 96{ 97 return user->name; 98} 99 100hidden_def(semanage_user_get_name) 101 102int semanage_user_set_name(semanage_handle_t * handle, 103 semanage_user_t * user, const char *name) 104{ 105 106 char *tmp_name = strdup(name); 107 if (!tmp_name) 108 goto omem; 109 110 if (semanage_user_base_set_name(handle, user->base, name) < 0) 111 goto err; 112 113 if (semanage_user_extra_set_name(handle, user->extra, name) < 0) 114 goto err; 115 116 free(user->name); 117 user->name = tmp_name; 118 return STATUS_SUCCESS; 119 120 omem: 121 ERR(handle, "out of memory"); 122 123 err: 124 ERR(handle, "could not set user name to %s", name); 125 free(tmp_name); 126 return STATUS_ERR; 127} 128 129hidden_def(semanage_user_set_name) 130 131/* Labeling prefix */ 132const char *semanage_user_get_prefix(const semanage_user_t * user) 133{ 134 135 return semanage_user_extra_get_prefix(user->extra); 136} 137 138int semanage_user_set_prefix(semanage_handle_t * handle, 139 semanage_user_t * user, const char *name) 140{ 141 142 return semanage_user_extra_set_prefix(handle, user->extra, name); 143} 144 145/* MLS */ 146const char *semanage_user_get_mlslevel(const semanage_user_t * user) 147{ 148 149 return semanage_user_base_get_mlslevel(user->base); 150} 151 152hidden_def(semanage_user_get_mlslevel) 153 154int semanage_user_set_mlslevel(semanage_handle_t * handle, 155 semanage_user_t * user, const char *mls_level) 156{ 157 158 return semanage_user_base_set_mlslevel(handle, user->base, mls_level); 159} 160 161hidden_def(semanage_user_set_mlslevel) 162 163const char *semanage_user_get_mlsrange(const semanage_user_t * user) 164{ 165 166 return semanage_user_base_get_mlsrange(user->base); 167} 168 169hidden_def(semanage_user_get_mlsrange) 170 171int semanage_user_set_mlsrange(semanage_handle_t * handle, 172 semanage_user_t * user, const char *mls_range) 173{ 174 175 return semanage_user_base_set_mlsrange(handle, user->base, mls_range); 176} 177 178hidden_def(semanage_user_set_mlsrange) 179 180/* Role management */ 181int semanage_user_get_num_roles(const semanage_user_t * user) 182{ 183 184 return semanage_user_base_get_num_roles(user->base); 185} 186 187int semanage_user_add_role(semanage_handle_t * handle, 188 semanage_user_t * user, const char *role) 189{ 190 191 return semanage_user_base_add_role(handle, user->base, role); 192} 193 194hidden_def(semanage_user_add_role) 195 196void semanage_user_del_role(semanage_user_t * user, const char *role) 197{ 198 199 semanage_user_base_del_role(user->base, role); 200} 201 202int semanage_user_has_role(const semanage_user_t * user, const char *role) 203{ 204 205 return semanage_user_base_has_role(user->base, role); 206} 207 208int semanage_user_get_roles(semanage_handle_t * handle, 209 const semanage_user_t * user, 210 const char ***roles_arr, unsigned int *num_roles) 211{ 212 213 return semanage_user_base_get_roles(handle, user->base, roles_arr, 214 num_roles); 215} 216 217hidden_def(semanage_user_get_roles) 218 219int semanage_user_set_roles(semanage_handle_t * handle, 220 semanage_user_t * user, 221 const char **roles_arr, unsigned int num_roles) 222{ 223 224 return semanage_user_base_set_roles(handle, user->base, roles_arr, 225 num_roles); 226} 227 228/* Create/Clone/Destroy */ 229int semanage_user_create(semanage_handle_t * handle, 230 semanage_user_t ** user_ptr) 231{ 232 233 semanage_user_t *tmp_user = calloc(1, sizeof(semanage_user_t)); 234 if (!tmp_user) 235 goto omem; 236 237 if (semanage_user_base_create(handle, &tmp_user->base) < 0) 238 goto err; 239 if (semanage_user_extra_create(handle, &tmp_user->extra) < 0) 240 goto err; 241 242 /* Initialize the prefix for migration purposes */ 243 if (semanage_user_extra_set_prefix(handle, tmp_user->extra, "user") < 0) 244 goto err; 245 246 *user_ptr = tmp_user; 247 return STATUS_SUCCESS; 248 249 omem: 250 ERR(handle, "out of memory"); 251 252 err: 253 ERR(handle, "could not create user record"); 254 semanage_user_free(tmp_user); 255 return STATUS_ERR; 256} 257 258hidden_def(semanage_user_create) 259 260int semanage_user_clone(semanage_handle_t * handle, 261 const semanage_user_t * user, 262 semanage_user_t ** user_ptr) 263{ 264 265 semanage_user_t *tmp_user = calloc(1, sizeof(semanage_user_t)); 266 if (!tmp_user) 267 goto omem; 268 269 /* Clone base and extra records */ 270 if (semanage_user_base_clone(handle, user->base, &tmp_user->base) < 0) 271 goto err; 272 if (semanage_user_extra_clone(handle, user->extra, &tmp_user->extra) < 273 0) 274 goto err; 275 276 /* Set the shared name */ 277 if (semanage_user_set_name(handle, tmp_user, user->name) < 0) 278 goto err; 279 280 *user_ptr = tmp_user; 281 return STATUS_SUCCESS; 282 283 omem: 284 ERR(handle, "out of memory"); 285 286 err: 287 ERR(handle, "could not clone user record"); 288 semanage_user_free(tmp_user); 289 return STATUS_ERR; 290} 291 292hidden_def(semanage_user_clone) 293 294void semanage_user_free(semanage_user_t * user) 295{ 296 297 if (!user) 298 return; 299 300 semanage_user_base_free(user->base); 301 semanage_user_extra_free(user->extra); 302 free(user->name); 303 free(user); 304} 305 306hidden_def(semanage_user_free) 307 308/* Join properties */ 309hidden int semanage_user_join(semanage_handle_t * handle, 310 const semanage_user_base_t * record1, 311 const semanage_user_extra_t * record2, 312 semanage_user_t ** result) 313{ 314 315 const char *name; 316 semanage_user_t *tmp_user = calloc(1, sizeof(semanage_user_t)); 317 if (!tmp_user) 318 goto omem; 319 320 /* Set the shared name from one of the records 321 * (at least one is available) */ 322 if (record1 == NULL) 323 name = semanage_user_extra_get_name(record2); 324 else 325 name = semanage_user_base_get_name(record1); 326 327 /* Join base record if it exists, create a blank one otherwise */ 328 if (record1) { 329 if (semanage_user_base_clone(handle, record1, &tmp_user->base) < 330 0) 331 goto err; 332 } else { 333 if (semanage_user_base_create(handle, &tmp_user->base) < 0) 334 goto err; 335 if (semanage_user_base_set_name(handle, tmp_user->base, name) < 336 0) 337 goto err; 338 } 339 340 /* Join extra record if it exists, create a blank one otherwise */ 341 if (record2) { 342 if (semanage_user_extra_clone(handle, record2, &tmp_user->extra) 343 < 0) 344 goto err; 345 } else { 346 if (semanage_user_extra_create(handle, &tmp_user->extra) < 0) 347 goto err; 348 if (semanage_user_extra_set_name(handle, tmp_user->extra, name) 349 < 0) 350 goto err; 351 if (semanage_user_extra_set_prefix 352 (handle, tmp_user->extra, "user") < 0) 353 goto err; 354 } 355 356 if (semanage_user_set_name(handle, tmp_user, name) < 0) 357 goto err; 358 359 *result = tmp_user; 360 return STATUS_SUCCESS; 361 362 omem: 363 ERR(handle, "out of memory"); 364 365 err: 366 ERR(handle, "could not join data records for user %s", 367 semanage_user_base_get_name(record1)); 368 semanage_user_free(tmp_user); 369 return STATUS_ERR; 370} 371 372hidden int semanage_user_split(semanage_handle_t * handle, 373 const semanage_user_t * record, 374 semanage_user_base_t ** split1, 375 semanage_user_extra_t ** split2) 376{ 377 378 semanage_user_base_t *tmp_base_user = NULL; 379 semanage_user_extra_t *tmp_extra_user = NULL; 380 381 if (semanage_user_base_clone(handle, record->base, &tmp_base_user) < 0) 382 goto err; 383 384 if (semanage_user_extra_clone(handle, record->extra, &tmp_extra_user) < 385 0) 386 goto err; 387 388 *split1 = tmp_base_user; 389 *split2 = tmp_extra_user; 390 return STATUS_SUCCESS; 391 392 err: 393 ERR(handle, "could not split data records for user %s", 394 semanage_user_get_name(record)); 395 semanage_user_base_free(tmp_base_user); 396 semanage_user_extra_free(tmp_extra_user); 397 return STATUS_ERR; 398} 399 400/* Record base functions */ 401record_table_t SEMANAGE_USER_RTABLE = { 402 .create = semanage_user_create, 403 .key_extract = semanage_user_key_extract, 404 .key_free = semanage_user_key_free, 405 .clone = semanage_user_clone, 406 .compare = semanage_user_compare, 407 .compare2 = semanage_user_compare2, 408 .compare2_qsort = semanage_user_compare2_qsort, 409 .free = semanage_user_free, 410}; 411