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
00029
00030 #include "policy-query-internal.h"
00031 #include <apol/bst.h>
00032 #include <qpol/policy_extend.h>
00033 #include <errno.h>
00034 #include <string.h>
00035
00036 struct apol_terule_query
00037 {
00038 char *source, *target, *default_type, *bool_name;
00039 apol_vector_t *classes;
00040 unsigned int rules;
00041 unsigned int flags;
00042 };
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 static int rule_select(const apol_policy_t * p, apol_vector_t * v, uint32_t rule_type, unsigned int flags,
00063 const apol_vector_t * source_list, const apol_vector_t * target_list, const apol_vector_t * class_list,
00064 const apol_vector_t * default_list, const char *bool_name)
00065 {
00066 qpol_iterator_t *iter = NULL;
00067 int only_enabled = flags & APOL_QUERY_ONLY_ENABLED;
00068 int is_regex = flags & APOL_QUERY_REGEX;
00069 int source_as_any = flags & APOL_QUERY_SOURCE_AS_ANY;
00070 int retv = -1;
00071 regex_t *bool_regex = NULL;
00072
00073 if (qpol_policy_get_terule_iter(p->p, rule_type, &iter) < 0) {
00074 goto cleanup;
00075 }
00076
00077 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00078 qpol_terule_t *rule;
00079 uint32_t is_enabled;
00080 const qpol_cond_t *cond = NULL;
00081 int match_source = 0, match_target = 0, match_default = 0, match_bool = 0;
00082 size_t i;
00083 if (qpol_iterator_get_item(iter, (void **)&rule) < 0) {
00084 goto cleanup;
00085 }
00086
00087 if (qpol_terule_get_is_enabled(p->p, rule, &is_enabled) < 0) {
00088 goto cleanup;
00089 }
00090 if (!is_enabled && only_enabled) {
00091 continue;
00092 }
00093
00094 if (bool_name != NULL) {
00095 if (qpol_terule_get_cond(p->p, rule, &cond) < 0) {
00096 goto cleanup;
00097 }
00098 if (cond == NULL) {
00099 continue;
00100 }
00101 match_bool = apol_compare_cond_expr(p, cond, bool_name, is_regex, &bool_regex);
00102 if (match_bool < 0) {
00103 goto cleanup;
00104 } else if (match_bool == 0) {
00105 continue;
00106 }
00107 }
00108
00109 if (source_list == NULL) {
00110 match_source = 1;
00111 } else {
00112 const qpol_type_t *source_type;
00113 if (qpol_terule_get_source_type(p->p, rule, &source_type) < 0) {
00114 goto cleanup;
00115 }
00116 if (apol_vector_get_index(source_list, source_type, NULL, NULL, &i) == 0) {
00117 match_source = 1;
00118 }
00119 }
00120
00121
00122
00123
00124 if (!source_as_any && !match_source) {
00125 continue;
00126 }
00127
00128 if (target_list == NULL || (source_as_any && match_source)) {
00129 match_target = 1;
00130 } else {
00131 const qpol_type_t *target_type;
00132 if (qpol_terule_get_target_type(p->p, rule, &target_type) < 0) {
00133 goto cleanup;
00134 }
00135 if (apol_vector_get_index(target_list, target_type, NULL, NULL, &i) == 0) {
00136 match_target = 1;
00137 }
00138 }
00139
00140 if (!source_as_any && !match_target) {
00141 continue;
00142 }
00143
00144 if (default_list == NULL || (source_as_any && match_source) || (source_as_any && match_target)) {
00145 match_default = 1;
00146 } else {
00147 const qpol_type_t *default_type;
00148 if (qpol_terule_get_default_type(p->p, rule, &default_type) < 0) {
00149 goto cleanup;
00150 }
00151 if (apol_vector_get_index(default_list, default_type, NULL, NULL, &i) == 0) {
00152 match_default = 1;
00153 }
00154 }
00155
00156 if (!source_as_any && !match_default) {
00157 continue;
00158 }
00159
00160 if (source_as_any && (!match_source && !match_target && !match_default)) {
00161 continue;
00162 }
00163
00164 if (class_list != NULL) {
00165 const qpol_class_t *obj_class;
00166 if (qpol_terule_get_object_class(p->p, rule, &obj_class) < 0) {
00167 goto cleanup;
00168 }
00169 if (apol_vector_get_index(class_list, obj_class, NULL, NULL, &i) < 0) {
00170 continue;
00171 }
00172 }
00173
00174 if (apol_vector_append(v, rule)) {
00175 ERR(p, "%s", strerror(ENOMEM));
00176 goto cleanup;
00177 }
00178 }
00179
00180 retv = 0;
00181
00182 cleanup:
00183 apol_regex_destroy(&bool_regex);
00184 qpol_iterator_destroy(&iter);
00185 return retv;
00186 }
00187
00188 int apol_terule_get_by_query(const apol_policy_t * p, const apol_terule_query_t * t, apol_vector_t ** v)
00189 {
00190 apol_vector_t *source_list = NULL, *target_list = NULL, *class_list = NULL, *default_list = NULL;
00191 int retval = -1, source_as_any = 0, is_regex = 0;
00192 char *bool_name = NULL;
00193 *v = NULL;
00194 unsigned int flags = 0;
00195
00196 uint32_t rule_type = QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_MEMBER | QPOL_RULE_TYPE_CHANGE;
00197 if (t != NULL) {
00198 if (t->rules != 0) {
00199 rule_type &= t->rules;
00200 }
00201 flags = t->flags;
00202 is_regex = t->flags & APOL_QUERY_REGEX;
00203 bool_name = t->bool_name;
00204 if (t->source != NULL &&
00205 (source_list =
00206 apol_query_create_candidate_type_list(p, t->source, is_regex,
00207 t->flags & APOL_QUERY_SOURCE_INDIRECT,
00208 ((t->flags & (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE)) /
00209 APOL_QUERY_SOURCE_TYPE))) == NULL) {
00210 goto cleanup;
00211 }
00212 if ((t->flags & APOL_QUERY_SOURCE_AS_ANY) && t->source != NULL) {
00213 default_list = target_list = source_list;
00214 source_as_any = 1;
00215 } else {
00216 if (t->target != NULL &&
00217 (target_list =
00218 apol_query_create_candidate_type_list(p, t->target, is_regex,
00219 t->flags & APOL_QUERY_TARGET_INDIRECT,
00220 ((t->
00221 flags & (APOL_QUERY_TARGET_TYPE | APOL_QUERY_TARGET_ATTRIBUTE))
00222 / APOL_QUERY_TARGET_TYPE))) == NULL) {
00223 goto cleanup;
00224 }
00225 if (t->default_type != NULL &&
00226 (default_list =
00227 apol_query_create_candidate_type_list(p, t->default_type, is_regex, 0,
00228 APOL_QUERY_SYMBOL_IS_TYPE)) == NULL) {
00229 goto cleanup;
00230 }
00231 }
00232 if (t->classes != NULL &&
00233 apol_vector_get_size(t->classes) > 0 &&
00234 (class_list = apol_query_create_candidate_class_list(p, t->classes)) == NULL) {
00235 goto cleanup;
00236 }
00237 }
00238
00239 if ((*v = apol_vector_create(NULL)) == NULL) {
00240 ERR(p, "%s", strerror(errno));
00241 goto cleanup;
00242 }
00243
00244 if (rule_select(p, *v, rule_type, flags, source_list, target_list, class_list, default_list, bool_name)) {
00245 goto cleanup;
00246 }
00247
00248 retval = 0;
00249 cleanup:
00250 if (retval != 0) {
00251 apol_vector_destroy(v);
00252 }
00253 apol_vector_destroy(&source_list);
00254 if (!source_as_any) {
00255 apol_vector_destroy(&target_list);
00256 apol_vector_destroy(&default_list);
00257 }
00258 apol_vector_destroy(&class_list);
00259 return retval;
00260 }
00261
00262 int apol_syn_terule_get_by_query(const apol_policy_t * p, const apol_terule_query_t * t, apol_vector_t ** v)
00263 {
00264 apol_vector_t *source_list = NULL, *target_list = NULL, *class_list = NULL, *default_list = NULL, *syn_v = NULL;
00265 int retval = -1, source_as_any = 0, is_regex = 0;
00266 char *bool_name = NULL;
00267 *v = NULL;
00268 size_t i;
00269 unsigned int flags = 0;
00270
00271 if (!p || !qpol_policy_has_capability(apol_policy_get_qpol(p), QPOL_CAP_SYN_RULES)) {
00272 ERR(p, "%s", strerror(EINVAL));
00273 goto cleanup;
00274 }
00275
00276 uint32_t rule_type = QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_MEMBER | QPOL_RULE_TYPE_CHANGE;
00277 if (t != NULL) {
00278 if (t->rules != 0) {
00279 rule_type &= t->rules;
00280 }
00281 flags = t->flags;
00282 is_regex = t->flags & APOL_QUERY_REGEX;
00283 bool_name = t->bool_name;
00284 if (t->source != NULL &&
00285 (source_list =
00286 apol_query_create_candidate_syn_type_list(p, t->source, is_regex,
00287 t->flags & APOL_QUERY_SOURCE_INDIRECT,
00288 ((t->flags & (APOL_QUERY_SOURCE_TYPE |
00289 APOL_QUERY_SOURCE_ATTRIBUTE)) /
00290 APOL_QUERY_SOURCE_TYPE))) == NULL) {
00291 goto cleanup;
00292 }
00293 if ((t->flags & APOL_QUERY_SOURCE_AS_ANY) && t->source != NULL) {
00294 default_list = target_list = source_list;
00295 source_as_any = 1;
00296 } else {
00297 if (t->target != NULL &&
00298 (target_list =
00299 apol_query_create_candidate_syn_type_list(p, t->target, is_regex,
00300 t->flags & APOL_QUERY_TARGET_INDIRECT,
00301 ((t->flags & (APOL_QUERY_TARGET_TYPE |
00302 APOL_QUERY_TARGET_ATTRIBUTE))
00303 / APOL_QUERY_TARGET_TYPE))) == NULL) {
00304 goto cleanup;
00305 }
00306 if (t->default_type != NULL &&
00307 (default_list =
00308 apol_query_create_candidate_type_list(p, t->default_type, is_regex, 0,
00309 APOL_QUERY_SYMBOL_IS_TYPE)) == NULL) {
00310 goto cleanup;
00311 }
00312 }
00313 if (t->classes != NULL &&
00314 apol_vector_get_size(t->classes) > 0 &&
00315 (class_list = apol_query_create_candidate_class_list(p, t->classes)) == NULL) {
00316 goto cleanup;
00317 }
00318 }
00319
00320 if ((*v = apol_vector_create(NULL)) == NULL) {
00321 ERR(p, "%s", strerror(errno));
00322 goto cleanup;
00323 }
00324
00325 if (rule_select(p, *v, rule_type, flags, source_list, target_list, class_list, default_list, bool_name)) {
00326 goto cleanup;
00327 }
00328
00329 syn_v = apol_terule_list_to_syn_terules(p, *v);
00330 if (!syn_v) {
00331 goto cleanup;
00332 }
00333 apol_vector_destroy(v);
00334 *v = syn_v;
00335 syn_v = NULL;
00336
00337
00338 if ((t->flags & APOL_QUERY_SOURCE_INDIRECT) && (t->flags & (APOL_QUERY_TARGET_INDIRECT | APOL_QUERY_SOURCE_AS_ANY))) {
00339 retval = 0;
00340 goto cleanup;
00341 }
00342
00343 if (!source_list && !target_list && !default_list) {
00344 retval = 0;
00345 goto cleanup;
00346 }
00347
00348 if (source_list && !(t->flags & APOL_QUERY_SOURCE_INDIRECT)) {
00349 apol_vector_destroy(&source_list);
00350 source_list =
00351 apol_query_create_candidate_type_list(p, t->source, is_regex, 0,
00352 ((t->flags & (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE)) /
00353 APOL_QUERY_SOURCE_TYPE));
00354 if (!source_list)
00355 goto cleanup;
00356 }
00357 if (target_list && (source_as_any || !(t->flags & APOL_QUERY_TARGET_INDIRECT))) {
00358 if (source_as_any) {
00359 target_list = source_list;
00360 } else {
00361 apol_vector_destroy(&target_list);
00362 target_list =
00363 apol_query_create_candidate_type_list(p, t->target, is_regex, 0,
00364 ((t->flags & (APOL_QUERY_SOURCE_TYPE |
00365 APOL_QUERY_SOURCE_ATTRIBUTE)) /
00366 APOL_QUERY_SOURCE_TYPE));
00367 if (!target_list)
00368 goto cleanup;
00369 }
00370 }
00371 if (source_as_any) {
00372 default_list = source_list;
00373 }
00374
00375 for (i = 0; i < apol_vector_get_size(*v); i++) {
00376 qpol_syn_terule_t *srule = apol_vector_get_element(*v, i);
00377 const qpol_type_set_t *stypes = NULL, *ttypes = NULL;
00378 const qpol_type_t *dflt = NULL;
00379 size_t j;
00380 int uses_source = 0, uses_target = 0, uses_default = 0;
00381 qpol_syn_terule_get_source_type_set(p->p, srule, &stypes);
00382 qpol_syn_terule_get_target_type_set(p->p, srule, &ttypes);
00383 if (source_list && !(t->flags & APOL_QUERY_SOURCE_INDIRECT)) {
00384 uses_source = apol_query_type_set_uses_types_directly(p, stypes, source_list);
00385 if (uses_source < 0)
00386 goto cleanup;
00387 } else if (source_list && (t->flags & APOL_QUERY_SOURCE_INDIRECT)) {
00388 uses_source = 1;
00389 } else if (!source_list) {
00390 uses_source = 1;
00391 }
00392
00393 if (target_list
00394 && !(t->flags & APOL_QUERY_TARGET_INDIRECT || (source_as_any && t->flags & APOL_QUERY_SOURCE_INDIRECT))) {
00395 uses_target = apol_query_type_set_uses_types_directly(p, ttypes, target_list);
00396 if (uses_target < 0)
00397 goto cleanup;
00398 } else if (target_list
00399 && (t->flags & APOL_QUERY_TARGET_INDIRECT || (source_as_any && t->flags & APOL_QUERY_SOURCE_INDIRECT))) {
00400 uses_target = 1;
00401 } else if (!target_list) {
00402 uses_target = 1;
00403 }
00404
00405 if (default_list) {
00406 qpol_syn_terule_get_default_type(p->p, srule, &dflt);
00407 if (!apol_vector_get_index(default_list, (void *)dflt, NULL, NULL, &j))
00408 uses_default = 1;
00409 } else if (!default_list) {
00410 uses_default = 1;
00411 }
00412
00413 if (!((uses_source && uses_target && uses_default)
00414 || (source_as_any && (uses_source || uses_target || uses_default)))) {
00415 apol_vector_remove(*v, i);
00416 i--;
00417 }
00418 }
00419
00420 retval = 0;
00421 cleanup:
00422 if (retval != 0) {
00423 apol_vector_destroy(v);
00424 }
00425 apol_vector_destroy(&syn_v);
00426 apol_vector_destroy(&source_list);
00427 if (!source_as_any) {
00428 apol_vector_destroy(&target_list);
00429 apol_vector_destroy(&default_list);
00430 }
00431 apol_vector_destroy(&class_list);
00432 return retval;
00433 }
00434
00435 apol_terule_query_t *apol_terule_query_create(void)
00436 {
00437 apol_terule_query_t *t = calloc(1, sizeof(apol_terule_query_t));
00438 if (t != NULL) {
00439 t->rules = ~0U;
00440 t->flags =
00441 (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE | APOL_QUERY_TARGET_TYPE |
00442 APOL_QUERY_TARGET_ATTRIBUTE);
00443 }
00444 return t;
00445 }
00446
00447 void apol_terule_query_destroy(apol_terule_query_t ** t)
00448 {
00449 if (*t != NULL) {
00450 free((*t)->source);
00451 free((*t)->target);
00452 free((*t)->default_type);
00453 free((*t)->bool_name);
00454 apol_vector_destroy(&(*t)->classes);
00455 free(*t);
00456 *t = NULL;
00457 }
00458 }
00459
00460 int apol_terule_query_set_rules(const apol_policy_t * p __attribute__ ((unused)), apol_terule_query_t * t, unsigned int rules)
00461 {
00462 if (rules != 0) {
00463 t->rules = rules;
00464 } else {
00465 t->rules = ~0U;
00466 }
00467 return 0;
00468 }
00469
00470 int apol_terule_query_set_source(const apol_policy_t * p, apol_terule_query_t * t, const char *symbol, int is_indirect)
00471 {
00472 apol_query_set_flag(p, &t->flags, is_indirect, APOL_QUERY_SOURCE_INDIRECT);
00473 return apol_query_set(p, &t->source, NULL, symbol);
00474 }
00475
00476 int apol_terule_query_set_source_component(const apol_policy_t * p, apol_terule_query_t * t, unsigned int component)
00477 {
00478 if (!t || !(component & APOL_QUERY_SYMBOL_IS_BOTH)) {
00479 ERR(p, "%s", strerror(EINVAL));
00480 errno = EINVAL;
00481 return -1;
00482 }
00483 apol_query_set_flag(p, &t->flags, component & APOL_QUERY_SYMBOL_IS_TYPE, APOL_QUERY_SOURCE_TYPE);
00484 apol_query_set_flag(p, &t->flags, component & APOL_QUERY_SYMBOL_IS_ATTRIBUTE, APOL_QUERY_SOURCE_ATTRIBUTE);
00485 return 0;
00486 }
00487
00488 int apol_terule_query_set_target(const apol_policy_t * p, apol_terule_query_t * t, const char *symbol, int is_indirect)
00489 {
00490 apol_query_set_flag(p, &t->flags, is_indirect, APOL_QUERY_TARGET_INDIRECT);
00491 return apol_query_set(p, &t->target, NULL, symbol);
00492 }
00493
00494 int apol_terule_query_set_target_component(const apol_policy_t * p, apol_terule_query_t * t, unsigned int component)
00495 {
00496 if (!t || !(component & APOL_QUERY_SYMBOL_IS_BOTH)) {
00497 ERR(p, "%s", strerror(EINVAL));
00498 errno = EINVAL;
00499 return -1;
00500 }
00501 apol_query_set_flag(p, &t->flags, component & APOL_QUERY_SYMBOL_IS_TYPE, APOL_QUERY_TARGET_TYPE);
00502 apol_query_set_flag(p, &t->flags, component & APOL_QUERY_SYMBOL_IS_ATTRIBUTE, APOL_QUERY_TARGET_ATTRIBUTE);
00503 return 0;
00504 }
00505
00506 int apol_terule_query_set_default(const apol_policy_t * p, apol_terule_query_t * t, const char *symbol)
00507 {
00508 return apol_query_set(p, &t->default_type, NULL, symbol);
00509 }
00510
00511 int apol_terule_query_append_class(const apol_policy_t * p, apol_terule_query_t * t, const char *obj_class)
00512 {
00513 char *s = NULL;
00514 if (obj_class == NULL) {
00515 apol_vector_destroy(&t->classes);
00516 } else if ((s = strdup(obj_class)) == NULL || (t->classes == NULL && (t->classes = apol_vector_create(free)) == NULL)
00517 || apol_vector_append(t->classes, s) < 0) {
00518 ERR(p, "%s", strerror(errno));
00519 free(s);
00520 return -1;
00521 }
00522 return 0;
00523 }
00524
00525 int apol_terule_query_set_bool(const apol_policy_t * p, apol_terule_query_t * t, const char *bool_name)
00526 {
00527 return apol_query_set(p, &t->bool_name, NULL, bool_name);
00528 }
00529
00530 int apol_terule_query_set_enabled(const apol_policy_t * p, apol_terule_query_t * t, int is_enabled)
00531 {
00532 return apol_query_set_flag(p, &t->flags, is_enabled, APOL_QUERY_ONLY_ENABLED);
00533 }
00534
00535 int apol_terule_query_set_source_any(const apol_policy_t * p, apol_terule_query_t * t, int is_any)
00536 {
00537 return apol_query_set_flag(p, &t->flags, is_any, APOL_QUERY_SOURCE_AS_ANY);
00538 }
00539
00540 int apol_terule_query_set_regex(const apol_policy_t * p, apol_terule_query_t * t, int is_regex)
00541 {
00542 return apol_query_set_regex(p, &t->flags, is_regex);
00543 }
00544
00545
00546
00547
00548
00549 static int apol_syn_terule_comp(const void *a, const void *b, void *data)
00550 {
00551 qpol_syn_terule_t *r1 = (qpol_syn_terule_t *) a;
00552 qpol_syn_terule_t *r2 = (qpol_syn_terule_t *) b;
00553 apol_policy_t *p = (apol_policy_t *) data;
00554 unsigned long num1, num2;
00555 if (qpol_syn_terule_get_lineno(p->p, r1, &num1) < 0 || qpol_syn_terule_get_lineno(p->p, r2, &num2) < 0) {
00556 return 0;
00557 }
00558 if (num1 != num2) {
00559 return (int)num1 - (int)num2;
00560 }
00561 return (int)((char *)r1 - (char *)r2);
00562 }
00563
00564 apol_vector_t *apol_terule_to_syn_terules(const apol_policy_t * p, const qpol_terule_t * rule)
00565 {
00566 apol_vector_t *v = NULL;
00567 qpol_iterator_t *iter = NULL;
00568 qpol_syn_terule_t *syn_terule;
00569 int retval = -1, error = 0;
00570 if (qpol_terule_get_syn_terule_iter(p->p, rule, &iter) < 0) {
00571 error = errno;
00572 goto cleanup;
00573 }
00574 if ((v = apol_vector_create(NULL)) == NULL) {
00575 error = errno;
00576 ERR(p, "%s", strerror(error));
00577 goto cleanup;
00578 }
00579 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00580 if (qpol_iterator_get_item(iter, (void **)&syn_terule) < 0) {
00581 error = errno;
00582 ERR(p, "%s", strerror(error));
00583 goto cleanup;
00584 }
00585 if (apol_vector_append(v, syn_terule) < 0) {
00586 error = errno;
00587 ERR(p, "%s", strerror(error));
00588 goto cleanup;
00589 }
00590 }
00591 apol_vector_sort_uniquify(v, apol_syn_terule_comp, (void *)p);
00592 retval = 0;
00593 cleanup:
00594 qpol_iterator_destroy(&iter);
00595 if (retval != 0) {
00596 apol_vector_destroy(&v);
00597 errno = error;
00598 return NULL;
00599 }
00600 return v;
00601 }
00602
00603 apol_vector_t *apol_terule_list_to_syn_terules(const apol_policy_t * p, const apol_vector_t * rules)
00604 {
00605 apol_bst_t *b = NULL;
00606 qpol_terule_t *rule;
00607 qpol_iterator_t *iter = NULL;
00608 qpol_syn_terule_t *syn_terule;
00609 apol_vector_t *v = NULL;
00610 size_t i;
00611 int retval = -1, error = 0;
00612
00613 if ((b = apol_bst_create(apol_syn_terule_comp, NULL)) == NULL) {
00614 error = errno;
00615 ERR(p, "%s", strerror(error));
00616 goto cleanup;
00617 }
00618 for (i = 0; i < apol_vector_get_size(rules); i++) {
00619 rule = apol_vector_get_element(rules, i);
00620 if (qpol_terule_get_syn_terule_iter(p->p, rule, &iter) < 0) {
00621 error = errno;
00622 goto cleanup;
00623 }
00624 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00625 if (qpol_iterator_get_item(iter, (void **)&syn_terule) < 0) {
00626 error = errno;
00627 ERR(p, "%s", strerror(error));
00628 goto cleanup;
00629 }
00630 if (apol_bst_insert(b, syn_terule, (void *)p) < 0) {
00631 error = errno;
00632 ERR(p, "%s", strerror(error));
00633 goto cleanup;
00634 }
00635 }
00636 qpol_iterator_destroy(&iter);
00637 }
00638 if ((v = apol_bst_get_vector(b, 1)) == NULL) {
00639 error = errno;
00640 ERR(p, "%s", strerror(error));
00641 goto cleanup;
00642 }
00643 retval = 0;
00644 cleanup:
00645 apol_bst_destroy(&b);
00646 qpol_iterator_destroy(&iter);
00647 if (retval != 0) {
00648 errno = error;
00649 return NULL;
00650 }
00651 return v;
00652 }
00653
00654 char *apol_terule_render(const apol_policy_t * policy, const qpol_terule_t * rule)
00655 {
00656 char *tmp = NULL;
00657 const char *tmp_name = NULL;
00658 const char *rule_type_str;
00659 int error = 0;
00660 size_t tmp_sz = 0;
00661 uint32_t rule_type = 0;
00662 const qpol_type_t *type = NULL;
00663 const qpol_class_t *obj_class = NULL;
00664
00665 if (!policy || !rule) {
00666 ERR(policy, "%s", strerror(EINVAL));
00667 errno = EINVAL;
00668 return NULL;
00669 }
00670
00671
00672 if (qpol_terule_get_rule_type(policy->p, rule, &rule_type)) {
00673 error = errno;
00674 errno = error;
00675 return NULL;
00676 }
00677 if (!(rule_type &= (QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_CHANGE | QPOL_RULE_TYPE_MEMBER))) {
00678 ERR(policy, "%s", "Invalid type rule type");
00679 errno = EINVAL;
00680 return NULL;
00681 }
00682 if (!(rule_type_str = apol_rule_type_to_str(rule_type))) {
00683 ERR(policy, "%s", "Type rule has multiple rule types?");
00684 errno = EINVAL;
00685 return NULL;
00686 }
00687 if (apol_str_append(&tmp, &tmp_sz, rule_type_str) || apol_str_append(&tmp, &tmp_sz, " ")) {
00688 error = error;
00689 ERR(policy, "%s", strerror(error));
00690 goto err;
00691 }
00692
00693
00694 if (qpol_terule_get_source_type(policy->p, rule, &type)) {
00695 error = errno;
00696 goto err;
00697 }
00698 if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00699 error = errno;
00700 goto err;
00701 }
00702 if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00703 error = error;
00704 ERR(policy, "%s", strerror(error));
00705 goto err;
00706 }
00707
00708
00709 if (qpol_terule_get_target_type(policy->p, rule, &type)) {
00710 error = errno;
00711 goto err;
00712 }
00713 if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00714 error = errno;
00715 goto err;
00716 }
00717 if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " : ")) {
00718 error = error;
00719 ERR(policy, "%s", strerror(error));
00720 goto err;
00721 }
00722
00723
00724 if (qpol_terule_get_object_class(policy->p, rule, &obj_class)) {
00725 error = errno;
00726 goto err;
00727 }
00728 if (qpol_class_get_name(policy->p, obj_class, &tmp_name)) {
00729 error = errno;
00730 goto err;
00731 }
00732 if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00733 error = error;
00734 ERR(policy, "%s", strerror(error));
00735 goto err;
00736 }
00737
00738
00739 if (qpol_terule_get_default_type(policy->p, rule, &type)) {
00740 error = errno;
00741 goto err;
00742 }
00743 if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00744 error = errno;
00745 goto err;
00746 }
00747 if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, ";")) {
00748 error = error;
00749 ERR(policy, "%s", strerror(error));
00750 goto err;
00751 }
00752
00753 return tmp;
00754
00755 err:
00756 free(tmp);
00757 errno = error;
00758 return NULL;
00759 }
00760
00761 char *apol_syn_terule_render(const apol_policy_t * policy, const qpol_syn_terule_t * rule)
00762 {
00763 char *tmp = NULL;
00764 const char *tmp_name = NULL;
00765 const char *rule_type_str;
00766 int error = 0;
00767 uint32_t rule_type = 0, star = 0, comp = 0;
00768 const qpol_type_t *type = NULL;
00769 const qpol_class_t *obj_class = NULL;
00770 qpol_iterator_t *iter = NULL, *iter2 = NULL;
00771 size_t tmp_sz = 0, iter_sz = 0, iter2_sz = 0;
00772 const qpol_type_set_t *set = NULL;
00773
00774 if (!policy || !rule) {
00775 ERR(policy, "%s", strerror(EINVAL));
00776 errno = EINVAL;
00777 return NULL;
00778 }
00779
00780
00781 if (qpol_syn_terule_get_rule_type(policy->p, rule, &rule_type)) {
00782 error = errno;
00783 return NULL;
00784 }
00785 if (!(rule_type &= (QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_CHANGE | QPOL_RULE_TYPE_MEMBER))) {
00786 ERR(policy, "%s", "Invalid te rule type");
00787 errno = EINVAL;
00788 return NULL;
00789 }
00790 if (!(rule_type_str = apol_rule_type_to_str(rule_type))) {
00791 ERR(policy, "%s", "Te rule has multiple rule types?");
00792 errno = EINVAL;
00793 return NULL;
00794 }
00795 if (apol_str_append(&tmp, &tmp_sz, rule_type_str) || apol_str_append(&tmp, &tmp_sz, " ")) {
00796 error = error;
00797 ERR(policy, "%s", strerror(error));
00798 goto err;
00799 }
00800
00801
00802 if (qpol_syn_terule_get_source_type_set(policy->p, rule, &set)) {
00803 error = errno;
00804 goto err;
00805 }
00806 if (qpol_type_set_get_is_star(policy->p, set, &star)) {
00807 error = errno;
00808 goto err;
00809 }
00810 if (star) {
00811 if (apol_str_append(&tmp, &tmp_sz, "* ")) {
00812 error = error;
00813 ERR(policy, "%s", strerror(error));
00814 goto err;
00815 }
00816 } else {
00817 if (qpol_type_set_get_is_comp(policy->p, set, &comp)) {
00818 error = errno;
00819 goto err;
00820 }
00821 if (comp) {
00822 if (apol_str_append(&tmp, &tmp_sz, "~")) {
00823 error = error;
00824 ERR(policy, "%s", strerror(error));
00825 goto err;
00826 }
00827 }
00828 if (qpol_type_set_get_included_types_iter(policy->p, set, &iter)) {
00829 error = errno;
00830 goto err;
00831 }
00832 if (qpol_type_set_get_subtracted_types_iter(policy->p, set, &iter2)) {
00833 error = errno;
00834 goto err;
00835 }
00836 if (qpol_iterator_get_size(iter, &iter_sz) || qpol_iterator_get_size(iter2, &iter2_sz)) {
00837 error = errno;
00838 ERR(policy, "%s", strerror(error));
00839 goto err;
00840 }
00841 if (iter_sz + iter2_sz > 1) {
00842 if (apol_str_append(&tmp, &tmp_sz, "{ ")) {
00843 error = error;
00844 ERR(policy, "%s", strerror(error));
00845 goto err;
00846 }
00847 }
00848 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00849 if (qpol_iterator_get_item(iter, (void **)&type)) {
00850 error = errno;
00851 ERR(policy, "%s", strerror(error));
00852 goto err;
00853 }
00854 if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00855 error = errno;
00856 goto err;
00857 }
00858 if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00859 error = error;
00860 ERR(policy, "%s", strerror(error));
00861 goto err;
00862 }
00863 }
00864 for (; !qpol_iterator_end(iter2); qpol_iterator_next(iter2)) {
00865 if (qpol_iterator_get_item(iter2, (void **)&type)) {
00866 error = errno;
00867 ERR(policy, "%s", strerror(error));
00868 goto err;
00869 }
00870 if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00871 error = errno;
00872 goto err;
00873 }
00874 if (apol_str_append(&tmp, &tmp_sz, "-") ||
00875 apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00876 error = error;
00877 ERR(policy, "%s", strerror(error));
00878 goto err;
00879 }
00880 }
00881 qpol_iterator_destroy(&iter);
00882 qpol_iterator_destroy(&iter2);
00883 if (iter_sz + iter2_sz > 1) {
00884 if (apol_str_append(&tmp, &tmp_sz, "} ")) {
00885 error = error;
00886 ERR(policy, "%s", strerror(error));
00887 goto err;
00888 }
00889 }
00890 }
00891
00892
00893 if (qpol_syn_terule_get_target_type_set(policy->p, rule, &set)) {
00894 error = errno;
00895 goto err;
00896 }
00897 if (qpol_type_set_get_is_star(policy->p, set, &star)) {
00898 error = errno;
00899 goto err;
00900 }
00901 if (star) {
00902 if (apol_str_append(&tmp, &tmp_sz, "* ")) {
00903 error = error;
00904 ERR(policy, "%s", strerror(error));
00905 goto err;
00906 }
00907 } else {
00908 if (qpol_type_set_get_is_comp(policy->p, set, &comp)) {
00909 error = errno;
00910 goto err;
00911 }
00912 if (comp) {
00913 if (apol_str_append(&tmp, &tmp_sz, "~")) {
00914 error = error;
00915 ERR(policy, "%s", strerror(error));
00916 goto err;
00917 }
00918 }
00919 if (qpol_type_set_get_included_types_iter(policy->p, set, &iter)) {
00920 error = errno;
00921 goto err;
00922 }
00923 if (qpol_type_set_get_subtracted_types_iter(policy->p, set, &iter2)) {
00924 error = errno;
00925 goto err;
00926 }
00927 if (qpol_iterator_get_size(iter, &iter_sz) || qpol_iterator_get_size(iter2, &iter2_sz)) {
00928 error = errno;
00929 ERR(policy, "%s", strerror(error));
00930 goto err;
00931 }
00932 if (iter_sz + iter2_sz > 1) {
00933 if (apol_str_append(&tmp, &tmp_sz, "{ ")) {
00934 error = error;
00935 ERR(policy, "%s", strerror(error));
00936 goto err;
00937 }
00938 }
00939 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
00940 if (qpol_iterator_get_item(iter, (void **)&type)) {
00941 error = errno;
00942 ERR(policy, "%s", strerror(error));
00943 goto err;
00944 }
00945 if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00946 error = errno;
00947 goto err;
00948 }
00949 if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00950 error = error;
00951 ERR(policy, "%s", strerror(error));
00952 goto err;
00953 }
00954 }
00955 for (; !qpol_iterator_end(iter2); qpol_iterator_next(iter2)) {
00956 if (qpol_iterator_get_item(iter2, (void **)&type)) {
00957 error = errno;
00958 ERR(policy, "%s", strerror(error));
00959 goto err;
00960 }
00961 if (qpol_type_get_name(policy->p, type, &tmp_name)) {
00962 error = errno;
00963 goto err;
00964 }
00965 if (apol_str_append(&tmp, &tmp_sz, "-") ||
00966 apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
00967 error = error;
00968 ERR(policy, "%s", strerror(error));
00969 goto err;
00970 }
00971 }
00972 qpol_iterator_destroy(&iter);
00973 qpol_iterator_destroy(&iter2);
00974 if (iter_sz + iter2_sz > 1) {
00975 if (apol_str_append(&tmp, &tmp_sz, "} ")) {
00976 error = error;
00977 ERR(policy, "%s", strerror(error));
00978 goto err;
00979 }
00980 }
00981 }
00982
00983 if (apol_str_append(&tmp, &tmp_sz, ": ")) {
00984 error = error;
00985 ERR(policy, "%s", strerror(error));
00986 goto err;
00987 }
00988
00989
00990 if (qpol_syn_terule_get_class_iter(policy->p, rule, &iter)) {
00991 error = errno;
00992 goto err;
00993 }
00994 if (qpol_iterator_get_size(iter, &iter_sz)) {
00995 error = errno;
00996 ERR(policy, "%s", strerror(error));
00997 goto err;
00998 }
00999 if (iter_sz > 1) {
01000 if (apol_str_append(&tmp, &tmp_sz, "{ ")) {
01001 error = errno;
01002 ERR(policy, "%s", strerror(error));
01003 goto err;
01004 }
01005 }
01006 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
01007 if (qpol_iterator_get_item(iter, (void **)&obj_class)) {
01008 error = errno;
01009 ERR(policy, "%s", strerror(error));
01010 goto err;
01011 }
01012 if (qpol_class_get_name(policy->p, obj_class, &tmp_name)) {
01013 error = errno;
01014 goto err;
01015 }
01016 if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, " ")) {
01017 error = errno;
01018 ERR(policy, "%s", strerror(error));
01019 goto err;
01020 }
01021 }
01022 qpol_iterator_destroy(&iter);
01023 if (iter_sz > 1) {
01024 if (apol_str_append(&tmp, &tmp_sz, "} ")) {
01025 error = errno;
01026 ERR(policy, "%s", strerror(error));
01027 goto err;
01028 }
01029 }
01030
01031
01032 if (qpol_syn_terule_get_default_type(policy->p, rule, &type)) {
01033 error = errno;
01034 goto err;
01035 }
01036 if (qpol_type_get_name(policy->p, type, &tmp_name)) {
01037 error = errno;
01038 goto err;
01039 }
01040 if (apol_str_append(&tmp, &tmp_sz, tmp_name) || apol_str_append(&tmp, &tmp_sz, ";")) {
01041 error = errno;
01042 ERR(policy, "%s", strerror(error));
01043 goto err;
01044 }
01045
01046 return tmp;
01047
01048 err:
01049 free(tmp);
01050 qpol_iterator_destroy(&iter);
01051 qpol_iterator_destroy(&iter2);
01052 errno = error;
01053 return NULL;
01054 }