1 // Author: Thomas Liu <tliu (at) redhat.com> 2 3 /** 4 * @file 5 * Python bindings used to search TE rules. 6 * 7 * @author Thomas Liu <tliu (at) redhat.com> 8 * @author Dan Walsh <dwalsh (at) redhat.com> 9 * Copyright (C) 2012-2013 Red Hat, inc 10 * 11 * Sections copied from sesearch.c in setools package 12 * @author Frank Mayer mayerf (at) tresys.com 13 * @author Jeremy A. Mowery jmowery (at) tresys.com 14 * @author Paul Rosenfeld prosenfeld (at) tresys.com 15 * Copyright (C) 2003-2008 Tresys Technology, LLC 16 * 17 * This program is free software; you can redistribute it and/or modify 18 * it under the terms of the GNU General Public License as published by 19 * the Free Software Foundation; either version 2 of the License, or 20 * (at your option) any later version. 21 * 22 * This program is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU General Public License for more details. 26 * 27 * You should have received a copy of the GNU General Public License 28 * along with this program; if not, write to the Free Software 29 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 30 */ 31 32 /** 33 * This is a modified version of sesearch to be used as part of a sepython library for 34 * Python bindings. 35 */ 36 37 #include "common.h" 38 #include "policy.h" 39 40 /* libapol */ 41 #include <apol/policy-query.h> 42 #include <apol/render.h> 43 #include <apol/util.h> 44 #include <apol/vector.h> 45 46 /* libqpol*/ 47 #include <qpol/policy.h> 48 #include <qpol/policy_extend.h> 49 #include <qpol/syn_rule_query.h> 50 #include <qpol/util.h> 51 52 /* other */ 53 #include <errno.h> 54 #include <stdlib.h> 55 #include <stdio.h> 56 #include <assert.h> 57 #include <getopt.h> 58 #include <string.h> 59 #include <stdbool.h> 60 61 #define COPYRIGHT_INFO "Copyright (C) 2012 Red Hat, Inc, Tresys Technology, LLC" 62 63 enum opt_values 64 { 65 RULE_NEVERALLOW = 256, RULE_AUDIT, RULE_AUDITALLOW, RULE_DONTAUDIT, 66 RULE_ROLE_ALLOW, RULE_ROLE_TRANS, RULE_RANGE_TRANS, RULE_ALL, 67 EXPR_ROLE_SOURCE, EXPR_ROLE_TARGET 68 }; 69 70 ; 71 72 typedef struct options 73 { 74 char *src_name; 75 char *tgt_name; 76 char *src_role_name; 77 char *tgt_role_name; 78 char *class_name; 79 char *permlist; 80 char *bool_name; 81 apol_vector_t *class_vector; 82 bool all; 83 bool lineno; 84 bool semantic; 85 bool indirect; 86 bool allow; 87 bool nallow; 88 bool auditallow; 89 bool dontaudit; 90 bool type; 91 bool rtrans; 92 bool role_allow; 93 bool role_trans; 94 bool useregex; 95 bool show_cond; 96 apol_vector_t *perm_vector; 97 } options_t; 98 99 static int py_tuple_insert_obj(PyObject *tuple, int pos, PyObject *obj) 100 { 101 int rt; 102 if (!obj) return -1; 103 rt = PyTuple_SetItem(tuple, pos, obj); 104 return rt; 105 } 106 107 static int perform_ra_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v) 108 { 109 apol_role_allow_query_t *raq = NULL; 110 int error = 0; 111 112 if (!policy || !opt || !v) { 113 ERR(policy, "%s", strerror(EINVAL)); 114 errno = EINVAL; 115 return -1; 116 } 117 118 if (!opt->role_allow && !opt->all) { 119 *v = NULL; 120 return 0; /* no search to do */ 121 } 122 123 raq = apol_role_allow_query_create(); 124 if (!raq) { 125 ERR(policy, "%s", strerror(ENOMEM)); 126 errno = ENOMEM; 127 return -1; 128 } 129 130 apol_role_allow_query_set_regex(policy, raq, opt->useregex); 131 if (opt->src_role_name) { 132 if (apol_role_allow_query_set_source(policy, raq, opt->src_role_name)) { 133 error = errno; 134 goto err; 135 } 136 } 137 if (opt->tgt_role_name) 138 if (apol_role_allow_query_set_target(policy, raq, opt->tgt_role_name)) { 139 error = errno; 140 goto err; 141 } 142 143 if (apol_role_allow_get_by_query(policy, raq, v)) { 144 error = errno; 145 goto err; 146 } 147 apol_role_allow_query_destroy(&raq); 148 return 0; 149 150 err: 151 apol_vector_destroy(v); 152 apol_role_allow_query_destroy(&raq); 153 ERR(policy, "%s", strerror(error)); 154 errno = error; 155 return -1; 156 } 157 158 static PyObject* get_ra_results(const apol_policy_t * policy, const apol_vector_t * v, PyObject *output) 159 { 160 size_t i, num_rules = 0; 161 qpol_policy_t *q; 162 const qpol_role_allow_t *rule = NULL; 163 const char *tmp; 164 PyObject *obj, *dict=NULL; 165 const qpol_role_t *role = NULL; 166 int error = 0; 167 errno = EINVAL; 168 int rt; 169 170 if (!policy || !v) { 171 errno = EINVAL; 172 goto err; 173 } 174 175 if (!(num_rules = apol_vector_get_size(v))) 176 return NULL; 177 178 q = apol_policy_get_qpol(policy); 179 180 for (i = 0; i < num_rules; i++) { 181 dict = PyDict_New(); 182 if (!dict) goto err; 183 if (!(rule = apol_vector_get_element(v, i))) 184 goto err; 185 186 if (qpol_role_allow_get_source_role(q, rule, &role)) { 187 goto err; 188 } 189 if (qpol_role_get_name(q, role, &tmp)) { 190 goto err; 191 } 192 obj = PyString_FromString(tmp); 193 if (py_insert_obj(dict, "source", obj)) 194 goto err; 195 196 if (qpol_role_allow_get_target_role(q, rule, &role)) { 197 goto err; 198 } 199 if (qpol_role_get_name(q, role, &tmp)) { 200 goto err; 201 } 202 obj = PyString_FromString(tmp); 203 if (py_insert_obj(dict, "target", obj)) 204 goto err; 205 206 rt = py_append_obj(output, dict); 207 if (rt) goto err; 208 py_decref(dict); dict=NULL; 209 } 210 goto cleanup; 211 err: 212 error = errno; 213 PyErr_SetString(PyExc_RuntimeError,strerror(error)); 214 py_decref(dict); 215 216 cleanup: 217 errno = error; 218 return output; 219 } 220 221 static int perform_te_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v) 222 { 223 apol_terule_query_t *teq = NULL; 224 unsigned int rules = 0; 225 int error = 0; 226 size_t i; 227 228 if (!policy || !opt || !v) { 229 PyErr_SetString(PyExc_RuntimeError,strerror(EINVAL)); 230 errno = EINVAL; 231 return -1; 232 } 233 234 if (opt->all || opt->type) { 235 rules = (QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_CHANGE | QPOL_RULE_TYPE_MEMBER); 236 } else { 237 *v = NULL; 238 return 0; /* no search to do */ 239 } 240 241 teq = apol_terule_query_create(); 242 if (!teq) { 243 PyErr_SetString(PyExc_RuntimeError,strerror(ENOMEM)); 244 errno = ENOMEM; 245 return -1; 246 } 247 248 apol_terule_query_set_rules(policy, teq, rules); 249 apol_terule_query_set_regex(policy, teq, opt->useregex); 250 251 if (opt->src_name) 252 apol_terule_query_set_source(policy, teq, opt->src_name, opt->indirect); 253 if (opt->tgt_name) 254 apol_terule_query_set_target(policy, teq, opt->tgt_name, opt->indirect); 255 if (opt->bool_name) 256 apol_terule_query_set_bool(policy, teq, opt->bool_name); 257 if (opt->class_name) { 258 if (opt->class_vector == NULL) { 259 if (apol_terule_query_append_class(policy, teq, opt->class_name)) { 260 error = errno; 261 goto err; 262 } 263 } else { 264 for (i = 0; i < apol_vector_get_size(opt->class_vector); ++i) { 265 char *class_name; 266 class_name = apol_vector_get_element(opt->class_vector, i); 267 if (!class_name) 268 continue; 269 if (apol_terule_query_append_class(policy, teq, class_name)) { 270 error = errno; 271 goto err; 272 } 273 } 274 } 275 } 276 277 if (!(opt->semantic) && qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) { 278 if (apol_syn_terule_get_by_query(policy, teq, v)) { 279 goto err; 280 } 281 } else { 282 if (apol_terule_get_by_query(policy, teq, v)) { 283 goto err; 284 } 285 } 286 287 apol_terule_query_destroy(&teq); 288 return 0; 289 290 err: 291 error = errno; 292 PyErr_SetString(PyExc_RuntimeError,strerror(error)); 293 apol_vector_destroy(v); 294 apol_terule_query_destroy(&teq); 295 errno = error; 296 return -1; 297 } 298 299 static PyObject* get_bool(const qpol_policy_t *q, const qpol_cond_t * cond, int enabled) 300 { 301 qpol_iterator_t *iter = NULL; 302 qpol_cond_expr_node_t *expr = NULL; 303 char *tmp = NULL; 304 const char *bool_name = NULL; 305 int error = 0; 306 uint32_t expr_type = 0; 307 qpol_bool_t *cond_bool = NULL; 308 PyObject *obj, *tuple = NULL; 309 PyObject *boollist = NULL; 310 311 if (!q || !cond) { 312 errno = EINVAL; 313 return NULL; 314 } 315 if (qpol_cond_get_expr_node_iter(q, cond, &iter) < 0) { 316 goto err; 317 } 318 319 boollist = PyList_New(0); 320 if (! boollist) goto err; 321 322 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { 323 if (qpol_iterator_get_item(iter, (void **)&expr)) { 324 goto err; 325 } 326 if (qpol_cond_expr_node_get_expr_type(q, expr, &expr_type)) { 327 goto err; 328 } 329 if (expr_type != QPOL_COND_EXPR_BOOL) { 330 obj = PyString_FromString(apol_cond_expr_type_to_str(expr_type)); 331 if (!obj) goto err; 332 if (py_append_obj(boollist, obj)) 333 goto err; 334 } else { 335 tuple = PyTuple_New(2); 336 if (!tuple) goto err; 337 338 if (qpol_cond_expr_node_get_bool(q, expr, &cond_bool)) { 339 goto err; 340 } 341 if (qpol_bool_get_name(q, cond_bool, &bool_name)) { 342 goto err; 343 } 344 obj = PyString_FromString(bool_name); 345 if (py_tuple_insert_obj(tuple, 0, obj)) 346 goto err; 347 obj = PyBool_FromLong(enabled); 348 if (py_tuple_insert_obj(tuple, 1, obj)) 349 goto err; 350 if (py_append_obj(boollist, tuple)) 351 goto err; 352 tuple=NULL; 353 } 354 } 355 356 qpol_iterator_destroy(&iter); 357 return boollist; 358 359 err: 360 error = errno; 361 qpol_iterator_destroy(&iter); 362 py_decref(tuple); 363 py_decref(boollist); 364 free(tmp); 365 errno = error; 366 return NULL; 367 } 368 369 static PyObject* get_te_results(const apol_policy_t * policy, const apol_vector_t * v, PyObject *output) 370 { 371 int error = 0; 372 int rt = 0; 373 PyObject *obj, *dict=NULL, *tuple = NULL; 374 qpol_policy_t *q; 375 uint32_t rule_type = 0; 376 const qpol_type_t *type; 377 size_t i, num_rules = 0; 378 const qpol_terule_t *rule = NULL; 379 char *tmp = NULL, *rule_str = NULL, *expr = NULL; 380 const qpol_cond_t *cond = NULL; 381 uint32_t enabled = 0; 382 const char *tmp_name; 383 const qpol_class_t *obj_class = NULL; 384 385 if (!policy || !v) { 386 errno = EINVAL; 387 goto err; 388 } 389 390 if (!(num_rules = apol_vector_get_size(v))) 391 return NULL; 392 393 q = apol_policy_get_qpol(policy); 394 395 for (i = 0; i < num_rules; i++) { 396 dict = PyDict_New(); 397 if (!dict) goto err; 398 if (!(rule = apol_vector_get_element(v, i))) 399 goto err; 400 if (qpol_terule_get_cond(q, rule, &cond)) 401 goto err; 402 if (qpol_terule_get_is_enabled(q, rule, &enabled)) 403 goto err; 404 405 if (cond) { 406 obj = get_bool(q, cond, enabled); 407 if (!obj) goto err; 408 rt = PyDict_SetItemString(dict, "boolean", obj); 409 py_decref(obj); 410 } 411 412 if (qpol_terule_get_rule_type(q, rule, &rule_type)) 413 goto err; 414 415 if (!(rule_type &= (QPOL_RULE_TYPE_TRANS | QPOL_RULE_TYPE_CHANGE | QPOL_RULE_TYPE_MEMBER))) { 416 PyErr_SetString(PyExc_RuntimeError,"Invalid TE rule type"); 417 errno = EINVAL; 418 goto err; 419 } 420 if (!(tmp_name = apol_rule_type_to_str(rule_type))) { 421 PyErr_SetString(PyExc_RuntimeError, "Could not get TE rule type's string"); 422 errno = EINVAL; 423 goto err; 424 } 425 426 if (py_insert_string(dict, "type", tmp_name)) 427 goto err; 428 429 if (qpol_terule_get_source_type(q, rule, &type)) 430 goto err; 431 if (qpol_type_get_name(q, type, &tmp_name)) 432 goto err; 433 if (py_insert_string(dict, "source", tmp_name)) 434 goto err; 435 436 if (qpol_terule_get_target_type(q, rule, &type)) 437 goto err; 438 if (qpol_type_get_name(q, type, &tmp_name)) 439 goto err; 440 if (py_insert_string(dict, "target", tmp_name)) 441 goto err; 442 443 if (qpol_terule_get_object_class(q, rule, &obj_class)) 444 goto err; 445 if (qpol_class_get_name(q, obj_class, &tmp_name)) 446 goto err; 447 if (py_insert_string(dict, "class", tmp_name)) 448 goto err; 449 450 if (qpol_terule_get_default_type(q, rule, &type)) 451 goto err; 452 if (qpol_type_get_name(q, type, &tmp_name)) 453 goto err; 454 if (py_insert_string(dict, "transtype", tmp_name)) 455 goto err; 456 457 rt = py_append_obj(output, dict); 458 dict = NULL; 459 if(rt) goto err; 460 461 free(rule_str); rule_str = NULL; 462 free(expr); expr = NULL; 463 } 464 goto cleanup; 465 466 err: 467 error = errno; 468 py_decref(dict); 469 py_decref(tuple); 470 PyErr_SetString(PyExc_RuntimeError,strerror(error)); 471 cleanup: 472 free(tmp); 473 free(rule_str); 474 free(expr); 475 errno = error; 476 return output; 477 } 478 479 static int perform_ft_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v) 480 { 481 apol_filename_trans_query_t *ftq = NULL; 482 size_t i; 483 int error = 0; 484 485 if (!policy || !opt || !v) { 486 PyErr_SetString(PyExc_RuntimeError,strerror(EINVAL)); 487 errno = EINVAL; 488 return -1; 489 } 490 491 if (!opt->type && !opt->all) { 492 *v = NULL; 493 return 0; /* no search to do */ 494 } 495 496 ftq = apol_filename_trans_query_create(); 497 if (!ftq) { 498 PyErr_SetString(PyExc_RuntimeError,strerror(ENOMEM)); 499 errno = ENOMEM; 500 return -1; 501 } 502 503 apol_filename_trans_query_set_regex(policy, ftq, opt->useregex); 504 if (opt->src_name) { 505 if (apol_filename_trans_query_set_source(policy, ftq, opt->src_name, opt->indirect)) { 506 goto err; 507 } 508 } 509 510 if (opt->tgt_name) { 511 if (apol_filename_trans_query_set_target(policy, ftq, opt->tgt_name, opt->indirect)) { 512 goto err; 513 } 514 } 515 if (opt->class_name) { 516 if (opt->class_vector == NULL) { 517 if (apol_filename_trans_query_append_class(policy, ftq, opt->class_name)) { 518 goto err; 519 } 520 } else { 521 for (i = 0; i < apol_vector_get_size(opt->class_vector); ++i) { 522 char *class_name; 523 class_name = apol_vector_get_element(opt->class_vector, i); 524 if (!class_name) 525 continue; 526 if (apol_filename_trans_query_append_class(policy, ftq, class_name)) { 527 goto err; 528 } 529 } 530 } 531 } 532 533 if (apol_filename_trans_get_by_query(policy, ftq, v)) 534 goto err; 535 536 apol_filename_trans_query_destroy(&ftq); 537 return 0; 538 539 err: 540 error = errno; 541 PyErr_SetString(PyExc_RuntimeError,strerror(errno)); 542 apol_vector_destroy(v); 543 apol_filename_trans_query_destroy(&ftq); 544 errno = error; 545 return -1; 546 } 547 548 static PyObject* get_ft_results(const apol_policy_t * policy, const apol_vector_t * v, PyObject *list) 549 { 550 PyObject *dict = NULL; 551 size_t i, num_filename_trans = 0; 552 const char *tmp_name; 553 int error = 0; 554 int rt; 555 const qpol_filename_trans_t *filename_trans = NULL; 556 const qpol_class_t *obj_class = NULL; 557 char *tmp = NULL, *filename_trans_str = NULL, *expr = NULL; 558 qpol_policy_t *q; 559 const qpol_type_t *type = NULL; 560 561 if (!policy || !v) { 562 errno = EINVAL; 563 goto err; 564 } 565 566 if (!(num_filename_trans = apol_vector_get_size(v))) 567 return NULL; 568 569 q = apol_policy_get_qpol(policy); 570 571 for (i = 0; i < num_filename_trans; i++) { 572 if (!(filename_trans = apol_vector_get_element(v, i))) 573 goto err; 574 575 dict = PyDict_New(); 576 if (!dict) goto err; 577 578 if (py_insert_string(dict, "type", "type_transition")) 579 goto err; 580 581 /* source type */ 582 if (qpol_filename_trans_get_source_type(q, filename_trans, &type)) { 583 goto err; 584 } 585 if (qpol_type_get_name(q, type, &tmp_name)) { 586 goto err; 587 } 588 589 if (py_insert_string(dict, "source", tmp_name)) 590 goto err; 591 592 if (qpol_filename_trans_get_target_type(q, filename_trans, &type)) 593 goto err; 594 595 if (qpol_type_get_name(q, type, &tmp_name)) 596 goto err; 597 598 if (py_insert_string(dict, "target", tmp_name)) 599 goto err; 600 601 if (qpol_filename_trans_get_object_class(q, filename_trans, &obj_class)) 602 goto err; 603 604 if (qpol_class_get_name(q, obj_class, &tmp_name)) 605 goto err; 606 607 if (py_insert_string(dict, "class", tmp_name)) 608 goto err; 609 610 if (qpol_filename_trans_get_default_type(q, filename_trans, &type)) 611 goto err; 612 if (qpol_type_get_name(q, type, &tmp_name)) 613 goto err; 614 if (py_insert_string(dict, "transtype", tmp_name)) 615 goto err; 616 617 if (! qpol_filename_trans_get_filename(q, filename_trans, &tmp_name)) { 618 if (py_insert_string(dict, "filename", tmp_name)) 619 goto err; 620 } 621 622 rt = py_append_obj(list, dict); 623 dict = NULL; 624 if (rt) goto err; 625 626 free(filename_trans_str); filename_trans_str = NULL; 627 free(expr); expr = NULL; 628 } 629 goto cleanup; 630 631 err: 632 error = errno; 633 PyErr_SetString(PyExc_RuntimeError,strerror(errno)); 634 py_decref(dict); 635 cleanup: 636 free(tmp); 637 free(filename_trans_str); 638 free(expr); 639 errno = error; 640 return list; 641 } 642 643 static int perform_av_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v) 644 { 645 apol_avrule_query_t *avq = NULL; 646 unsigned int rules = 0; 647 int error = 0; 648 char *tmp = NULL, *tok = NULL, *s = NULL; 649 650 if (!policy || !opt || !v) { 651 PyErr_SetString(PyExc_RuntimeError,strerror(EINVAL)); 652 errno = EINVAL; 653 return -1; 654 } 655 656 if (!opt->all && !opt->allow && !opt->nallow && !opt->auditallow && !opt->dontaudit) { 657 *v = NULL; 658 return 0; /* no search to do */ 659 } 660 661 avq = apol_avrule_query_create(); 662 if (!avq) { 663 PyErr_SetString(PyExc_RuntimeError,strerror(ENOMEM)); 664 errno = ENOMEM; 665 return -1; 666 } 667 668 if (opt->allow || opt->all) 669 rules |= QPOL_RULE_ALLOW; 670 if (opt->nallow || opt->all) // Add this regardless of policy capabilities 671 rules |= QPOL_RULE_NEVERALLOW; 672 if (opt->auditallow || opt->all) 673 rules |= QPOL_RULE_AUDITALLOW; 674 if (opt->dontaudit || opt->all) 675 rules |= QPOL_RULE_DONTAUDIT; 676 if (rules != 0) // Setting rules = 0 means you want all the rules 677 apol_avrule_query_set_rules(policy, avq, rules); 678 apol_avrule_query_set_regex(policy, avq, opt->useregex); 679 if (opt->src_name) 680 apol_avrule_query_set_source(policy, avq, opt->src_name, opt->indirect); 681 if (opt->tgt_name) 682 apol_avrule_query_set_target(policy, avq, opt->tgt_name, opt->indirect); 683 if (opt->bool_name) 684 apol_avrule_query_set_bool(policy, avq, opt->bool_name); 685 if (opt->class_name) { 686 if (opt->class_vector == NULL) { 687 if (apol_avrule_query_append_class(policy, avq, opt->class_name)) { 688 goto err; 689 } 690 } else { 691 size_t i; 692 for (i = 0; i < apol_vector_get_size(opt->class_vector); ++i) { 693 char *class_name; 694 class_name = apol_vector_get_element(opt->class_vector, i); 695 if (!class_name) 696 continue; 697 if (apol_avrule_query_append_class(policy, avq, class_name)) { 698 goto err; 699 } 700 } 701 } 702 } 703 704 if (opt->permlist) { 705 tmp = strdup(opt->permlist); 706 for (tok = strtok(tmp, ","); tok; tok = strtok(NULL, ",")) { 707 if (apol_avrule_query_append_perm(policy, avq, tok)) { 708 goto err; 709 } 710 if ((s = strdup(tok)) == NULL || apol_vector_append(opt->perm_vector, s) < 0) { 711 goto err; 712 } 713 s = NULL; 714 } 715 free(tmp); 716 tmp = NULL; 717 } 718 719 if (!(opt->semantic) && qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) { 720 if (apol_syn_avrule_get_by_query(policy, avq, v)) { 721 goto err; 722 } 723 } else { 724 if (apol_avrule_get_by_query(policy, avq, v)) { 725 goto err; 726 } 727 } 728 729 apol_avrule_query_destroy(&avq); 730 return 0; 731 732 err: 733 error = errno; 734 PyErr_SetString(PyExc_RuntimeError,strerror(error)); 735 apol_vector_destroy(v); 736 apol_avrule_query_destroy(&avq); 737 free(tmp); 738 free(s); 739 errno = error; 740 return -1; 741 } 742 743 static PyObject* get_av_results(const apol_policy_t * policy, const apol_vector_t * v, PyObject *output) 744 { 745 PyObject *obj, *dict=NULL; 746 PyObject *permlist = NULL; 747 PyObject *boollist = NULL; 748 uint32_t rule_type = 0; 749 int rt; 750 int error = 0; 751 qpol_policy_t *q; 752 size_t i, num_rules = 0; 753 const qpol_avrule_t *rule = NULL; 754 char *tmp = NULL, *rule_str = NULL; 755 qpol_cond_expr_node_t *expr = NULL; 756 qpol_iterator_t *iter = NULL; 757 const qpol_cond_t *cond = NULL; 758 uint32_t enabled = 0; 759 const qpol_type_t *type; 760 const char *tmp_name; 761 const qpol_class_t *obj_class = NULL; 762 763 if (!policy || !v) { 764 errno = EINVAL; 765 goto err; 766 } 767 768 if (!(num_rules = apol_vector_get_size(v))) 769 return NULL; 770 771 q = apol_policy_get_qpol(policy); 772 773 for (i = 0; i < num_rules; i++) { 774 if (!(rule = apol_vector_get_element(v, i))) 775 goto err; 776 777 dict = PyDict_New(); 778 if (!dict) goto err; 779 780 if (qpol_avrule_get_rule_type(q, rule, &rule_type)) 781 goto err; 782 783 if (!(tmp_name = apol_rule_type_to_str(rule_type))) { 784 PyErr_SetString(PyExc_RuntimeError, "Could not get TE rule type's string"); 785 errno = EINVAL; 786 goto err; 787 } 788 789 if (py_insert_string(dict, "type", tmp_name)) 790 goto err; 791 792 if (qpol_avrule_get_source_type(q, rule, &type)) { 793 goto err; 794 } 795 796 if (qpol_type_get_name(q, type, &tmp_name)) { 797 goto err; 798 } 799 800 if (py_insert_string(dict, "source", tmp_name)) 801 goto err; 802 803 if (qpol_avrule_get_target_type(q, rule, &type)) { 804 goto err; 805 } 806 if (qpol_type_get_name(q, type, &tmp_name)) { 807 goto err; 808 } 809 810 if (py_insert_string(dict, "target", tmp_name)) 811 goto err; 812 813 if (qpol_avrule_get_object_class(q, rule, &obj_class)) { 814 goto err; 815 } 816 if (qpol_class_get_name(q, obj_class, &tmp_name)) { 817 goto err; 818 } 819 820 if (py_insert_string(dict, "class", tmp_name)) 821 goto err; 822 823 if (qpol_avrule_get_perm_iter(q, rule, &iter)) { 824 goto err; 825 } 826 827 permlist = PyList_New(0); 828 if (! permlist) goto err; 829 830 for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { 831 const char *perm_name = NULL; 832 if (qpol_iterator_get_item(iter, (void **)&perm_name)) 833 goto err; 834 if (py_append_string(permlist, perm_name)) 835 goto err; 836 } 837 838 rt = PyDict_SetItemString(dict, "permlist", permlist); 839 py_decref(permlist); permlist=NULL; 840 if (rt) goto err; 841 842 if (qpol_avrule_get_cond(q, rule, &cond)) 843 goto err; 844 if (qpol_avrule_get_is_enabled(q, rule, &enabled)) 845 goto err; 846 847 obj = PyBool_FromLong(enabled); 848 rt = PyDict_SetItemString(dict, "enabled", obj); 849 py_decref(obj); 850 851 if (cond) { 852 obj = get_bool(q, cond, enabled); 853 if (!obj) goto err; 854 rt = PyDict_SetItemString(dict, "boolean", obj); 855 py_decref(obj); 856 } 857 858 rt = py_append_obj(output, dict); 859 py_decref(dict); dict=NULL; 860 if (rt) goto err; 861 862 free(rule_str); rule_str = NULL; 863 free(expr); expr = NULL; 864 } 865 goto cleanup; 866 867 err: 868 error = errno; 869 PyErr_SetString(PyExc_RuntimeError,strerror(errno)); 870 py_decref(dict); 871 py_decref(permlist); 872 py_decref(boollist); 873 874 cleanup: 875 free(tmp); 876 free(rule_str); 877 free(expr); 878 errno = error; 879 return output; 880 } 881 882 PyObject* search(bool allow, 883 bool neverallow, 884 bool auditallow, 885 bool dontaudit, 886 bool transition, 887 bool role_allow, 888 const char *src_name, 889 const char *tgt_name, 890 const char *class_name, 891 const char *permlist 892 ) 893 { 894 options_t cmd_opts; 895 PyObject *output = NULL; 896 apol_vector_t *v = NULL; 897 898 memset(&cmd_opts, 0, sizeof(cmd_opts)); 899 cmd_opts.indirect = true; 900 cmd_opts.show_cond = true; 901 cmd_opts.allow = allow; 902 cmd_opts.nallow = neverallow; 903 cmd_opts.auditallow = auditallow; 904 cmd_opts.dontaudit = dontaudit; 905 cmd_opts.type = transition; 906 cmd_opts.role_allow = role_allow; 907 if (src_name) 908 cmd_opts.src_name = strdup(src_name); 909 if (tgt_name) 910 cmd_opts.tgt_name = strdup(tgt_name); 911 if (class_name) 912 cmd_opts.class_name = strdup(class_name); 913 if (permlist){ 914 cmd_opts.perm_vector = apol_vector_create(free); 915 cmd_opts.permlist = strdup(permlist); 916 } 917 if (!cmd_opts.semantic && qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) { 918 if (qpol_policy_build_syn_rule_table(apol_policy_get_qpol(policy))) { 919 PyErr_SetString(PyExc_RuntimeError,"Query failed"); 920 goto cleanup; 921 } 922 } 923 924 /* if syntactic rules are not available always do semantic search */ 925 if (!qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) { 926 cmd_opts.semantic = 1; 927 } 928 929 /* supress line numbers if doing semantic search or not available */ 930 if (cmd_opts.semantic || !qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_LINE_NUMBERS)) { 931 cmd_opts.lineno = 0; 932 } 933 if (perform_av_query(policy, &cmd_opts, &v)) { 934 goto cleanup; 935 } 936 output = PyList_New(0); 937 if (!output) 938 goto cleanup; 939 940 if (v) { 941 get_av_results(policy, v, output); 942 } 943 944 apol_vector_destroy(&v); 945 if (perform_te_query(policy, &cmd_opts, &v)) { 946 goto cleanup; 947 } 948 if (v) { 949 get_te_results(policy, v, output); 950 } 951 952 if (cmd_opts.all || cmd_opts.type) { 953 apol_vector_destroy(&v); 954 if (perform_ft_query(policy, &cmd_opts, &v)) { 955 goto cleanup; 956 } 957 958 if (v) { 959 get_ft_results(policy, v, output); 960 } 961 } 962 963 if (cmd_opts.all || cmd_opts.role_allow) { 964 apol_vector_destroy(&v); 965 if (perform_ra_query(policy, &cmd_opts, &v)) { 966 goto cleanup; 967 } 968 969 if (v) { 970 get_ra_results(policy, v, output); 971 } 972 } 973 974 apol_vector_destroy(&v); 975 976 cleanup: 977 free(cmd_opts.src_name); 978 free(cmd_opts.tgt_name); 979 free(cmd_opts.class_name); 980 free(cmd_opts.permlist); 981 free(cmd_opts.bool_name); 982 free(cmd_opts.src_role_name); 983 free(cmd_opts.tgt_role_name); 984 apol_vector_destroy(&cmd_opts.perm_vector); 985 apol_vector_destroy(&cmd_opts.class_vector); 986 987 if (output && PyList_GET_SIZE(output) == 0) { 988 py_decref(output); 989 return Py_None; 990 } 991 return output; 992 } 993 994 static int Dict_ContainsInt(PyObject *dict, const char *key){ 995 PyObject *item = PyDict_GetItemString(dict, key); 996 if (item) 997 return PyInt_AsLong(item); 998 return false; 999 } 1000 1001 static const char *Dict_ContainsString(PyObject *dict, const char *key){ 1002 PyObject *item = PyDict_GetItemString(dict, key); 1003 if (item) 1004 return PyString_AsString(item); 1005 return NULL; 1006 } 1007 1008 PyObject *wrap_search(PyObject *UNUSED(self), PyObject *args){ 1009 PyObject *dict; 1010 if (!PyArg_ParseTuple(args, "O", &dict)) 1011 return NULL; 1012 int allow = Dict_ContainsInt(dict, "allow"); 1013 int neverallow = Dict_ContainsInt(dict, "neverallow"); 1014 int auditallow = Dict_ContainsInt(dict, "auditallow"); 1015 int dontaudit = Dict_ContainsInt(dict, "dontaudit"); 1016 int transition = Dict_ContainsInt(dict, "transition"); 1017 int role_allow = Dict_ContainsInt(dict, "role_allow"); 1018 1019 if (!policy) { 1020 PyErr_SetString(PyExc_RuntimeError,"Policy not loaded"); 1021 return NULL; 1022 } 1023 const char *src_name = Dict_ContainsString(dict, "source"); 1024 const char *tgt_name = Dict_ContainsString(dict, "target"); 1025 const char *class_name = Dict_ContainsString(dict, "class"); 1026 const char *permlist = Dict_ContainsString(dict, "permlist"); 1027 1028 return search(allow, neverallow, auditallow, dontaudit, transition, role_allow, src_name, tgt_name, class_name, permlist); 1029 } 1030