iterator.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <config.h>
00029
00030 #include <qpol/iterator.h>
00031 #include <qpol/policy.h>
00032 #include <qpol/mls_query.h>
00033
00034 #include <stdlib.h>
00035 #include <errno.h>
00036 #include <string.h>
00037
00038 #include <sepol/policydb/policydb.h>
00039 #include <sepol/policydb/util.h>
00040 #include <sepol/policydb.h>
00041
00042 #include "qpol_internal.h"
00043 #include "iterator_internal.h"
00044
00045
00046
00047
00048
00049
00050 struct qpol_iterator
00051 {
00052 policydb_t *policy;
00053 void *state;
00054 void *(*get_cur) (const qpol_iterator_t * iter);
00055 int (*next) (qpol_iterator_t * iter);
00056 int (*end) (const qpol_iterator_t * iter);
00057 size_t(*size) (const qpol_iterator_t * iter);
00058 void (*free_fn) (void *x);
00059 };
00060
00061
00062
00063
00064
00065
00066 static uint32_t iterator_get_avtab_size(const avtab_t * avtab)
00067 {
00068 #ifdef SEPOL_DYNAMIC_AVTAB
00069 return avtab->nslot;
00070 #else
00071 return AVTAB_SIZE;
00072 #endif
00073 }
00074
00075 int qpol_iterator_create(const qpol_policy_t * policy, void *state,
00076 void *(*get_cur) (const qpol_iterator_t * iter),
00077 int (*next) (qpol_iterator_t * iter),
00078 int (*end) (const qpol_iterator_t * iter),
00079 size_t(*size) (const qpol_iterator_t * iter), void (*free_fn) (void *x), qpol_iterator_t ** iter)
00080 {
00081 int error = 0;
00082
00083 if (iter != NULL)
00084 *iter = NULL;
00085
00086 if (policy == NULL || state == NULL || iter == NULL || get_cur == NULL || next == NULL || end == NULL || size == NULL) {
00087 ERR(policy, "%s", strerror(EINVAL));
00088 errno = EINVAL;
00089 return STATUS_ERR;
00090 }
00091
00092 *iter = calloc(1, sizeof(struct qpol_iterator));
00093 if (*iter == NULL) {
00094 error = errno;
00095 ERR(policy, "%s", strerror(ENOMEM));
00096 errno = error;
00097 return STATUS_ERR;
00098 }
00099
00100 (*iter)->policy = &policy->p->p;
00101 (*iter)->state = state;
00102 (*iter)->get_cur = get_cur;
00103 (*iter)->next = next;
00104 (*iter)->end = end;
00105 (*iter)->size = size;
00106 (*iter)->free_fn = free_fn;
00107
00108 return STATUS_SUCCESS;
00109 }
00110
00111 void *qpol_iterator_state(const qpol_iterator_t * iter)
00112 {
00113 if (iter == NULL || iter->state == NULL) {
00114 errno = EINVAL;
00115 return NULL;
00116 }
00117
00118 return iter->state;
00119 }
00120
00121 const policydb_t *qpol_iterator_policy(const qpol_iterator_t * iter)
00122 {
00123 if (iter == NULL || iter->policy == NULL) {
00124 errno = EINVAL;
00125 return NULL;
00126 }
00127
00128 return iter->policy;
00129 }
00130
00131 void *hash_state_get_cur(const qpol_iterator_t * iter)
00132 {
00133 hash_state_t *hs = NULL;
00134
00135 if (iter == NULL || iter->state == NULL || hash_state_end(iter)) {
00136 errno = EINVAL;
00137 return NULL;
00138 }
00139
00140 hs = (hash_state_t *) iter->state;
00141
00142 return hs->node->datum;
00143 }
00144
00145 void *hash_state_get_cur_key(const qpol_iterator_t * iter)
00146 {
00147 hash_state_t *hs = NULL;
00148
00149 if (iter == NULL || iter->state == NULL || hash_state_end(iter)) {
00150 errno = EINVAL;
00151 return NULL;
00152 }
00153
00154 hs = (hash_state_t *) iter->state;
00155
00156 return hs->node->key;
00157 }
00158
00159 void *ocon_state_get_cur(const qpol_iterator_t * iter)
00160 {
00161 ocon_state_t *os = NULL;
00162
00163 if (iter == NULL || iter->state == NULL || ocon_state_end(iter)) {
00164 errno = EINVAL;
00165 return NULL;
00166 }
00167
00168 os = (ocon_state_t *) iter->state;
00169
00170 return os->cur;
00171 }
00172
00173 void *avtab_state_get_cur(const qpol_iterator_t * iter)
00174 {
00175 avtab_state_t *state;
00176
00177 if (iter == NULL || iter->state == NULL || avtab_state_end(iter)) {
00178 errno = EINVAL;
00179 return NULL;
00180 }
00181 state = (avtab_state_t *) iter->state;
00182 return state->node;
00183 }
00184
00185 int hash_state_next(qpol_iterator_t * iter)
00186 {
00187 hash_state_t *hs = NULL;
00188
00189 if (iter == NULL || iter->state == NULL) {
00190 errno = EINVAL;
00191 return STATUS_ERR;
00192 }
00193
00194 hs = (hash_state_t *) iter->state;
00195
00196 if (hs->table == NULL || *(hs->table) == NULL || hs->bucket >= (*(hs->table))->size) {
00197 errno = ERANGE;
00198 return STATUS_ERR;
00199 }
00200
00201 if (hs->node != NULL && hs->node->next != NULL) {
00202 hs->node = hs->node->next;
00203 } else {
00204 do {
00205 hs->bucket++;
00206 if (hs->bucket < (*(hs->table))->size) {
00207 hs->node = (*(hs->table))->htable[hs->bucket];
00208 } else {
00209 hs->node = NULL;
00210 }
00211 } while (hs->bucket < (*(hs->table))->size && hs->node == NULL);
00212 }
00213
00214 return STATUS_SUCCESS;
00215 }
00216
00217 int ebitmap_state_next(qpol_iterator_t * iter)
00218 {
00219 ebitmap_state_t *es = NULL;
00220
00221 if (iter == NULL || iter->state == NULL) {
00222 errno = EINVAL;
00223 return STATUS_ERR;
00224 }
00225
00226 es = (ebitmap_state_t *) iter->state;
00227
00228 if (es->cur >= es->bmap->highbit) {
00229 errno = ERANGE;
00230 return STATUS_ERR;
00231 }
00232
00233 do {
00234 es->cur++;
00235 } while (es->cur < es->bmap->highbit && !ebitmap_get_bit(es->bmap, es->cur));
00236
00237 return STATUS_SUCCESS;
00238 }
00239
00240 int ocon_state_next(qpol_iterator_t * iter)
00241 {
00242 ocon_state_t *os = NULL;
00243
00244 if (iter == NULL || iter->state == NULL) {
00245 errno = EINVAL;
00246 return STATUS_ERR;
00247 }
00248
00249 os = (ocon_state_t *) iter->state;
00250
00251 if (os->cur == NULL) {
00252 errno = ERANGE;
00253 return STATUS_ERR;
00254 }
00255
00256 os->cur = os->cur->next;
00257
00258 return STATUS_SUCCESS;
00259 }
00260
00261 int avtab_state_next(qpol_iterator_t * iter)
00262 {
00263 avtab_t *avtab;
00264 avtab_state_t *state;
00265
00266 if (iter == NULL || iter->state == NULL) {
00267 errno = EINVAL;
00268 return STATUS_ERR;
00269 }
00270
00271 state = iter->state;
00272 avtab = (state->which == QPOL_AVTAB_STATE_AV ? state->ucond_tab : state->cond_tab);
00273
00274 if ((!avtab->htable || state->bucket >= iterator_get_avtab_size(avtab)) && state->which == QPOL_AVTAB_STATE_COND) {
00275 errno = ERANGE;
00276 return STATUS_ERR;
00277 }
00278
00279 do {
00280 if (state->node != NULL && state->node->next != NULL) {
00281 state->node = state->node->next;
00282 } else {
00283
00284 do {
00285 state->bucket++;
00286 if (!avtab->htable || state->bucket >= iterator_get_avtab_size(avtab)) {
00287 if (state->which == QPOL_AVTAB_STATE_AV) {
00288 state->bucket = 0;
00289 avtab = state->cond_tab;
00290 state->which = QPOL_AVTAB_STATE_COND;
00291 } else {
00292 state->node = NULL;
00293 break;
00294 }
00295 }
00296 if (avtab->htable && avtab->htable[state->bucket] != NULL) {
00297 state->node = avtab->htable[state->bucket];
00298 break;
00299 }
00300 } while (avtab->htable && state->bucket < iterator_get_avtab_size(avtab));
00301 }
00302 } while (avtab->htable && state->bucket < iterator_get_avtab_size(avtab) &&
00303 state->node ? !(state->rule_type_mask & state->node->key.specified) : 0);
00304
00305 return STATUS_SUCCESS;
00306 }
00307
00308 int hash_state_end(const qpol_iterator_t * iter)
00309 {
00310 hash_state_t *hs = NULL;
00311
00312 if (iter == NULL || iter->state == NULL) {
00313 errno = EINVAL;
00314 return STATUS_ERR;
00315 }
00316
00317 hs = (hash_state_t *) iter->state;
00318
00319 if (hs->table == NULL || *(hs->table) == NULL || (*(hs->table))->nel == 0 || hs->bucket >= (*(hs->table))->size)
00320 return 1;
00321
00322 return 0;
00323 }
00324
00325 int ebitmap_state_end(const qpol_iterator_t * iter)
00326 {
00327 ebitmap_state_t *es = NULL;
00328
00329 if (iter == NULL || iter->state == NULL) {
00330 errno = EINVAL;
00331 return STATUS_ERR;
00332 }
00333
00334 es = (ebitmap_state_t *) iter->state;
00335
00336 if (es->cur >= es->bmap->highbit)
00337 return 1;
00338
00339 return 0;
00340 }
00341
00342 int ocon_state_end(const qpol_iterator_t * iter)
00343 {
00344 ocon_state_t *os = NULL;
00345
00346 if (iter == NULL || iter->state == NULL) {
00347 errno = EINVAL;
00348 return STATUS_ERR;
00349 }
00350
00351 os = (ocon_state_t *) iter->state;
00352
00353 if (os->cur == NULL)
00354 return 1;
00355
00356 return 0;
00357 }
00358
00359 int avtab_state_end(const qpol_iterator_t * iter)
00360 {
00361 avtab_state_t *state;
00362 avtab_t *avtab;
00363
00364 if (iter == NULL || iter->state == NULL) {
00365 errno = EINVAL;
00366 return STATUS_ERR;
00367 }
00368 state = iter->state;
00369 avtab = (state->which == QPOL_AVTAB_STATE_AV ? state->ucond_tab : state->cond_tab);
00370 if ((!avtab->htable || state->bucket >= iterator_get_avtab_size(avtab)) && state->which == QPOL_AVTAB_STATE_COND)
00371 return 1;
00372 return 0;
00373 }
00374
00375 size_t hash_state_size(const qpol_iterator_t * iter)
00376 {
00377 hash_state_t *hs = NULL;
00378
00379 if (iter == NULL || iter->state == NULL) {
00380 errno = EINVAL;
00381 return 0;
00382 }
00383
00384 hs = (hash_state_t *) iter->state;
00385
00386 return (*(hs->table))->nel;
00387 }
00388
00389 size_t ebitmap_state_size(const qpol_iterator_t * iter)
00390 {
00391 ebitmap_state_t *es = NULL;
00392 size_t count = 0, bit = 0;
00393 ebitmap_node_t *node = NULL;
00394
00395 if (iter == NULL || iter->state == NULL) {
00396 errno = EINVAL;
00397 return 0;
00398 }
00399
00400 es = (ebitmap_state_t *) iter->state;
00401
00402 ebitmap_for_each_bit(es->bmap, node, bit) {
00403 count += ebitmap_get_bit(es->bmap, bit);
00404 }
00405
00406 return count;
00407 }
00408
00409 size_t ocon_state_size(const qpol_iterator_t * iter)
00410 {
00411 ocon_state_t *os = NULL;
00412 size_t count = 0;
00413 ocontext_t *ocon = NULL;
00414
00415 if (iter == NULL || iter->state == NULL) {
00416 errno = EINVAL;
00417 return 0;
00418 }
00419
00420 os = (ocon_state_t *) iter->state;
00421
00422 for (ocon = os->head; ocon; ocon = ocon->next)
00423 count++;
00424
00425 return count;
00426 }
00427
00428 size_t avtab_state_size(const qpol_iterator_t * iter)
00429 {
00430 avtab_state_t *state;
00431 avtab_t *avtab;
00432 size_t count = 0;
00433 avtab_ptr_t node = NULL;
00434 uint32_t bucket = 0;
00435
00436 if (iter == NULL || iter->state == NULL || iter->policy == NULL) {
00437 errno = EINVAL;
00438 return STATUS_ERR;
00439 }
00440
00441 state = iter->state;
00442 avtab = state->ucond_tab;
00443
00444 for (bucket = 0; avtab->htable && bucket < iterator_get_avtab_size(avtab); bucket++) {
00445 for (node = avtab->htable[bucket]; node; node = node->next) {
00446 if (node->key.specified & state->rule_type_mask)
00447 count++;
00448 }
00449 }
00450
00451 avtab = state->cond_tab;
00452
00453 for (bucket = 0; avtab->htable && bucket < iterator_get_avtab_size(avtab); bucket++) {
00454 for (node = avtab->htable[bucket]; node; node = node->next) {
00455 if (node->key.specified & state->rule_type_mask)
00456 count++;
00457 }
00458 }
00459
00460 return count;
00461 }
00462
00463 void qpol_iterator_destroy(qpol_iterator_t ** iter)
00464 {
00465 if (iter == NULL || *iter == NULL)
00466 return;
00467
00468 if ((*iter)->free_fn)
00469 (*iter)->free_fn((*iter)->state);
00470
00471 free(*iter);
00472 *iter = NULL;
00473 }
00474
00475 int qpol_iterator_get_item(const qpol_iterator_t * iter, void **item)
00476 {
00477 if (item != NULL)
00478 *item = NULL;
00479
00480 if (iter == NULL || iter->get_cur == NULL || item == NULL) {
00481 errno = EINVAL;
00482 return STATUS_ERR;
00483 }
00484
00485 *item = iter->get_cur(iter);
00486 if (*item == NULL)
00487 return STATUS_ERR;
00488
00489 return STATUS_SUCCESS;
00490 }
00491
00492 int qpol_iterator_next(qpol_iterator_t * iter)
00493 {
00494 if (iter == NULL || iter->next == NULL) {
00495 errno = EINVAL;
00496 return STATUS_ERR;
00497 }
00498
00499 return iter->next(iter);
00500 }
00501
00502 int qpol_iterator_end(const qpol_iterator_t * iter)
00503 {
00504 if (iter == NULL || iter->end == NULL) {
00505 errno = EINVAL;
00506 return STATUS_ERR;
00507 }
00508
00509 return iter->end(iter);
00510 }
00511
00512 int qpol_iterator_get_size(const qpol_iterator_t * iter, size_t * size)
00513 {
00514 if (size != NULL)
00515 *size = 0;
00516
00517 if (iter == NULL || size == NULL || iter->size == NULL) {
00518 errno = EINVAL;
00519 return STATUS_ERR;
00520 }
00521
00522 *size = iter->size(iter);
00523
00524 return STATUS_SUCCESS;
00525 }
00526
00527 void *ebitmap_state_get_cur_type(const qpol_iterator_t * iter)
00528 {
00529 ebitmap_state_t *es = NULL;
00530 const policydb_t *db = NULL;
00531
00532 if (iter == NULL) {
00533 errno = EINVAL;
00534 return NULL;
00535 }
00536 es = qpol_iterator_state(iter);
00537 if (es == NULL) {
00538 errno = EINVAL;
00539 return NULL;
00540 }
00541 db = qpol_iterator_policy(iter);
00542 if (db == NULL) {
00543 errno = EINVAL;
00544 return NULL;
00545 }
00546
00547 return db->type_val_to_struct[es->cur];
00548 }
00549
00550 void *ebitmap_state_get_cur_role(const qpol_iterator_t * iter)
00551 {
00552 ebitmap_state_t *es = NULL;
00553 const policydb_t *db = NULL;
00554
00555 if (iter == NULL) {
00556 errno = EINVAL;
00557 return NULL;
00558 }
00559 es = qpol_iterator_state(iter);
00560 if (es == NULL) {
00561 errno = EINVAL;
00562 return NULL;
00563 }
00564 db = qpol_iterator_policy(iter);
00565 if (db == NULL) {
00566 errno = EINVAL;
00567 return NULL;
00568 }
00569
00570 return db->role_val_to_struct[es->cur];
00571 }
00572
00573 void *ebitmap_state_get_cur_cat(const qpol_iterator_t * iter)
00574 {
00575 ebitmap_state_t *es = NULL;
00576 const policydb_t *db = NULL;
00577 const qpol_cat_t *cat = NULL;
00578 sepol_policydb_t sp;
00579 qpol_policy_t qp;
00580
00581 if (iter == NULL) {
00582 errno = EINVAL;
00583 return NULL;
00584 }
00585 es = qpol_iterator_state(iter);
00586 if (es == NULL) {
00587 errno = EINVAL;
00588 return NULL;
00589 }
00590 db = qpol_iterator_policy(iter);
00591 if (db == NULL) {
00592 errno = EINVAL;
00593 return NULL;
00594 }
00595
00596
00597 sp.p = *db;
00598 qp.p = &sp;
00599 qp.fn = NULL;
00600
00601 qpol_policy_get_cat_by_name(&qp, db->p_cat_val_to_name[es->cur], &cat);
00602
00603
00604
00605
00606 return (void *)cat;
00607 }
00608
00609 void ebitmap_state_destroy(void *es)
00610 {
00611 ebitmap_state_t *ies = (ebitmap_state_t *) es;
00612
00613 if (!es)
00614 return;
00615
00616 ebitmap_destroy(ies->bmap);
00617 free(ies->bmap);
00618 free(ies);
00619 }
00620
00621 int perm_state_end(const qpol_iterator_t * iter)
00622 {
00623 perm_state_t *ps = NULL;
00624 const policydb_t *db = NULL;
00625 unsigned int perm_max = 0;
00626
00627 if (iter == NULL || (ps = qpol_iterator_state(iter)) == NULL || (db = qpol_iterator_policy(iter)) == NULL) {
00628 errno = EINVAL;
00629 return STATUS_ERR;
00630 }
00631
00632
00633
00634 perm_max = db->class_val_to_struct[ps->obj_class_val - 1]->permissions.nprim;
00635 if (perm_max > 32) {
00636 errno = EDOM;
00637 return STATUS_ERR;
00638 }
00639
00640 if (!(ps->perm_set) || ps->cur >= perm_max)
00641 return 1;
00642
00643 return 0;
00644 }
00645
00646 void *perm_state_get_cur(const qpol_iterator_t * iter)
00647 {
00648 const policydb_t *db = NULL;
00649 class_datum_t *obj_class = NULL;
00650 common_datum_t *comm = NULL;
00651 perm_state_t *ps = NULL;
00652 unsigned int perm_max = 0;
00653 char *tmp = NULL;
00654
00655 if (iter == NULL || (db = qpol_iterator_policy(iter)) == NULL ||
00656 (ps = (perm_state_t *) qpol_iterator_state(iter)) == NULL || perm_state_end(iter)) {
00657 errno = EINVAL;
00658 return NULL;
00659 }
00660
00661 obj_class = db->class_val_to_struct[ps->obj_class_val - 1];
00662 comm = obj_class->comdatum;
00663
00664
00665
00666 perm_max = obj_class->permissions.nprim;
00667 if (perm_max > 32) {
00668 errno = EDOM;
00669 return NULL;
00670 }
00671 if (ps->cur >= perm_max) {
00672 errno = ERANGE;
00673 return NULL;
00674 }
00675 if (!(ps->perm_set & 1 << (ps->cur))) {
00676 errno = EINVAL;
00677 return NULL;
00678 }
00679
00680
00681 tmp = sepol_av_to_string((policydb_t *) db, ps->obj_class_val, (sepol_access_vector_t) 1 << (ps->cur));
00682 if (tmp) {
00683 tmp++;
00684 return strdup(tmp);
00685 } else {
00686 errno = EINVAL;
00687 return NULL;
00688 }
00689 }
00690
00691 int perm_state_next(qpol_iterator_t * iter)
00692 {
00693 perm_state_t *ps = NULL;
00694 const policydb_t *db = NULL;
00695 unsigned int perm_max = 0;
00696
00697 if (iter == NULL || (ps = qpol_iterator_state(iter)) == NULL ||
00698 (db = qpol_iterator_policy(iter)) == NULL || perm_state_end(iter)) {
00699 errno = EINVAL;
00700 return STATUS_ERR;
00701 }
00702
00703
00704
00705 perm_max = db->class_val_to_struct[ps->obj_class_val - 1]->permissions.nprim;
00706 if (perm_max > 32) {
00707 errno = EDOM;
00708 return STATUS_ERR;
00709 }
00710
00711 if (ps->cur >= perm_max) {
00712 errno = ERANGE;
00713 return STATUS_ERR;
00714 }
00715
00716 do {
00717 ps->cur++;
00718 } while (ps->cur < perm_max && !(ps->perm_set & 1 << (ps->cur)));
00719
00720 return STATUS_SUCCESS;
00721 }
00722
00723 size_t perm_state_size(const qpol_iterator_t * iter)
00724 {
00725 perm_state_t *ps = NULL;
00726 const policydb_t *db = NULL;
00727 unsigned int perm_max = 0;
00728 size_t i, count = 0;
00729
00730 if (iter == NULL || (ps = qpol_iterator_state(iter)) == NULL ||
00731 (db = qpol_iterator_policy(iter)) == NULL || perm_state_end(iter)) {
00732 errno = EINVAL;
00733 return 0;
00734 }
00735
00736
00737
00738 perm_max = db->class_val_to_struct[ps->obj_class_val - 1]->permissions.nprim;
00739 if (perm_max > 32) {
00740 errno = EDOM;
00741 return 0;
00742 }
00743
00744 for (i = 0; i < perm_max; i++) {
00745 if (ps->perm_set & 1 << i)
00746 count++;
00747 }
00748
00749 return count;
00750 }