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 11 typedef sepol_user_key_t semanage_user_key_t; 12 #define _SEMANAGE_USER_KEY_DEFINED_ 13 14 struct semanage_user; 15 typedef struct semanage_user record_t; 16 typedef 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 26 struct semanage_user { 27 char *name; 28 semanage_user_base_t *base; 29 semanage_user_extra_t *extra; 30 }; 31 32 /* Key */ 33 int 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 40 hidden_def(semanage_user_key_create) 41 42 int 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 50 hidden_def(semanage_user_key_extract) 51 52 void semanage_user_key_free(semanage_user_key_t * key) 53 { 54 55 sepol_user_key_free(key); 56 } 57 58 hidden_def(semanage_user_key_free) 59 60 hidden 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 67 int 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 76 hidden_def(semanage_user_compare) 77 78 int 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 85 hidden_def(semanage_user_compare2) 86 87 static 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 */ 95 const char *semanage_user_get_name(const semanage_user_t * user) 96 { 97 return user->name; 98 } 99 100 hidden_def(semanage_user_get_name) 101 102 int 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 129 hidden_def(semanage_user_set_name) 130 131 /* Labeling prefix */ 132 const char *semanage_user_get_prefix(const semanage_user_t * user) 133 { 134 135 return semanage_user_extra_get_prefix(user->extra); 136 } 137 138 int 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 */ 146 const char *semanage_user_get_mlslevel(const semanage_user_t * user) 147 { 148 149 return semanage_user_base_get_mlslevel(user->base); 150 } 151 152 hidden_def(semanage_user_get_mlslevel) 153 154 int 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 161 hidden_def(semanage_user_set_mlslevel) 162 163 const char *semanage_user_get_mlsrange(const semanage_user_t * user) 164 { 165 166 return semanage_user_base_get_mlsrange(user->base); 167 } 168 169 hidden_def(semanage_user_get_mlsrange) 170 171 int 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 178 hidden_def(semanage_user_set_mlsrange) 179 180 /* Role management */ 181 int semanage_user_get_num_roles(const semanage_user_t * user) 182 { 183 184 return semanage_user_base_get_num_roles(user->base); 185 } 186 187 int 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 194 hidden_def(semanage_user_add_role) 195 196 void semanage_user_del_role(semanage_user_t * user, const char *role) 197 { 198 199 semanage_user_base_del_role(user->base, role); 200 } 201 202 int 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 208 int 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 217 hidden_def(semanage_user_get_roles) 218 219 int 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 */ 229 int 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 258 hidden_def(semanage_user_create) 259 260 int 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 292 hidden_def(semanage_user_clone) 293 294 void 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 306 hidden_def(semanage_user_free) 307 308 /* Join properties */ 309 hidden 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 372 hidden 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 */ 401 record_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