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 #include <qpol/policy.h>
00028 #include <qpol/cond_query.h>
00029 #include <qpol/bool_query.h>
00030 #include <qpol/avrule_query.h>
00031 #include <qpol/terule_query.h>
00032 #include <qpol/iterator.h>
00033 #include "iterator_internal.h"
00034 #include "qpol_internal.h"
00035
00036 #include <sepol/policydb/conditional.h>
00037
00038 #include <stdlib.h>
00039 #include <errno.h>
00040
00041 typedef struct cond_state
00042 {
00043 cond_node_t *head;
00044 cond_node_t *cur;
00045 } cond_state_t;
00046
00047 static int cond_state_end(const qpol_iterator_t * iter)
00048 {
00049 cond_state_t *cs = NULL;
00050
00051 if (!iter || !(cs = (cond_state_t *) qpol_iterator_state(iter))) {
00052 errno = EINVAL;
00053 return STATUS_ERR;
00054 }
00055
00056 return cs->cur ? 0 : 1;
00057 }
00058
00059 static void *cond_state_get_cur(const qpol_iterator_t * iter)
00060 {
00061 cond_state_t *cs = NULL;
00062
00063 if (!iter || !(cs = (cond_state_t *) qpol_iterator_state(iter)) || qpol_iterator_end(iter)) {
00064 errno = EINVAL;
00065 return NULL;
00066 }
00067
00068 return cs->cur;
00069 }
00070
00071 static int cond_state_next(qpol_iterator_t * iter)
00072 {
00073 cond_state_t *cs = NULL;
00074
00075 if (!iter || !(cs = (cond_state_t *) qpol_iterator_state(iter))) {
00076 errno = EINVAL;
00077 return STATUS_ERR;
00078 }
00079
00080 if (qpol_iterator_end(iter)) {
00081 errno = ERANGE;
00082 return STATUS_ERR;
00083 }
00084
00085 cs->cur = cs->cur->next;
00086
00087 return STATUS_SUCCESS;
00088 }
00089
00090 static size_t cond_state_size(const qpol_iterator_t * iter)
00091 {
00092 cond_state_t *cs = NULL;
00093 cond_node_t *tmp = NULL;
00094 size_t count = 0;
00095
00096 if (!iter || !(cs = (cond_state_t *) qpol_iterator_state(iter))) {
00097 errno = EINVAL;
00098 return 0;
00099 }
00100
00101 for (tmp = cs->head; tmp; tmp = tmp->next)
00102 count++;
00103
00104 return count;
00105 }
00106
00107 int qpol_policy_get_cond_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter)
00108 {
00109 int error = 0;
00110 cond_state_t *cs = NULL;
00111 policydb_t *db = NULL;
00112
00113 if (iter)
00114 *iter = NULL;
00115
00116 if (!policy || !iter) {
00117 ERR(policy, "%s", strerror(EINVAL));
00118 errno = EINVAL;
00119 return STATUS_ERR;
00120 }
00121
00122 if (!qpol_policy_has_capability(policy, QPOL_CAP_RULES_LOADED)) {
00123 ERR(policy, "%s", "Cannot get conditionals: Rules not loaded");
00124 errno = ENOTSUP;
00125 return STATUS_ERR;
00126 }
00127
00128 db = &policy->p->p;
00129
00130 if (!(cs = calloc(1, sizeof(cond_state_t)))) {
00131 error = errno;
00132 ERR(policy, "%s", strerror(error));
00133 goto err;
00134 }
00135 cs->head = cs->cur = db->cond_list;
00136
00137 if (qpol_iterator_create(policy, (void *)cs,
00138 cond_state_get_cur, cond_state_next, cond_state_end, cond_state_size, free, iter)) {
00139 error = errno;
00140 goto err;
00141 }
00142
00143 return STATUS_SUCCESS;
00144
00145 err:
00146 free(cs);
00147 errno = error;
00148 return STATUS_ERR;
00149 }
00150
00151 typedef struct cond_expr_state
00152 {
00153 cond_expr_t *head;
00154 cond_expr_t *cur;
00155 } cond_expr_state_t;
00156
00157 static int cond_expr_state_end(const qpol_iterator_t * iter)
00158 {
00159 cond_expr_state_t *ces = NULL;
00160
00161 if (!iter || !(ces = (cond_expr_state_t *) qpol_iterator_state(iter))) {
00162 errno = EINVAL;
00163 return STATUS_ERR;
00164 }
00165
00166 return ces->cur ? 0 : 1;
00167 }
00168
00169 static void *cond_expr_state_get_cur(const qpol_iterator_t * iter)
00170 {
00171 cond_expr_state_t *ces = NULL;
00172
00173 if (!iter || !(ces = (cond_expr_state_t *) qpol_iterator_state(iter)) || qpol_iterator_end(iter)) {
00174 errno = EINVAL;
00175 return NULL;
00176 }
00177
00178 return ces->cur;
00179 }
00180
00181 static int cond_expr_state_next(qpol_iterator_t * iter)
00182 {
00183 cond_expr_state_t *ces = NULL;
00184
00185 if (!iter || !(ces = (cond_expr_state_t *) qpol_iterator_state(iter))) {
00186 errno = EINVAL;
00187 return STATUS_ERR;
00188 }
00189
00190 if (qpol_iterator_end(iter)) {
00191 errno = ERANGE;
00192 return STATUS_ERR;
00193 }
00194
00195 ces->cur = ces->cur->next;
00196
00197 return STATUS_SUCCESS;
00198 }
00199
00200 static size_t cond_expr_state_size(const qpol_iterator_t * iter)
00201 {
00202 cond_expr_state_t *ces = NULL;
00203 cond_expr_t *tmp = NULL;
00204 size_t count = 0;
00205
00206 if (!iter || !(ces = (cond_expr_state_t *) qpol_iterator_state(iter))) {
00207 errno = EINVAL;
00208 return 0;
00209 }
00210
00211 for (tmp = ces->head; tmp; tmp = tmp->next)
00212 count++;
00213
00214 return count;
00215 }
00216
00217 int qpol_cond_get_expr_node_iter(const qpol_policy_t * policy, const qpol_cond_t * cond, qpol_iterator_t ** iter)
00218 {
00219 int error = 0;
00220 cond_expr_state_t *ces = NULL;
00221 cond_node_t *internal_cond = NULL;
00222 policydb_t *db = NULL;
00223
00224 if (iter)
00225 *iter = NULL;
00226
00227 if (!policy || !cond || !iter) {
00228 ERR(policy, "%s", strerror(EINVAL));
00229 errno = EINVAL;
00230 return STATUS_ERR;
00231 }
00232
00233 db = &policy->p->p;
00234 internal_cond = (cond_node_t *) cond;
00235
00236 if (!(ces = calloc(1, sizeof(cond_expr_state_t)))) {
00237 error = errno;
00238 ERR(policy, "%s", strerror(error));
00239 goto err;
00240 }
00241 ces->head = ces->cur = internal_cond->expr;
00242
00243 if (qpol_iterator_create(policy, (void *)ces,
00244 cond_expr_state_get_cur, cond_expr_state_next, cond_expr_state_end,
00245 cond_expr_state_size, free, iter)) {
00246 error = errno;
00247 goto err;
00248 }
00249
00250 return STATUS_SUCCESS;
00251
00252 err:
00253 free(ces);
00254 errno = error;
00255 return STATUS_ERR;
00256 }
00257
00258 typedef struct cond_rule_state
00259 {
00260 cond_av_list_t *head;
00261 cond_av_list_t *cur;
00262 uint32_t rule_type_mask;
00263 } cond_rule_state_t;
00264
00265 static int cond_rule_state_end(const qpol_iterator_t * iter)
00266 {
00267 cond_rule_state_t *crs = NULL;
00268
00269 if (!iter || !(crs = (cond_rule_state_t *) qpol_iterator_state(iter))) {
00270 errno = EINVAL;
00271 return STATUS_ERR;
00272 }
00273
00274 return crs->cur ? 0 : 1;
00275 }
00276
00277 static void *cond_rule_state_get_cur(const qpol_iterator_t * iter)
00278 {
00279 cond_rule_state_t *crs = NULL;
00280
00281 if (!iter || !(crs = (cond_rule_state_t *) qpol_iterator_state(iter)) || qpol_iterator_end(iter)) {
00282 errno = EINVAL;
00283 return NULL;
00284 }
00285
00286 return crs->cur->node;
00287 }
00288
00289 static int cond_rule_state_next(qpol_iterator_t * iter)
00290 {
00291 cond_rule_state_t *crs = NULL;
00292
00293 if (!iter || !(crs = (cond_rule_state_t *) qpol_iterator_state(iter))) {
00294 errno = EINVAL;
00295 return STATUS_ERR;
00296 }
00297
00298 if (qpol_iterator_end(iter)) {
00299 errno = ERANGE;
00300 return STATUS_ERR;
00301 }
00302
00303 do {
00304 crs->cur = crs->cur->next;
00305 } while (crs->cur && !(crs->cur->node->key.specified & crs->rule_type_mask));
00306
00307 return STATUS_SUCCESS;
00308 }
00309
00310 static size_t cond_rule_state_size(const qpol_iterator_t * iter)
00311 {
00312 cond_rule_state_t *crs = NULL;
00313 cond_av_list_t *tmp = NULL;
00314 size_t count = 0;
00315
00316 if (!iter || !(crs = (cond_rule_state_t *) qpol_iterator_state(iter))) {
00317 errno = EINVAL;
00318 return 0;
00319 }
00320
00321 for (tmp = crs->head; tmp; tmp = tmp->next) {
00322 if (tmp->node->key.specified & crs->rule_type_mask)
00323 count++;
00324 }
00325
00326 return count;
00327 }
00328
00329 int qpol_cond_get_av_true_iter(const qpol_policy_t * policy, const qpol_cond_t * cond, uint32_t rule_type_mask,
00330 qpol_iterator_t ** iter)
00331 {
00332 int error = 0;
00333 cond_rule_state_t *crs = NULL;
00334 cond_node_t *internal_cond = NULL;
00335 policydb_t *db = NULL;
00336
00337 if (iter)
00338 *iter = NULL;
00339
00340 if (!policy || !cond || !iter) {
00341 ERR(policy, "%s", strerror(EINVAL));
00342 errno = EINVAL;
00343 return STATUS_ERR;
00344 }
00345
00346 if (rule_type_mask & ~(QPOL_RULE_ALLOW | QPOL_RULE_NEVERALLOW | QPOL_RULE_AUDITALLOW | QPOL_RULE_DONTAUDIT)) {
00347 ERR(policy, "%s", strerror(EINVAL));
00348 errno = EINVAL;
00349 return STATUS_ERR;
00350 }
00351
00352 db = &policy->p->p;
00353 internal_cond = (cond_node_t *) cond;
00354
00355 if (!(crs = calloc(1, sizeof(cond_rule_state_t)))) {
00356 error = errno;
00357 ERR(policy, "%s", strerror(error));
00358 goto err;
00359 }
00360 crs->head = crs->cur = internal_cond->true_list;
00361 crs->rule_type_mask = rule_type_mask;
00362
00363 if (qpol_iterator_create(policy, (void *)crs,
00364 cond_rule_state_get_cur, cond_rule_state_next, cond_rule_state_end,
00365 cond_rule_state_size, free, iter)) {
00366 error = errno;
00367 goto err;
00368 }
00369
00370 if (crs->cur && !(crs->cur->node->key.specified & crs->rule_type_mask))
00371 qpol_iterator_next(*iter);
00372
00373 return STATUS_SUCCESS;
00374
00375 err:
00376 free(crs);
00377 errno = error;
00378 return STATUS_ERR;
00379 }
00380
00381 int qpol_cond_get_te_true_iter(const qpol_policy_t * policy, const qpol_cond_t * cond, uint32_t rule_type_mask,
00382 qpol_iterator_t ** iter)
00383 {
00384 int error = 0;
00385 cond_rule_state_t *crs = NULL;
00386 cond_node_t *internal_cond = NULL;
00387 policydb_t *db = NULL;
00388
00389 if (iter)
00390 *iter = NULL;
00391
00392 if (!policy || !cond || !iter) {
00393 ERR(policy, "%s", strerror(EINVAL));
00394 errno = EINVAL;
00395 return STATUS_ERR;
00396 }
00397
00398 if (rule_type_mask & ~(QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_CHANGE | QPOL_RULE_TYPE_MEMBER)) {
00399 ERR(policy, "%s", strerror(EINVAL));
00400 errno = EINVAL;
00401 return STATUS_ERR;
00402 }
00403
00404 db = &policy->p->p;
00405 internal_cond = (cond_node_t *) cond;
00406
00407 if (!(crs = calloc(1, sizeof(cond_rule_state_t)))) {
00408 error = errno;
00409 ERR(policy, "%s", strerror(error));
00410 goto err;
00411 }
00412 crs->head = crs->cur = internal_cond->true_list;
00413 crs->rule_type_mask = rule_type_mask;
00414
00415 if (qpol_iterator_create(policy, (void *)crs,
00416 cond_rule_state_get_cur, cond_rule_state_next, cond_rule_state_end,
00417 cond_rule_state_size, free, iter)) {
00418 error = errno;
00419 goto err;
00420 }
00421
00422 if (crs->cur && !(crs->cur->node->key.specified & crs->rule_type_mask))
00423 qpol_iterator_next(*iter);
00424
00425 return STATUS_SUCCESS;
00426
00427 err:
00428 free(crs);
00429 errno = error;
00430 return STATUS_ERR;
00431 }
00432
00433 int qpol_cond_get_av_false_iter(const qpol_policy_t * policy, const qpol_cond_t * cond, uint32_t rule_type_mask,
00434 qpol_iterator_t ** iter)
00435 {
00436 int error = 0;
00437 cond_rule_state_t *crs = NULL;
00438 cond_node_t *internal_cond = NULL;
00439 policydb_t *db = NULL;
00440
00441 if (iter)
00442 *iter = NULL;
00443
00444 if (!policy || !cond || !iter) {
00445 ERR(policy, "%s", strerror(EINVAL));
00446 errno = EINVAL;
00447 return STATUS_ERR;
00448 }
00449
00450 if (rule_type_mask & ~(QPOL_RULE_ALLOW | QPOL_RULE_NEVERALLOW | QPOL_RULE_AUDITALLOW | QPOL_RULE_DONTAUDIT)) {
00451 ERR(policy, "%s", strerror(EINVAL));
00452 errno = EINVAL;
00453 return STATUS_ERR;
00454 }
00455
00456 db = &policy->p->p;
00457 internal_cond = (cond_node_t *) cond;
00458
00459 if (!(crs = calloc(1, sizeof(cond_rule_state_t)))) {
00460 error = errno;
00461 ERR(policy, "%s", strerror(error));
00462 goto err;
00463 }
00464 crs->head = crs->cur = internal_cond->false_list;
00465 crs->rule_type_mask = rule_type_mask;
00466
00467 if (qpol_iterator_create(policy, (void *)crs,
00468 cond_rule_state_get_cur, cond_rule_state_next, cond_rule_state_end,
00469 cond_rule_state_size, free, iter)) {
00470 error = errno;
00471 goto err;
00472 }
00473
00474 if (crs->cur && !(crs->cur->node->key.specified & crs->rule_type_mask))
00475 qpol_iterator_next(*iter);
00476
00477 return STATUS_SUCCESS;
00478
00479 err:
00480 free(crs);
00481 errno = error;
00482 return STATUS_ERR;
00483 }
00484
00485 int qpol_cond_get_te_false_iter(const qpol_policy_t * policy, const qpol_cond_t * cond, uint32_t rule_type_mask,
00486 qpol_iterator_t ** iter)
00487 {
00488 int error = 0;
00489 cond_rule_state_t *crs = NULL;
00490 cond_node_t *internal_cond = NULL;
00491 policydb_t *db = NULL;
00492
00493 if (iter)
00494 *iter = NULL;
00495
00496 if (!policy || !cond || !iter) {
00497 ERR(policy, "%s", strerror(EINVAL));
00498 errno = EINVAL;
00499 return STATUS_ERR;
00500 }
00501
00502 if (rule_type_mask & ~(QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_CHANGE | QPOL_RULE_TYPE_MEMBER)) {
00503 ERR(policy, "%s", strerror(EINVAL));
00504 errno = EINVAL;
00505 return STATUS_ERR;
00506 }
00507
00508 db = &policy->p->p;
00509 internal_cond = (cond_node_t *) cond;
00510
00511 if (!(crs = calloc(1, sizeof(cond_rule_state_t)))) {
00512 error = errno;
00513 ERR(policy, "%s", strerror(error));
00514 goto err;
00515 }
00516 crs->head = crs->cur = internal_cond->false_list;
00517 crs->rule_type_mask = rule_type_mask;
00518
00519 if (qpol_iterator_create(policy, (void *)crs,
00520 cond_rule_state_get_cur, cond_rule_state_next, cond_rule_state_end,
00521 cond_rule_state_size, free, iter)) {
00522 error = errno;
00523 goto err;
00524 }
00525
00526 if (crs->cur && !(crs->cur->node->key.specified & crs->rule_type_mask))
00527 qpol_iterator_next(*iter);
00528
00529 return STATUS_SUCCESS;
00530
00531 err:
00532 free(crs);
00533 errno = error;
00534 return STATUS_ERR;
00535 }
00536
00537 int qpol_cond_eval(const qpol_policy_t * policy, const qpol_cond_t * cond, uint32_t * is_true)
00538 {
00539 int error = 0;
00540 cond_node_t *internal_cond = NULL;
00541
00542 if (is_true)
00543 *is_true = 0;
00544
00545 if (!policy || !cond || !is_true) {
00546 ERR(policy, "%s", strerror(EINVAL));
00547 errno = EINVAL;
00548 return STATUS_ERR;
00549 }
00550
00551 internal_cond = (cond_node_t *) cond;
00552
00553 if ((*is_true = (uint32_t) cond_evaluate_expr(&policy->p->p, internal_cond->expr)) > 1) {
00554 error = ERANGE;
00555 goto err;
00556 }
00557
00558 return STATUS_SUCCESS;
00559
00560 err:
00561 ERR(policy, "%s", strerror(error));
00562 errno = error;
00563 return STATUS_ERR;
00564 }
00565
00566 int qpol_cond_expr_node_get_expr_type(const qpol_policy_t * policy, const qpol_cond_expr_node_t * node, uint32_t * expr_type)
00567 {
00568 cond_expr_t *internal_cond = NULL;
00569
00570 if (expr_type)
00571 *expr_type = 0;
00572
00573 if (!policy || !node || !expr_type) {
00574 ERR(policy, "%s", strerror(EINVAL));
00575 errno = EINVAL;
00576 return STATUS_ERR;
00577 }
00578
00579 internal_cond = (cond_expr_t *) node;
00580
00581 *expr_type = internal_cond->expr_type;
00582
00583 return STATUS_SUCCESS;
00584 }
00585
00586 int qpol_cond_expr_node_get_bool(const qpol_policy_t * policy, const qpol_cond_expr_node_t * node, qpol_bool_t ** cond_bool)
00587 {
00588 int error = 0;
00589 cond_expr_t *internal_cond = NULL;
00590 policydb_t *db = NULL;
00591
00592 if (cond_bool)
00593 *cond_bool = NULL;
00594
00595 if (!policy || !node || !cond_bool) {
00596 ERR(policy, "%s", strerror(EINVAL));
00597 errno = EINVAL;
00598 return STATUS_ERR;
00599 }
00600
00601 db = &policy->p->p;
00602 internal_cond = (cond_expr_t *) node;
00603
00604 if (internal_cond->expr_type != QPOL_COND_EXPR_BOOL) {
00605 error = EINVAL;
00606 goto err;
00607 }
00608
00609 if (!(*cond_bool = (qpol_bool_t *) db->bool_val_to_struct[internal_cond->bool - 1])) {
00610 error = EINVAL;
00611 goto err;
00612 }
00613
00614 return STATUS_SUCCESS;
00615
00616 err:
00617 ERR(policy, "%s", strerror(error));
00618 errno = error;
00619 return STATUS_ERR;
00620 }