1 /* 2 * Copyright 2011 Tresys Technology, LLC. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS 15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 22 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * The views and conclusions contained in the software and documentation are those 26 * of the authors and should not be interpreted as representing official policies, 27 * either expressed or implied, of Tresys Technology, LLC. 28 */ 29 30 #include <stdlib.h> 31 #include <stdio.h> 32 #include <string.h> 33 #include <stdint.h> 34 #include <unistd.h> 35 #include <inttypes.h> 36 37 #include <sepol/policydb/conditional.h> 38 #include <sepol/errcodes.h> 39 40 #include "cil_internal.h" 41 #include "cil_flavor.h" 42 #include "cil_log.h" 43 #include "cil_mem.h" 44 #include "cil_tree.h" 45 #include "cil_list.h" 46 #include "cil_policy.h" 47 #include "cil_symtab.h" 48 #include "cil_strpool.h" 49 50 #define SEPOL_DONE 555 51 52 #define CLASS_DECL 0 53 #define ISIDS 1 54 #define COMMONS 2 55 #define CLASSES 3 56 #define INTERFACES 4 57 #define SENS 5 58 #define CATS 6 59 #define LEVELS 7 60 #define CONSTRAINS 8 61 #define TYPEATTRTYPES 9 62 #define ALIASES 10 63 #define ALLOWS 11 64 #define CONDS 12 65 #define USERROLES 13 66 #define SIDS 14 67 #define NETIFCONS 15 68 69 #define BUFFER 1024 70 #define NUM_POLICY_FILES 16 71 72 struct cil_args_genpolicy { 73 struct cil_list *users; 74 struct cil_list *sens; 75 struct cil_list *cats; 76 FILE **file_arr; 77 }; 78 79 struct cil_args_booleanif { 80 FILE **file_arr; 81 uint32_t *file_index; 82 }; 83 84 85 int cil_expr_to_policy(FILE **file_arr, uint32_t file_index, struct cil_list *expr); 86 87 int cil_combine_policy(FILE **file_arr, FILE *policy_file) 88 { 89 char temp[BUFFER]; 90 int i, rc, rc_read, rc_write; 91 92 for(i=0; i<NUM_POLICY_FILES; i++) { 93 fseek(file_arr[i], 0, SEEK_SET); 94 while (!feof(file_arr[i])) { 95 rc_read = fread(temp, 1, BUFFER, file_arr[i]); 96 if (rc_read == 0 && ferror(file_arr[i])) { 97 cil_log(CIL_ERR, "Error reading temp policy file\n"); 98 return SEPOL_ERR; 99 } 100 rc_write = 0; 101 while (rc_read > rc_write) { 102 rc = fwrite(temp+rc_write, 1, rc_read-rc_write, policy_file); 103 rc_write += rc; 104 if (rc == 0 && ferror(file_arr[i])) { 105 cil_log(CIL_ERR, "Error writing to policy.conf\n"); 106 return SEPOL_ERR; 107 } 108 } 109 } 110 } 111 112 return SEPOL_OK; 113 } 114 115 int cil_portcon_to_policy(FILE **file_arr, struct cil_sort *sort) 116 { 117 uint32_t i = 0; 118 119 for (i=0; i<sort->count; i++) { 120 struct cil_portcon *portcon = (struct cil_portcon*)sort->array[i]; 121 fprintf(file_arr[NETIFCONS], "portcon "); 122 if (portcon->proto == CIL_PROTOCOL_UDP) { 123 fprintf(file_arr[NETIFCONS], "udp "); 124 } else if (portcon->proto == CIL_PROTOCOL_TCP) { 125 fprintf(file_arr[NETIFCONS], "tcp "); 126 } 127 fprintf(file_arr[NETIFCONS], "%d ", portcon->port_low); 128 fprintf(file_arr[NETIFCONS], "%d ", portcon->port_high); 129 cil_context_to_policy(file_arr, NETIFCONS, portcon->context); 130 fprintf(file_arr[NETIFCONS], ";\n"); 131 } 132 133 return SEPOL_OK; 134 } 135 136 int cil_genfscon_to_policy(FILE **file_arr, struct cil_sort *sort) 137 { 138 uint32_t i = 0; 139 140 for (i=0; i<sort->count; i++) { 141 struct cil_genfscon *genfscon = (struct cil_genfscon*)sort->array[i]; 142 fprintf(file_arr[NETIFCONS], "genfscon %s ", genfscon->fs_str); 143 fprintf(file_arr[NETIFCONS], "%s ", genfscon->path_str); 144 cil_context_to_policy(file_arr, NETIFCONS, genfscon->context); 145 fprintf(file_arr[NETIFCONS], ";\n"); 146 } 147 148 return SEPOL_OK; 149 } 150 151 int cil_netifcon_to_policy(FILE **file_arr, struct cil_sort *sort) 152 { 153 uint32_t i = 0; 154 155 for (i=0; i<sort->count; i++) { 156 struct cil_netifcon *netifcon = (struct cil_netifcon*)sort->array[i]; 157 fprintf(file_arr[NETIFCONS], "netifcon %s ", netifcon->interface_str); 158 cil_context_to_policy(file_arr, NETIFCONS, netifcon->if_context); 159 fprintf(file_arr[NETIFCONS], " "); 160 cil_context_to_policy(file_arr, NETIFCONS, netifcon->packet_context); 161 fprintf(file_arr[NETIFCONS], ";\n"); 162 } 163 164 return SEPOL_OK; 165 } 166 167 int cil_nodecon_to_policy(FILE **file_arr, struct cil_sort *sort) 168 { 169 uint32_t i = 0; 170 int rc = SEPOL_ERR; 171 172 for (i=0; i<sort->count; i++) { 173 struct cil_nodecon *nodecon = (struct cil_nodecon*)sort->array[i]; 174 char *buf = NULL; 175 errno = 0; 176 if (nodecon->addr->family == AF_INET) { 177 buf = cil_malloc(INET_ADDRSTRLEN); 178 inet_ntop(nodecon->addr->family, &nodecon->addr->ip.v4, buf, INET_ADDRSTRLEN); 179 } else if (nodecon->addr->family == AF_INET6) { 180 buf = cil_malloc(INET6_ADDRSTRLEN); 181 inet_ntop(nodecon->addr->family, &nodecon->addr->ip.v6, buf, INET6_ADDRSTRLEN); 182 } 183 184 if (errno != 0) { 185 cil_log(CIL_INFO, "Failed to convert ip address to string\n"); 186 rc = SEPOL_ERR; 187 goto exit; 188 } 189 190 fprintf(file_arr[NETIFCONS], "nodecon %s ", buf); 191 free(buf); 192 193 if (nodecon->mask->family == AF_INET) { 194 buf = cil_malloc(INET_ADDRSTRLEN); 195 inet_ntop(nodecon->mask->family, &nodecon->mask->ip.v4, buf, INET_ADDRSTRLEN); 196 } else if (nodecon->mask->family == AF_INET6) { 197 buf = cil_malloc(INET6_ADDRSTRLEN); 198 inet_ntop(nodecon->mask->family, &nodecon->mask->ip.v6, buf, INET6_ADDRSTRLEN); 199 } 200 201 if (errno != 0) { 202 cil_log(CIL_INFO, "Failed to convert mask to string\n"); 203 rc = SEPOL_ERR; 204 goto exit; 205 } 206 207 fprintf(file_arr[NETIFCONS], "%s ", buf); 208 free(buf); 209 210 cil_context_to_policy(file_arr, NETIFCONS, nodecon->context); 211 fprintf(file_arr[NETIFCONS], ";\n"); 212 } 213 214 return SEPOL_OK; 215 216 exit: 217 return rc; 218 } 219 220 221 int cil_pirqcon_to_policy(FILE **file_arr, struct cil_sort *sort) 222 { 223 uint32_t i = 0; 224 225 for (i = 0; i < sort->count; i++) { 226 struct cil_pirqcon *pirqcon = (struct cil_pirqcon*)sort->array[i]; 227 fprintf(file_arr[NETIFCONS], "pirqcon %d ", pirqcon->pirq); 228 cil_context_to_policy(file_arr, NETIFCONS, pirqcon->context); 229 fprintf(file_arr[NETIFCONS], ";\n"); 230 } 231 232 return SEPOL_OK; 233 } 234 int cil_iomemcon_to_policy(FILE **file_arr, struct cil_sort *sort) 235 { 236 uint32_t i = 0; 237 238 for (i = 0; i < sort->count; i++) { 239 struct cil_iomemcon *iomemcon = (struct cil_iomemcon*)sort->array[i]; 240 fprintf(file_arr[NETIFCONS], "iomemcon %"PRId64"-%"PRId64" ", iomemcon->iomem_low, iomemcon->iomem_high); 241 cil_context_to_policy(file_arr, NETIFCONS, iomemcon->context); 242 fprintf(file_arr[NETIFCONS], ";\n"); 243 } 244 245 return SEPOL_OK; 246 } 247 248 int cil_ioportcon_to_policy(FILE **file_arr, struct cil_sort *sort) 249 { 250 uint32_t i = 0; 251 252 for (i = 0; i < sort->count; i++) { 253 struct cil_ioportcon *ioportcon = (struct cil_ioportcon*)sort->array[i]; 254 fprintf(file_arr[NETIFCONS], "ioportcon %d-%d ", ioportcon->ioport_low, ioportcon->ioport_high); 255 cil_context_to_policy(file_arr, NETIFCONS, ioportcon->context); 256 fprintf(file_arr[NETIFCONS], ";\n"); 257 } 258 259 return SEPOL_OK; 260 } 261 262 int cil_pcidevicecon_to_policy(FILE **file_arr, struct cil_sort *sort) 263 { 264 uint32_t i = 0; 265 266 for (i = 0; i < sort->count; i++) { 267 struct cil_pcidevicecon *pcidevicecon = (struct cil_pcidevicecon*)sort->array[i]; 268 fprintf(file_arr[NETIFCONS], "pcidevicecon %d ", pcidevicecon->dev); 269 cil_context_to_policy(file_arr, NETIFCONS, pcidevicecon->context); 270 fprintf(file_arr[NETIFCONS], ";\n"); 271 } 272 273 return SEPOL_OK; 274 } 275 276 int cil_fsuse_to_policy(FILE **file_arr, struct cil_sort *sort) 277 { 278 uint32_t i = 0; 279 280 for (i=0; i<sort->count; i++) { 281 struct cil_fsuse *fsuse = (struct cil_fsuse*)sort->array[i]; 282 if (fsuse->type == CIL_FSUSE_XATTR) { 283 fprintf(file_arr[NETIFCONS], "fs_use_xattr "); 284 } else if (fsuse->type == CIL_FSUSE_TASK) { 285 fprintf(file_arr[NETIFCONS], "fs_use_task "); 286 } else if (fsuse->type == CIL_FSUSE_TRANS) { 287 fprintf(file_arr[NETIFCONS], "fs_use_trans "); 288 } else { 289 return SEPOL_ERR; 290 } 291 fprintf(file_arr[NETIFCONS], "%s ", fsuse->fs_str); 292 cil_context_to_policy(file_arr, NETIFCONS, fsuse->context); 293 fprintf(file_arr[NETIFCONS], ";\n"); 294 } 295 296 return SEPOL_OK; 297 } 298 299 int cil_multimap_insert(struct cil_list *list, struct cil_symtab_datum *key, struct cil_symtab_datum *value, uint32_t key_flavor, uint32_t val_flavor) 300 { 301 struct cil_list_item *curr_key; 302 struct cil_multimap_item *new_data; 303 304 if (list == NULL || key == NULL) { 305 return SEPOL_ERR; 306 } 307 308 cil_list_for_each(curr_key, list) { 309 struct cil_multimap_item *curr_multimap_item = curr_key->data; 310 if (curr_multimap_item != NULL) { 311 if (curr_multimap_item->key != NULL && curr_multimap_item->key == key) { 312 struct cil_list_item *curr_value; 313 cil_list_for_each(curr_value, curr_multimap_item->values) { 314 if (curr_value == (struct cil_list_item*)value) { 315 return SEPOL_OK;; 316 } 317 } 318 cil_list_append(curr_multimap_item->values, val_flavor, value); 319 } 320 } else { 321 cil_log(CIL_INFO, "No data in list item\n"); 322 return SEPOL_ERR; 323 } 324 } 325 326 new_data = cil_malloc(sizeof(*new_data)); 327 new_data->key = key; 328 cil_list_init(&new_data->values, CIL_LIST_ITEM); 329 if (value != NULL) { 330 cil_list_append(new_data->values, val_flavor, value); 331 } 332 cil_list_append(list, key_flavor, new_data); 333 334 return SEPOL_OK; 335 } 336 337 int cil_userrole_to_policy(FILE **file_arr, struct cil_list *userroles) 338 { 339 struct cil_list_item *current_user; 340 341 if (userroles == NULL) { 342 return SEPOL_OK; 343 } 344 345 cil_list_for_each(current_user, userroles) { 346 struct cil_multimap_item *user_multimap_item = current_user->data; 347 struct cil_list_item *current_role; 348 if (user_multimap_item->values->head == NULL) { 349 cil_log(CIL_INFO, "No roles associated with user %s\n", 350 user_multimap_item->key->name); 351 return SEPOL_ERR; 352 } 353 354 fprintf(file_arr[USERROLES], "user %s roles {", user_multimap_item->key->name); 355 356 cil_list_for_each(current_role, user_multimap_item->values) { 357 fprintf(file_arr[USERROLES], " %s", ((struct cil_role*)current_role->data)->datum.name); 358 } 359 fprintf(file_arr[USERROLES], " };\n"); 360 } 361 362 return SEPOL_OK; 363 } 364 365 int cil_cat_to_policy(FILE **file_arr, struct cil_list *cats) 366 { 367 struct cil_list_item *curr_cat; 368 369 if (cats == NULL) { 370 return SEPOL_OK; 371 } 372 373 cil_list_for_each(curr_cat, cats) { 374 struct cil_multimap_item *cat_multimap_item = curr_cat->data; 375 fprintf(file_arr[CATS], "category %s", cat_multimap_item->key->name); 376 if (cat_multimap_item->values->head == NULL) { 377 fprintf(file_arr[CATS], ";\n"); 378 } else { 379 struct cil_list_item *curr_catalias; 380 fprintf(file_arr[CATS], " alias"); 381 cil_list_for_each(curr_catalias, cat_multimap_item->values) { 382 fprintf(file_arr[CATS], " %s", ((struct cil_cat*)curr_catalias->data)->datum.name); 383 } 384 fprintf(file_arr[CATS], ";\n"); 385 } 386 } 387 388 return SEPOL_OK; 389 } 390 391 int cil_sens_to_policy(FILE **file_arr, struct cil_list *sens) 392 { 393 struct cil_list_item *curr_sens; 394 395 if (sens == NULL) { 396 return SEPOL_OK; 397 } 398 399 cil_list_for_each(curr_sens, sens) { 400 struct cil_multimap_item *sens_multimap_item = curr_sens->data; 401 fprintf(file_arr[SENS], "sensitivity %s", sens_multimap_item->key->name); 402 if (sens_multimap_item->values->head == NULL) 403 fprintf(file_arr[SENS], ";\n"); 404 else { 405 struct cil_list_item *curr_sensalias; 406 fprintf(file_arr[SENS], " alias"); 407 cil_list_for_each(curr_sensalias, sens_multimap_item->values) { 408 fprintf(file_arr[SENS], " %s", ((struct cil_sens*)curr_sensalias->data)->datum.name); 409 } 410 fprintf(file_arr[SENS], ";\n"); 411 } 412 } 413 414 return SEPOL_OK; 415 } 416 417 void cil_cats_to_policy(FILE **file_arr, uint32_t file_index, struct cil_cats *cats) 418 { 419 cil_expr_to_policy(file_arr, file_index, cats->datum_expr); 420 } 421 422 void cil_level_to_policy(FILE **file_arr, uint32_t file_index, struct cil_level *level) 423 { 424 char *sens_str = level->sens->datum.name; 425 426 fprintf(file_arr[file_index], "%s", sens_str); 427 if (level->cats != NULL) { 428 fprintf(file_arr[file_index], ":"); 429 cil_cats_to_policy(file_arr, file_index, level->cats); 430 } 431 } 432 433 void cil_levelrange_to_policy(FILE **file_arr, uint32_t file_index, struct cil_levelrange *lvlrange) 434 { 435 struct cil_level *low = lvlrange->low; 436 struct cil_level *high = lvlrange->high; 437 438 cil_level_to_policy(file_arr, file_index, low); 439 fprintf(file_arr[file_index], "-"); 440 cil_level_to_policy(file_arr, file_index, high); 441 } 442 443 void cil_context_to_policy(FILE **file_arr, uint32_t file_index, struct cil_context *context) 444 { 445 char *user_str = ((struct cil_symtab_datum*)context->user)->name; 446 char *role_str = ((struct cil_symtab_datum*)context->role)->name; 447 char *type_str = ((struct cil_symtab_datum*)context->type)->name; 448 struct cil_levelrange *lvlrange = context->range; 449 450 fprintf(file_arr[file_index], "%s:%s:%s:", user_str, role_str, type_str); 451 cil_levelrange_to_policy(file_arr, file_index, lvlrange); 452 } 453 454 void cil_perms_to_policy(FILE **file_arr, uint32_t file_index, struct cil_list *list) 455 { 456 struct cil_list_item *curr; 457 458 fprintf(file_arr[file_index], " {"); 459 cil_list_for_each(curr, list) { 460 switch (curr->flavor) { 461 case CIL_LIST: 462 cil_perms_to_policy(file_arr, file_index, curr->data); 463 break; 464 case CIL_STRING: 465 fprintf(file_arr[file_index], " %s", (char *)curr->data); 466 break; 467 case CIL_DATUM: 468 fprintf(file_arr[file_index], " %s", ((struct cil_symtab_datum *)curr->data)->name); 469 break; 470 case CIL_OP: { 471 enum cil_flavor op_flavor = *((enum cil_flavor *)curr->data); 472 char *op_str = NULL; 473 474 switch (op_flavor) { 475 case CIL_AND: 476 op_str = CIL_KEY_AND; 477 break; 478 case CIL_OR: 479 op_str = CIL_KEY_OR; 480 break; 481 case CIL_NOT: 482 op_str = CIL_KEY_NOT; 483 break; 484 case CIL_ALL: 485 op_str = CIL_KEY_ALL; 486 break; 487 case CIL_XOR: 488 op_str = CIL_KEY_XOR; 489 break; 490 default: 491 cil_log(CIL_ERR, "Unknown operator in expression\n"); 492 break; 493 } 494 fprintf(file_arr[file_index], " %s", op_str); 495 break; 496 } 497 default: 498 cil_log(CIL_ERR, "Unknown flavor in expression\n"); 499 break; 500 } 501 } 502 fprintf(file_arr[file_index], " }"); 503 } 504 505 void cil_constrain_to_policy_helper(FILE **file_arr, char *kind, struct cil_list *classperms, struct cil_list *expr) 506 { 507 struct cil_list_item *curr; 508 509 cil_list_for_each(curr, classperms) { 510 if (curr->flavor == CIL_CLASSPERMS) { 511 struct cil_classperms *cp = curr->data; 512 if (FLAVOR(cp->class) == CIL_CLASS) { 513 fprintf(file_arr[CONSTRAINS], "%s %s", kind, cp->class->datum.name); 514 cil_perms_to_policy(file_arr, CONSTRAINS, cp->perms); 515 fprintf(file_arr[CONSTRAINS], "\n\t"); 516 cil_expr_to_policy(file_arr, CONSTRAINS, expr); 517 fprintf(file_arr[CONSTRAINS], ";\n"); 518 } else { /* MAP */ 519 struct cil_list_item *i = NULL; 520 cil_list_for_each(i, cp->perms) { 521 struct cil_perm *cmp = i->data; 522 cil_constrain_to_policy_helper(file_arr, kind, cmp->classperms, expr); 523 } 524 } 525 } else { /* SET */ 526 struct cil_classperms_set *cp_set = curr->data; 527 struct cil_classpermission *cp = cp_set->set; 528 cil_constrain_to_policy_helper(file_arr, kind, cp->classperms, expr); 529 } 530 } 531 } 532 533 void cil_constrain_to_policy(FILE **file_arr, __attribute__((unused)) uint32_t file_index, struct cil_constrain *cons, enum cil_flavor flavor) 534 { 535 char *kind = NULL; 536 537 if (flavor == CIL_CONSTRAIN) { 538 kind = CIL_KEY_CONSTRAIN; 539 } else if (flavor == CIL_MLSCONSTRAIN) { 540 kind = CIL_KEY_MLSCONSTRAIN; 541 } 542 543 cil_constrain_to_policy_helper(file_arr, kind, cons->classperms, cons->datum_expr); 544 } 545 546 void cil_avrule_to_policy_helper(FILE **file_arr, uint32_t file_index, const char *kind, const char *src, const char *tgt, struct cil_list *classperms) 547 { 548 struct cil_list_item *i; 549 550 cil_list_for_each(i, classperms) { 551 if (i->flavor == CIL_CLASSPERMS) { 552 struct cil_classperms *cp = i->data; 553 if (FLAVOR(cp->class) == CIL_CLASS) { 554 fprintf(file_arr[file_index], "%s %s %s: %s", kind, src, tgt, cp->class->datum.name); 555 cil_perms_to_policy(file_arr, file_index, cp->perms); 556 fprintf(file_arr[file_index], ";\n"); 557 } else { /* MAP */ 558 struct cil_list_item *j = NULL; 559 cil_list_for_each(j, cp->perms) { 560 struct cil_perm *cmp = j->data; 561 cil_avrule_to_policy_helper(file_arr, file_index, kind, src, tgt, cmp->classperms); 562 } 563 } 564 } else { /* SET */ 565 struct cil_list_item *j; 566 struct cil_classperms_set *cp_set = i->data; 567 struct cil_classpermission *cp = cp_set->set; 568 cil_list_for_each(j, cp->classperms) { 569 cil_avrule_to_policy_helper(file_arr, file_index, kind, src, tgt, j->data); 570 } 571 } 572 } 573 } 574 575 int cil_avrule_to_policy(FILE **file_arr, uint32_t file_index, struct cil_avrule *rule) 576 { 577 const char *kind_str = NULL; 578 const char *src_str = DATUM(rule->src)->name; 579 const char *tgt_str = DATUM(rule->tgt)->name; 580 581 582 switch (rule->rule_kind) { 583 case CIL_AVRULE_ALLOWED: 584 kind_str = "allow"; 585 break; 586 case CIL_AVRULE_AUDITALLOW: 587 kind_str = "auditallow"; 588 break; 589 case CIL_AVRULE_DONTAUDIT: 590 kind_str = "dontaudit"; 591 break; 592 case CIL_AVRULE_NEVERALLOW: 593 kind_str = "neverallow"; 594 break; 595 default : 596 cil_log(CIL_INFO, "Unknown avrule with kind=%d src=%s tgt=%s\n", 597 rule->rule_kind, src_str, tgt_str); 598 return SEPOL_ERR; 599 } 600 601 cil_avrule_to_policy_helper(file_arr, file_index, kind_str, src_str, tgt_str, rule->classperms); 602 603 return SEPOL_OK; 604 } 605 606 int cil_typerule_to_policy(FILE **file_arr, __attribute__((unused)) uint32_t file_index, struct cil_type_rule *rule) 607 { 608 char *src_str = ((struct cil_symtab_datum*)rule->src)->name; 609 char *tgt_str = ((struct cil_symtab_datum*)rule->tgt)->name; 610 char *obj_str = ((struct cil_symtab_datum*)rule->obj)->name; 611 char *result_str = ((struct cil_symtab_datum*)rule->result)->name; 612 613 switch (rule->rule_kind) { 614 case CIL_TYPE_TRANSITION: 615 fprintf(file_arr[ALLOWS], "type_transition %s %s : %s %s;\n", src_str, tgt_str, obj_str, result_str); 616 break; 617 case CIL_TYPE_CHANGE: 618 fprintf(file_arr[ALLOWS], "type_change %s %s : %s %s\n;", src_str, tgt_str, obj_str, result_str); 619 break; 620 case CIL_TYPE_MEMBER: 621 fprintf(file_arr[ALLOWS], "type_member %s %s : %s %s;\n", src_str, tgt_str, obj_str, result_str); 622 break; 623 default: 624 cil_log(CIL_INFO, "Unknown type_rule\n"); 625 return SEPOL_ERR; 626 } 627 628 return SEPOL_OK; 629 } 630 631 int cil_nametypetransition_to_policy(FILE **file_arr, uint32_t file_index, struct cil_nametypetransition *nametypetrans) 632 { 633 char *src_str = ((struct cil_symtab_datum*)nametypetrans->src)->name; 634 char *tgt_str = ((struct cil_symtab_datum*)nametypetrans->tgt)->name; 635 char *obj_str = ((struct cil_symtab_datum*)nametypetrans->obj)->name; 636 char *result_str = ((struct cil_symtab_datum*)nametypetrans->result)->name; 637 638 fprintf(file_arr[file_index], "type_transition %s %s : %s %s %s;\n", src_str, tgt_str, obj_str, result_str, nametypetrans->name_str); 639 return SEPOL_OK; 640 } 641 642 static int cil_expr_to_string(struct cil_list *expr, char **out) 643 { 644 int rc = SEPOL_ERR; 645 struct cil_list_item *curr; 646 char *stack[COND_EXPR_MAXDEPTH] = {}; 647 int pos = 0; 648 int i; 649 650 cil_list_for_each(curr, expr) { 651 if (pos > COND_EXPR_MAXDEPTH) { 652 rc = SEPOL_ERR; 653 goto exit; 654 } 655 switch (curr->flavor) { 656 case CIL_LIST: 657 rc = cil_expr_to_string(curr->data, &stack[pos]); 658 if (rc != SEPOL_OK) { 659 goto exit; 660 } 661 pos++; 662 break; 663 case CIL_STRING: 664 stack[pos] = curr->data; 665 pos++; 666 break; 667 case CIL_DATUM: 668 stack[pos] = ((struct cil_symtab_datum *)curr->data)->name; 669 pos++; 670 break; 671 case CIL_OP: { 672 int len; 673 char *expr_str; 674 enum cil_flavor op_flavor = *((enum cil_flavor *)curr->data); 675 char *op_str = NULL; 676 677 if (pos == 0) { 678 rc = SEPOL_ERR; 679 goto exit; 680 } 681 switch (op_flavor) { 682 case CIL_AND: 683 op_str = CIL_KEY_AND; 684 break; 685 case CIL_OR: 686 op_str = CIL_KEY_OR; 687 break; 688 case CIL_NOT: 689 op_str = CIL_KEY_NOT; 690 break; 691 case CIL_ALL: 692 op_str = CIL_KEY_ALL; 693 break; 694 case CIL_EQ: 695 op_str = CIL_KEY_EQ; 696 break; 697 case CIL_NEQ: 698 op_str = CIL_KEY_NEQ; 699 break; 700 case CIL_XOR: 701 op_str = CIL_KEY_XOR; 702 break; 703 case CIL_CONS_DOM: 704 op_str = CIL_KEY_CONS_DOM; 705 break; 706 case CIL_CONS_DOMBY: 707 op_str = CIL_KEY_CONS_DOMBY; 708 break; 709 case CIL_CONS_INCOMP: 710 op_str = CIL_KEY_CONS_INCOMP; 711 break; 712 default: 713 cil_log(CIL_ERR, "Unknown operator in expression\n"); 714 goto exit; 715 break; 716 } 717 if (op_flavor == CIL_NOT) { 718 len = strlen(stack[pos-1]) + strlen(op_str) + 4; 719 expr_str = cil_malloc(len); 720 snprintf(expr_str, len, "(%s %s)", op_str, stack[pos-1]); 721 free(stack[pos-1]); 722 stack[pos-1] = NULL; 723 pos--; 724 } else { 725 if (pos < 2) { 726 rc = SEPOL_ERR; 727 goto exit; 728 } 729 len = strlen(stack[pos-1]) + strlen(stack[pos-2]) + strlen(op_str) + 5; 730 expr_str = cil_malloc(len); 731 snprintf(expr_str, len, "(%s %s %s)", stack[pos-1], op_str, stack[pos-2]); 732 free(stack[pos-2]); 733 free(stack[pos-1]); 734 stack[pos-2] = NULL; 735 stack[pos-1] = NULL; 736 pos -= 2; 737 } 738 stack[pos] = expr_str; 739 pos++; 740 break; 741 } 742 case CIL_CONS_OPERAND: { 743 enum cil_flavor operand_flavor = *((enum cil_flavor *)curr->data); 744 char *operand_str = NULL; 745 switch (operand_flavor) { 746 case CIL_CONS_U1: 747 operand_str = CIL_KEY_CONS_U1; 748 break; 749 case CIL_CONS_U2: 750 operand_str = CIL_KEY_CONS_U2; 751 break; 752 case CIL_CONS_U3: 753 operand_str = CIL_KEY_CONS_U3; 754 break; 755 case CIL_CONS_T1: 756 operand_str = CIL_KEY_CONS_T1; 757 break; 758 case CIL_CONS_T2: 759 operand_str = CIL_KEY_CONS_T2; 760 break; 761 case CIL_CONS_T3: 762 operand_str = CIL_KEY_CONS_T3; 763 break; 764 case CIL_CONS_R1: 765 operand_str = CIL_KEY_CONS_R1; 766 break; 767 case CIL_CONS_R2: 768 operand_str = CIL_KEY_CONS_R2; 769 break; 770 case CIL_CONS_R3: 771 operand_str = CIL_KEY_CONS_R3; 772 break; 773 case CIL_CONS_L1: 774 operand_str = CIL_KEY_CONS_L1; 775 break; 776 case CIL_CONS_L2: 777 operand_str = CIL_KEY_CONS_L2; 778 break; 779 case CIL_CONS_H1: 780 operand_str = CIL_KEY_CONS_H1; 781 break; 782 case CIL_CONS_H2: 783 operand_str = CIL_KEY_CONS_H2; 784 break; 785 default: 786 cil_log(CIL_ERR, "Unknown operand in expression\n"); 787 goto exit; 788 break; 789 } 790 stack[pos] = operand_str; 791 pos++; 792 break; 793 } 794 default: 795 cil_log(CIL_ERR, "Unknown flavor in expression\n"); 796 goto exit; 797 break; 798 } 799 } 800 801 *out = stack[0]; 802 803 return SEPOL_OK; 804 805 exit: 806 for (i = 0; i < pos; i++) { 807 free(stack[i]); 808 } 809 return rc; 810 } 811 812 int cil_expr_to_policy(FILE **file_arr, uint32_t file_index, struct cil_list *expr) 813 { 814 int rc = SEPOL_ERR; 815 char *str_out; 816 817 rc = cil_expr_to_string(expr, &str_out); 818 if (rc != SEPOL_OK) { 819 goto out; 820 } 821 fprintf(file_arr[file_index], "%s", str_out); 822 free(str_out); 823 824 return SEPOL_OK; 825 826 out: 827 return rc; 828 } 829 830 int __cil_booleanif_node_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args) 831 { 832 int rc = SEPOL_ERR; 833 struct cil_args_booleanif *args; 834 FILE **file_arr; 835 uint32_t *file_index; 836 837 args = extra_args; 838 file_arr = args->file_arr; 839 file_index = args->file_index; 840 841 switch (node->flavor) { 842 case CIL_AVRULE: 843 rc = cil_avrule_to_policy(file_arr, *file_index, (struct cil_avrule*)node->data); 844 if (rc != SEPOL_OK) { 845 cil_log(CIL_INFO, "cil_avrule_to_policy failed, rc: %d\n", rc); 846 return rc; 847 } 848 break; 849 case CIL_TYPE_RULE: 850 rc = cil_typerule_to_policy(file_arr, *file_index, (struct cil_type_rule*)node->data); 851 if (rc != SEPOL_OK) { 852 cil_log(CIL_INFO, "cil_typerule_to_policy failed, rc: %d\n", rc); 853 return rc; 854 } 855 break; 856 case CIL_FALSE: 857 fprintf(file_arr[*file_index], "else {\n"); 858 break; 859 case CIL_TRUE: 860 break; 861 default: 862 return SEPOL_ERR; 863 } 864 865 return SEPOL_OK; 866 } 867 868 int __cil_booleanif_last_child_helper(struct cil_tree_node *node, void *extra_args) 869 { 870 struct cil_args_booleanif *args; 871 FILE **file_arr; 872 uint32_t *file_index; 873 874 args = extra_args; 875 file_arr = args->file_arr; 876 file_index = args->file_index; 877 878 if (node->parent->flavor == CIL_FALSE) { 879 fprintf(file_arr[*file_index], "}\n"); 880 } 881 882 return SEPOL_OK; 883 } 884 885 int cil_booleanif_to_policy(FILE **file_arr, uint32_t file_index, struct cil_tree_node *node) 886 { 887 int rc = SEPOL_ERR; 888 struct cil_booleanif *bif = node->data; 889 struct cil_list *expr = bif->datum_expr; 890 struct cil_args_booleanif extra_args; 891 struct cil_tree_node *true_node = NULL; 892 struct cil_tree_node *false_node = NULL; 893 struct cil_condblock *cb = NULL; 894 895 extra_args.file_arr = file_arr; 896 extra_args.file_index = &file_index;; 897 898 fprintf(file_arr[file_index], "if "); 899 900 rc = cil_expr_to_policy(file_arr, file_index, expr); 901 if (rc != SEPOL_OK) { 902 cil_log(CIL_ERR, "Failed to write expression\n"); 903 return rc; 904 } 905 906 if (node->cl_head != NULL && node->cl_head->flavor == CIL_CONDBLOCK) { 907 cb = node->cl_head->data; 908 if (cb->flavor == CIL_CONDTRUE) { 909 true_node = node->cl_head; 910 } else if (cb->flavor == CIL_CONDFALSE) { 911 false_node = node->cl_head; 912 } 913 } 914 915 if (node->cl_head != NULL && node->cl_head->next != NULL && node->cl_head->next->flavor == CIL_CONDBLOCK) { 916 cb = node->cl_head->next->data; 917 if (cb->flavor == CIL_CONDTRUE) { 918 true_node = node->cl_head->next; 919 } else if (cb->flavor == CIL_CONDFALSE) { 920 false_node = node->cl_head->next; 921 } 922 } 923 924 fprintf(file_arr[file_index], "{\n"); 925 if (true_node != NULL) { 926 rc = cil_tree_walk(true_node, __cil_booleanif_node_helper, __cil_booleanif_last_child_helper, NULL, &extra_args); 927 if (rc != SEPOL_OK) { 928 cil_log(CIL_INFO, "Failed to write booleanif content to file, rc: %d\n", rc); 929 return rc; 930 } 931 } 932 fprintf(file_arr[file_index], "}\n"); 933 934 if (false_node != NULL) { 935 fprintf(file_arr[file_index], "else {\n"); 936 rc = cil_tree_walk(false_node, __cil_booleanif_node_helper, __cil_booleanif_last_child_helper, NULL, &extra_args); 937 if (rc != SEPOL_OK) { 938 cil_log(CIL_INFO, "Failed to write booleanif false content to file, rc: %d\n", rc); 939 return rc; 940 } 941 fprintf(file_arr[file_index], "}\n"); 942 } 943 944 return SEPOL_OK; 945 } 946 947 int cil_name_to_policy(FILE **file_arr, struct cil_tree_node *current) 948 { 949 uint32_t flavor = current->flavor; 950 int rc = SEPOL_ERR; 951 952 switch(flavor) { 953 case CIL_TYPEATTRIBUTE: 954 fprintf(file_arr[TYPEATTRTYPES], "attribute %s;\n", ((struct cil_symtab_datum*)current->data)->name); 955 break; 956 case CIL_TYPE: 957 fprintf(file_arr[TYPEATTRTYPES], "type %s;\n", ((struct cil_symtab_datum*)current->data)->name); 958 break; 959 case CIL_TYPEALIAS: { 960 struct cil_alias *alias = current->data; 961 fprintf(file_arr[ALIASES], "typealias %s alias %s;\n", ((struct cil_symtab_datum*)alias->actual)->name, ((struct cil_symtab_datum*)current->data)->name); 962 break; 963 } 964 case CIL_TYPEBOUNDS: { 965 struct cil_bounds *bnds = current->data; 966 fprintf(file_arr[ALLOWS], "typebounds %s %s;\n", bnds->parent_str, bnds->child_str); 967 break; 968 } 969 case CIL_TYPEPERMISSIVE: { 970 struct cil_typepermissive *typeperm = (struct cil_typepermissive*)current->data; 971 fprintf(file_arr[TYPEATTRTYPES], "permissive %s;\n", ((struct cil_symtab_datum*)typeperm->type)->name); 972 break; 973 } 974 case CIL_ROLE: 975 fprintf(file_arr[TYPEATTRTYPES], "role %s;\n", ((struct cil_symtab_datum*)current->data)->name); 976 break; 977 case CIL_BOOL: { 978 const char *boolean = ((struct cil_bool*)current->data)->value ? "true" : "false"; 979 fprintf(file_arr[TYPEATTRTYPES], "bool %s %s;\n", ((struct cil_symtab_datum*)current->data)->name, boolean); 980 break; 981 } 982 case CIL_COMMON: 983 fprintf(file_arr[COMMONS], "common %s", ((struct cil_symtab_datum*)current->data)->name); 984 985 if (current->cl_head != NULL) { 986 current = current->cl_head; 987 fprintf(file_arr[COMMONS], " {"); 988 } else { 989 cil_log(CIL_INFO, "No permissions given\n"); 990 return SEPOL_ERR; 991 } 992 993 while (current != NULL) { 994 if (current->flavor == CIL_PERM) { 995 fprintf(file_arr[COMMONS], "%s ", ((struct cil_symtab_datum*)current->data)->name); 996 } else { 997 cil_log(CIL_INFO, "Improper data type found in common permissions: %d\n", current->flavor); 998 return SEPOL_ERR; 999 } 1000 current = current->next; 1001 } 1002 fprintf(file_arr[COMMONS], "}\n"); 1003 1004 return SEPOL_DONE; 1005 case CIL_AVRULE: { 1006 struct cil_avrule *avrule = (struct cil_avrule*)current->data; 1007 rc = cil_avrule_to_policy(file_arr, ALLOWS, avrule); 1008 if (rc != SEPOL_OK) { 1009 cil_log(CIL_INFO, "Failed to write avrule to policy\n"); 1010 return rc; 1011 } 1012 break; 1013 } 1014 case CIL_TYPE_RULE: { 1015 struct cil_type_rule *rule = (struct cil_type_rule*)current->data; 1016 rc = cil_typerule_to_policy(file_arr, ALLOWS, rule); 1017 if (rc != SEPOL_OK) { 1018 cil_log(CIL_INFO, "Failed to write type rule to policy\n"); 1019 return rc; 1020 } 1021 break; 1022 } 1023 case CIL_NAMETYPETRANSITION: { 1024 struct cil_nametypetransition *nametypetrans = (struct cil_nametypetransition*)current->data; 1025 rc = cil_nametypetransition_to_policy(file_arr, ALLOWS, nametypetrans); 1026 if (rc != SEPOL_OK) { 1027 cil_log(CIL_INFO, "Failed to write nametypetransition to policy\n"); 1028 return rc; 1029 } 1030 } 1031 case CIL_ROLETRANSITION: { 1032 struct cil_roletransition *roletrans = (struct cil_roletransition*)current->data; 1033 char *src_str = ((struct cil_symtab_datum*)roletrans->src)->name; 1034 char *tgt_str = ((struct cil_symtab_datum*)roletrans->tgt)->name; 1035 char *obj_str = ((struct cil_symtab_datum*)roletrans->obj)->name; 1036 char *result_str = ((struct cil_symtab_datum*)roletrans->result)->name; 1037 1038 fprintf(file_arr[ALLOWS], "role_transition %s %s:%s %s;\n", src_str, tgt_str, obj_str, result_str); 1039 break; 1040 } 1041 case CIL_ROLEALLOW: { 1042 struct cil_roleallow *roleallow = (struct cil_roleallow*)current->data; 1043 char *src_str = ((struct cil_symtab_datum*)roleallow->src)->name; 1044 char *tgt_str = ((struct cil_symtab_datum*)roleallow->tgt)->name; 1045 1046 fprintf(file_arr[ALLOWS], "roleallow %s %s;\n", src_str, tgt_str); 1047 break; 1048 } 1049 case CIL_ROLETYPE: { 1050 struct cil_roletype *roletype = (struct cil_roletype*)current->data; 1051 char *role_str = ((struct cil_symtab_datum*)roletype->role)->name; 1052 char *type_str = ((struct cil_symtab_datum*)roletype->type)->name; 1053 1054 fprintf(file_arr[ALIASES], "role %s types %s\n", role_str, type_str); 1055 break; 1056 } 1057 case CIL_LEVEL: 1058 fprintf(file_arr[LEVELS], "level "); 1059 cil_level_to_policy(file_arr, LEVELS, (struct cil_level*)current->data); 1060 fprintf(file_arr[LEVELS], ";\n"); 1061 break; 1062 case CIL_CONSTRAIN: 1063 cil_constrain_to_policy(file_arr, CONSTRAINS, (struct cil_constrain*)current->data, flavor); 1064 break; 1065 case CIL_MLSCONSTRAIN: 1066 cil_constrain_to_policy(file_arr, CONSTRAINS, (struct cil_constrain*)current->data, flavor); 1067 break; 1068 case CIL_VALIDATETRANS: { 1069 struct cil_validatetrans *vt = current->data; 1070 fprintf(file_arr[CONSTRAINS], "validatetrans"); 1071 fprintf(file_arr[CONSTRAINS], " %s ", ((struct cil_class*)vt->class)->datum.name); 1072 cil_expr_to_policy(file_arr, CONSTRAINS, vt->datum_expr); 1073 fprintf(file_arr[CONSTRAINS], ";\n"); 1074 break; 1075 } 1076 case CIL_MLSVALIDATETRANS: { 1077 struct cil_validatetrans *vt = current->data; 1078 fprintf(file_arr[CONSTRAINS], "mlsvalidatetrans"); 1079 fprintf(file_arr[CONSTRAINS], " %s " , ((struct cil_class*)vt->class)->datum.name); 1080 cil_expr_to_policy(file_arr, CONSTRAINS, vt->datum_expr); 1081 fprintf(file_arr[CONSTRAINS], ";\n"); 1082 break; 1083 } 1084 case CIL_SID: 1085 fprintf(file_arr[ISIDS], "sid %s\n", ((struct cil_symtab_datum*)current->data)->name); 1086 break; 1087 case CIL_SIDCONTEXT: { 1088 struct cil_sidcontext *sidcon = (struct cil_sidcontext*)current->data; 1089 fprintf(file_arr[SIDS], "sid %s ", sidcon->sid_str); 1090 cil_context_to_policy(file_arr, SIDS, sidcon->context); 1091 fprintf(file_arr[SIDS], "\n"); 1092 break; 1093 } 1094 case CIL_POLICYCAP: 1095 fprintf(file_arr[TYPEATTRTYPES], "policycap %s;\n", ((struct cil_symtab_datum*)current->data)->name); 1096 break; 1097 default: 1098 break; 1099 } 1100 1101 return SEPOL_OK; 1102 } 1103 1104 int __cil_gen_policy_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 1105 { 1106 int rc = SEPOL_ERR; 1107 struct cil_args_genpolicy *args = NULL; 1108 struct cil_list *users = NULL; 1109 struct cil_list *sens = NULL; 1110 struct cil_list *cats = NULL; 1111 FILE **file_arr = NULL; 1112 1113 if (extra_args == NULL) { 1114 return SEPOL_ERR; 1115 } 1116 1117 *finished = CIL_TREE_SKIP_NOTHING; 1118 1119 args = extra_args; 1120 users = args->users; 1121 sens = args->sens; 1122 cats = args->cats; 1123 file_arr = args->file_arr; 1124 1125 if (node->cl_head != NULL) { 1126 if (node->flavor == CIL_MACRO) { 1127 *finished = CIL_TREE_SKIP_HEAD; 1128 return SEPOL_OK; 1129 } 1130 1131 if (node->flavor == CIL_BOOLEANIF) { 1132 rc = cil_booleanif_to_policy(file_arr, CONDS, node); 1133 if (rc != SEPOL_OK) { 1134 cil_log(CIL_INFO, "Failed to write booleanif contents to file\n"); 1135 return rc; 1136 } 1137 *finished = CIL_TREE_SKIP_HEAD; 1138 return SEPOL_OK; 1139 } 1140 1141 if (node->flavor == CIL_BLOCK && ((struct cil_block*)node->data)->is_abstract == CIL_TRUE) { 1142 *finished = CIL_TREE_SKIP_HEAD; 1143 return SEPOL_OK; 1144 } 1145 1146 if (node->flavor != CIL_ROOT) { 1147 rc = cil_name_to_policy(file_arr, node); 1148 if (rc != SEPOL_OK && rc != SEPOL_DONE) { 1149 cil_log(CIL_ERR, "Error converting node to policy %d\n", node->flavor); 1150 return SEPOL_ERR; 1151 } 1152 } 1153 } else { 1154 switch (node->flavor) { 1155 case CIL_USER: 1156 cil_multimap_insert(users, node->data, NULL, CIL_USERROLE, CIL_NONE); 1157 break; 1158 case CIL_USERROLE: { 1159 struct cil_userrole *userrole = node->data; 1160 cil_multimap_insert(users, &userrole->user->datum, (struct cil_symtab_datum *)userrole->role, CIL_USERROLE, CIL_ROLE); 1161 } 1162 break; 1163 case CIL_CATALIAS: { 1164 struct cil_alias *alias = node->data; 1165 struct cil_symtab_datum *datum = alias->actual; 1166 cil_multimap_insert(cats, datum, node->data, CIL_CAT, CIL_CATALIAS); 1167 } 1168 break; 1169 case CIL_SENSALIAS: { 1170 struct cil_alias *alias = node->data; 1171 struct cil_symtab_datum *datum = alias->actual; 1172 cil_multimap_insert(sens, datum, node->data, CIL_SENS, CIL_SENSALIAS); 1173 } 1174 break; 1175 default: 1176 rc = cil_name_to_policy(file_arr, node); 1177 if (rc != SEPOL_OK && rc != SEPOL_DONE) { 1178 cil_log(CIL_ERR, "Error converting node to policy %d\n", rc); 1179 return SEPOL_ERR; 1180 } 1181 break; 1182 } 1183 } 1184 1185 return SEPOL_OK; 1186 } 1187 1188 int cil_gen_policy(struct cil_db *db) 1189 { 1190 struct cil_tree_node *curr = db->ast->root; 1191 struct cil_list_item *item; 1192 int rc = SEPOL_ERR; 1193 FILE *policy_file; 1194 FILE **file_arr = cil_malloc(sizeof(FILE*) * NUM_POLICY_FILES); 1195 char *file_path_arr[NUM_POLICY_FILES]; 1196 char temp[32]; 1197 1198 struct cil_list *users = NULL; 1199 struct cil_list *cats = NULL; 1200 struct cil_list *sens = NULL; 1201 struct cil_args_genpolicy extra_args; 1202 1203 cil_list_init(&users, CIL_LIST_ITEM); 1204 cil_list_init(&cats, CIL_LIST_ITEM); 1205 cil_list_init(&sens, CIL_LIST_ITEM); 1206 1207 strcpy(temp, "/tmp/cil_classdecl-XXXXXX"); 1208 file_arr[CLASS_DECL] = fdopen(mkstemp(temp), "w+"); 1209 file_path_arr[CLASS_DECL] = cil_strpool_add(temp); 1210 1211 strcpy(temp, "/tmp/cil_isids-XXXXXX"); 1212 file_arr[ISIDS] = fdopen(mkstemp(temp), "w+"); 1213 file_path_arr[ISIDS] = cil_strpool_add(temp); 1214 1215 strcpy(temp,"/tmp/cil_common-XXXXXX"); 1216 file_arr[COMMONS] = fdopen(mkstemp(temp), "w+"); 1217 file_path_arr[COMMONS] = cil_strpool_add(temp); 1218 1219 strcpy(temp, "/tmp/cil_class-XXXXXX"); 1220 file_arr[CLASSES] = fdopen(mkstemp(temp), "w+"); 1221 file_path_arr[CLASSES] = cil_strpool_add(temp); 1222 1223 strcpy(temp, "/tmp/cil_interf-XXXXXX"); 1224 file_arr[INTERFACES] = fdopen(mkstemp(temp), "w+"); 1225 file_path_arr[INTERFACES] = cil_strpool_add(temp); 1226 1227 strcpy(temp, "/tmp/cil_sens-XXXXXX"); 1228 file_arr[SENS] = fdopen(mkstemp(temp), "w+"); 1229 file_path_arr[SENS] = cil_strpool_add(temp); 1230 1231 strcpy(temp, "/tmp/cil_cats-XXXXXX"); 1232 file_arr[CATS] = fdopen(mkstemp(temp), "w+"); 1233 file_path_arr[CATS] = cil_strpool_add(temp); 1234 1235 strcpy(temp, "/tmp/cil_levels-XXXXXX"); 1236 file_arr[LEVELS] = fdopen(mkstemp(temp), "w+"); 1237 file_path_arr[LEVELS] = cil_strpool_add(temp); 1238 1239 strcpy(temp, "/tmp/cil_mlscon-XXXXXX"); 1240 file_arr[CONSTRAINS] = fdopen(mkstemp(temp), "w+"); 1241 file_path_arr[CONSTRAINS] = cil_strpool_add(temp); 1242 1243 strcpy(temp, "/tmp/cil_attrtypes-XXXXXX"); 1244 file_arr[TYPEATTRTYPES] = fdopen(mkstemp(temp), "w+"); 1245 file_path_arr[TYPEATTRTYPES] = cil_strpool_add(temp); 1246 1247 strcpy(temp, "/tmp/cil_aliases-XXXXXX"); 1248 file_arr[ALIASES] = fdopen(mkstemp(temp), "w+"); 1249 file_path_arr[ALIASES] = cil_strpool_add(temp); 1250 1251 strcpy(temp, "/tmp/cil_allows-XXXXXX"); 1252 file_arr[ALLOWS] = fdopen(mkstemp(temp), "w+"); 1253 file_path_arr[ALLOWS] = cil_strpool_add(temp); 1254 1255 strcpy(temp, "/tmp/cil_conds-XXXXXX"); 1256 file_arr[CONDS] = fdopen(mkstemp(temp), "w+"); 1257 file_path_arr[CONDS] = cil_strpool_add(temp); 1258 1259 strcpy(temp, "/tmp/cil_userroles-XXXXXX"); 1260 file_arr[USERROLES] = fdopen(mkstemp(temp), "w+"); 1261 file_path_arr[USERROLES] = cil_strpool_add(temp); 1262 1263 strcpy(temp, "/tmp/cil_sids-XXXXXX"); 1264 file_arr[SIDS] = fdopen(mkstemp(temp), "w+"); 1265 file_path_arr[SIDS] = cil_strpool_add(temp); 1266 1267 strcpy(temp, "/tmp/cil_netifcons-XXXXXX"); 1268 file_arr[NETIFCONS] = fdopen(mkstemp(temp), "w+"); 1269 file_path_arr[NETIFCONS] = cil_strpool_add(temp); 1270 1271 policy_file = fopen("policy.conf", "w+"); 1272 1273 cil_list_for_each(item, db->sidorder) { 1274 fprintf(file_arr[ISIDS], "sid %s ", ((struct cil_sid*)item->data)->datum.name); 1275 } 1276 1277 cil_list_for_each(item, db->classorder) { 1278 struct cil_class *class = item->data; 1279 struct cil_tree_node *node = class->datum.nodes->head->data; 1280 1281 fprintf(file_arr[CLASS_DECL], "class %s\n", class->datum.name); 1282 1283 fprintf(file_arr[CLASSES], "class %s ", class->datum.name); 1284 if (class->common != NULL) { 1285 fprintf(file_arr[CLASSES], "inherits %s ", class->common->datum.name); 1286 } 1287 if (node->cl_head != NULL) { 1288 struct cil_tree_node *curr_perm = node->cl_head; 1289 fprintf(file_arr[CLASSES], "{ "); 1290 while (curr_perm != NULL) { 1291 fprintf(file_arr[CLASSES], "%s ", ((struct cil_symtab_datum*)curr_perm->data)->name); 1292 curr_perm = curr_perm->next; 1293 } 1294 fprintf(file_arr[CLASSES], "}"); 1295 } 1296 fprintf(file_arr[CLASSES], "\n"); 1297 } 1298 1299 if (db->catorder->head != NULL) { 1300 cil_list_for_each(item, db->catorder) { 1301 cil_multimap_insert(cats, item->data, NULL, CIL_CAT, 0); 1302 } 1303 } 1304 1305 if (db->sensitivityorder->head != NULL) { 1306 fprintf(file_arr[SENS], "sensitivityorder { "); 1307 cil_list_for_each(item, db->sensitivityorder) { 1308 fprintf(file_arr[SENS], "%s ", ((struct cil_sens*)item->data)->datum.name); 1309 } 1310 fprintf(file_arr[SENS], "};\n"); 1311 } 1312 1313 extra_args.users = users; 1314 extra_args.sens = sens; 1315 extra_args.cats = cats; 1316 extra_args.file_arr= file_arr; 1317 1318 rc = cil_tree_walk(curr, __cil_gen_policy_node_helper, NULL, NULL, &extra_args); 1319 if (rc != SEPOL_OK) { 1320 cil_log(CIL_ERR, "Error walking tree\n"); 1321 return rc; 1322 } 1323 1324 rc = cil_netifcon_to_policy(file_arr, db->netifcon); 1325 if (rc != SEPOL_OK) { 1326 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1327 return rc; 1328 } 1329 1330 rc = cil_genfscon_to_policy(file_arr, db->genfscon); 1331 if (rc != SEPOL_OK) { 1332 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1333 return rc; 1334 } 1335 1336 rc = cil_portcon_to_policy(file_arr, db->portcon); 1337 if (rc != SEPOL_OK) { 1338 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1339 return rc; 1340 } 1341 1342 rc = cil_nodecon_to_policy(file_arr, db->nodecon); 1343 if (rc != SEPOL_OK) { 1344 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1345 return rc; 1346 } 1347 1348 rc = cil_fsuse_to_policy(file_arr, db->fsuse); 1349 if (rc != SEPOL_OK) { 1350 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1351 return rc; 1352 } 1353 1354 rc = cil_pirqcon_to_policy(file_arr, db->pirqcon); 1355 if (rc != SEPOL_OK) { 1356 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1357 return rc; 1358 } 1359 1360 rc = cil_iomemcon_to_policy(file_arr, db->iomemcon); 1361 if (rc != SEPOL_OK) { 1362 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1363 return rc; 1364 } 1365 1366 rc = cil_ioportcon_to_policy(file_arr, db->ioportcon); 1367 if (rc != SEPOL_OK) { 1368 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1369 return rc; 1370 } 1371 1372 rc = cil_pcidevicecon_to_policy(file_arr, db->pcidevicecon); 1373 if (rc != SEPOL_OK) { 1374 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1375 return rc; 1376 } 1377 1378 rc = cil_userrole_to_policy(file_arr, users); 1379 if (rc != SEPOL_OK) { 1380 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1381 return SEPOL_ERR; 1382 } 1383 1384 rc = cil_sens_to_policy(file_arr, sens); 1385 if (rc != SEPOL_OK) { 1386 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1387 return SEPOL_ERR; 1388 } 1389 1390 rc = cil_cat_to_policy(file_arr, cats); 1391 if (rc != SEPOL_OK) { 1392 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1393 return SEPOL_ERR; 1394 } 1395 1396 rc = cil_combine_policy(file_arr, policy_file); 1397 if (rc != SEPOL_OK) { 1398 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1399 return SEPOL_ERR; 1400 } 1401 1402 // Remove temp files 1403 int i; 1404 for (i=0; i<NUM_POLICY_FILES; i++) { 1405 rc = fclose(file_arr[i]); 1406 if (rc != 0) { 1407 cil_log(CIL_ERR, "Error closing temporary file\n"); 1408 return SEPOL_ERR; 1409 } 1410 rc = unlink(file_path_arr[i]); 1411 if (rc != 0) { 1412 cil_log(CIL_ERR, "Error unlinking temporary files\n"); 1413 return SEPOL_ERR; 1414 } 1415 } 1416 1417 rc = fclose(policy_file); 1418 if (rc != 0) { 1419 cil_log(CIL_ERR, "Error closing policy.conf\n"); 1420 return SEPOL_ERR; 1421 } 1422 free(file_arr); 1423 1424 cil_list_destroy(&users, CIL_FALSE); 1425 cil_list_destroy(&cats, CIL_FALSE); 1426 cil_list_destroy(&sens, CIL_FALSE); 1427 1428 return SEPOL_OK; 1429 } 1430