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 72struct cil_args_genpolicy { 73 struct cil_list *users; 74 struct cil_list *sens; 75 struct cil_list *cats; 76 FILE **file_arr; 77}; 78 79struct cil_args_booleanif { 80 FILE **file_arr; 81 uint32_t *file_index; 82}; 83 84 85int cil_expr_to_policy(FILE **file_arr, uint32_t file_index, struct cil_list *expr); 86 87int 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 115int 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 136int 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 151int 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 167int 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 216exit: 217 return rc; 218} 219 220 221int 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} 234int 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 248int 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 262int 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 276int 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 299int 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 337int 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 365int 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 391int 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 417void 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 422void 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 433void 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 443void 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 454void 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 505void 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 533void 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 546void 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 575int 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->perms.classperms); 602 603 return SEPOL_OK; 604} 605 606int 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 631int 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 642static 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 805exit: 806 for (i = 0; i < pos; i++) { 807 free(stack[i]); 808 } 809 return rc; 810} 811 812int 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 826out: 827 return rc; 828} 829 830int __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 868int __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 885int 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 947int 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 1104int __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_CATALIAS: { 1159 struct cil_alias *alias = node->data; 1160 struct cil_symtab_datum *datum = alias->actual; 1161 cil_multimap_insert(cats, datum, node->data, CIL_CAT, CIL_CATALIAS); 1162 } 1163 break; 1164 case CIL_SENSALIAS: { 1165 struct cil_alias *alias = node->data; 1166 struct cil_symtab_datum *datum = alias->actual; 1167 cil_multimap_insert(sens, datum, node->data, CIL_SENS, CIL_SENSALIAS); 1168 } 1169 break; 1170 default: 1171 rc = cil_name_to_policy(file_arr, node); 1172 if (rc != SEPOL_OK && rc != SEPOL_DONE) { 1173 cil_log(CIL_ERR, "Error converting node to policy %d\n", rc); 1174 return SEPOL_ERR; 1175 } 1176 break; 1177 } 1178 } 1179 1180 return SEPOL_OK; 1181} 1182 1183int cil_gen_policy(struct cil_db *db) 1184{ 1185 struct cil_tree_node *curr = db->ast->root; 1186 struct cil_list_item *item; 1187 int rc = SEPOL_ERR; 1188 FILE *policy_file; 1189 FILE **file_arr = cil_malloc(sizeof(FILE*) * NUM_POLICY_FILES); 1190 char *file_path_arr[NUM_POLICY_FILES]; 1191 char temp[32]; 1192 1193 struct cil_list *users = NULL; 1194 struct cil_list *cats = NULL; 1195 struct cil_list *sens = NULL; 1196 struct cil_args_genpolicy extra_args; 1197 1198 cil_list_init(&users, CIL_LIST_ITEM); 1199 cil_list_init(&cats, CIL_LIST_ITEM); 1200 cil_list_init(&sens, CIL_LIST_ITEM); 1201 1202 strcpy(temp, "/tmp/cil_classdecl-XXXXXX"); 1203 file_arr[CLASS_DECL] = fdopen(mkstemp(temp), "w+"); 1204 file_path_arr[CLASS_DECL] = cil_strpool_add(temp); 1205 1206 strcpy(temp, "/tmp/cil_isids-XXXXXX"); 1207 file_arr[ISIDS] = fdopen(mkstemp(temp), "w+"); 1208 file_path_arr[ISIDS] = cil_strpool_add(temp); 1209 1210 strcpy(temp,"/tmp/cil_common-XXXXXX"); 1211 file_arr[COMMONS] = fdopen(mkstemp(temp), "w+"); 1212 file_path_arr[COMMONS] = cil_strpool_add(temp); 1213 1214 strcpy(temp, "/tmp/cil_class-XXXXXX"); 1215 file_arr[CLASSES] = fdopen(mkstemp(temp), "w+"); 1216 file_path_arr[CLASSES] = cil_strpool_add(temp); 1217 1218 strcpy(temp, "/tmp/cil_interf-XXXXXX"); 1219 file_arr[INTERFACES] = fdopen(mkstemp(temp), "w+"); 1220 file_path_arr[INTERFACES] = cil_strpool_add(temp); 1221 1222 strcpy(temp, "/tmp/cil_sens-XXXXXX"); 1223 file_arr[SENS] = fdopen(mkstemp(temp), "w+"); 1224 file_path_arr[SENS] = cil_strpool_add(temp); 1225 1226 strcpy(temp, "/tmp/cil_cats-XXXXXX"); 1227 file_arr[CATS] = fdopen(mkstemp(temp), "w+"); 1228 file_path_arr[CATS] = cil_strpool_add(temp); 1229 1230 strcpy(temp, "/tmp/cil_levels-XXXXXX"); 1231 file_arr[LEVELS] = fdopen(mkstemp(temp), "w+"); 1232 file_path_arr[LEVELS] = cil_strpool_add(temp); 1233 1234 strcpy(temp, "/tmp/cil_mlscon-XXXXXX"); 1235 file_arr[CONSTRAINS] = fdopen(mkstemp(temp), "w+"); 1236 file_path_arr[CONSTRAINS] = cil_strpool_add(temp); 1237 1238 strcpy(temp, "/tmp/cil_attrtypes-XXXXXX"); 1239 file_arr[TYPEATTRTYPES] = fdopen(mkstemp(temp), "w+"); 1240 file_path_arr[TYPEATTRTYPES] = cil_strpool_add(temp); 1241 1242 strcpy(temp, "/tmp/cil_aliases-XXXXXX"); 1243 file_arr[ALIASES] = fdopen(mkstemp(temp), "w+"); 1244 file_path_arr[ALIASES] = cil_strpool_add(temp); 1245 1246 strcpy(temp, "/tmp/cil_allows-XXXXXX"); 1247 file_arr[ALLOWS] = fdopen(mkstemp(temp), "w+"); 1248 file_path_arr[ALLOWS] = cil_strpool_add(temp); 1249 1250 strcpy(temp, "/tmp/cil_conds-XXXXXX"); 1251 file_arr[CONDS] = fdopen(mkstemp(temp), "w+"); 1252 file_path_arr[CONDS] = cil_strpool_add(temp); 1253 1254 strcpy(temp, "/tmp/cil_userroles-XXXXXX"); 1255 file_arr[USERROLES] = fdopen(mkstemp(temp), "w+"); 1256 file_path_arr[USERROLES] = cil_strpool_add(temp); 1257 1258 strcpy(temp, "/tmp/cil_sids-XXXXXX"); 1259 file_arr[SIDS] = fdopen(mkstemp(temp), "w+"); 1260 file_path_arr[SIDS] = cil_strpool_add(temp); 1261 1262 strcpy(temp, "/tmp/cil_netifcons-XXXXXX"); 1263 file_arr[NETIFCONS] = fdopen(mkstemp(temp), "w+"); 1264 file_path_arr[NETIFCONS] = cil_strpool_add(temp); 1265 1266 policy_file = fopen("policy.conf", "w+"); 1267 1268 cil_list_for_each(item, db->sidorder) { 1269 fprintf(file_arr[ISIDS], "sid %s ", ((struct cil_sid*)item->data)->datum.name); 1270 } 1271 1272 cil_list_for_each(item, db->classorder) { 1273 struct cil_class *class = item->data; 1274 struct cil_tree_node *node = class->datum.nodes->head->data; 1275 1276 fprintf(file_arr[CLASS_DECL], "class %s\n", class->datum.name); 1277 1278 fprintf(file_arr[CLASSES], "class %s ", class->datum.name); 1279 if (class->common != NULL) { 1280 fprintf(file_arr[CLASSES], "inherits %s ", class->common->datum.name); 1281 } 1282 if (node->cl_head != NULL) { 1283 struct cil_tree_node *curr_perm = node->cl_head; 1284 fprintf(file_arr[CLASSES], "{ "); 1285 while (curr_perm != NULL) { 1286 fprintf(file_arr[CLASSES], "%s ", ((struct cil_symtab_datum*)curr_perm->data)->name); 1287 curr_perm = curr_perm->next; 1288 } 1289 fprintf(file_arr[CLASSES], "}"); 1290 } 1291 fprintf(file_arr[CLASSES], "\n"); 1292 } 1293 1294 if (db->catorder->head != NULL) { 1295 cil_list_for_each(item, db->catorder) { 1296 cil_multimap_insert(cats, item->data, NULL, CIL_CAT, 0); 1297 } 1298 } 1299 1300 if (db->sensitivityorder->head != NULL) { 1301 fprintf(file_arr[SENS], "sensitivityorder { "); 1302 cil_list_for_each(item, db->sensitivityorder) { 1303 fprintf(file_arr[SENS], "%s ", ((struct cil_sens*)item->data)->datum.name); 1304 } 1305 fprintf(file_arr[SENS], "};\n"); 1306 } 1307 1308 extra_args.users = users; 1309 extra_args.sens = sens; 1310 extra_args.cats = cats; 1311 extra_args.file_arr= file_arr; 1312 1313 rc = cil_tree_walk(curr, __cil_gen_policy_node_helper, NULL, NULL, &extra_args); 1314 if (rc != SEPOL_OK) { 1315 cil_log(CIL_ERR, "Error walking tree\n"); 1316 return rc; 1317 } 1318 1319 rc = cil_netifcon_to_policy(file_arr, db->netifcon); 1320 if (rc != SEPOL_OK) { 1321 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1322 return rc; 1323 } 1324 1325 rc = cil_genfscon_to_policy(file_arr, db->genfscon); 1326 if (rc != SEPOL_OK) { 1327 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1328 return rc; 1329 } 1330 1331 rc = cil_portcon_to_policy(file_arr, db->portcon); 1332 if (rc != SEPOL_OK) { 1333 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1334 return rc; 1335 } 1336 1337 rc = cil_nodecon_to_policy(file_arr, db->nodecon); 1338 if (rc != SEPOL_OK) { 1339 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1340 return rc; 1341 } 1342 1343 rc = cil_fsuse_to_policy(file_arr, db->fsuse); 1344 if (rc != SEPOL_OK) { 1345 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1346 return rc; 1347 } 1348 1349 rc = cil_pirqcon_to_policy(file_arr, db->pirqcon); 1350 if (rc != SEPOL_OK) { 1351 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1352 return rc; 1353 } 1354 1355 rc = cil_iomemcon_to_policy(file_arr, db->iomemcon); 1356 if (rc != SEPOL_OK) { 1357 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1358 return rc; 1359 } 1360 1361 rc = cil_ioportcon_to_policy(file_arr, db->ioportcon); 1362 if (rc != SEPOL_OK) { 1363 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1364 return rc; 1365 } 1366 1367 rc = cil_pcidevicecon_to_policy(file_arr, db->pcidevicecon); 1368 if (rc != SEPOL_OK) { 1369 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1370 return rc; 1371 } 1372 1373 rc = cil_userrole_to_policy(file_arr, users); 1374 if (rc != SEPOL_OK) { 1375 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1376 return SEPOL_ERR; 1377 } 1378 1379 rc = cil_sens_to_policy(file_arr, sens); 1380 if (rc != SEPOL_OK) { 1381 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1382 return SEPOL_ERR; 1383 } 1384 1385 rc = cil_cat_to_policy(file_arr, cats); 1386 if (rc != SEPOL_OK) { 1387 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1388 return SEPOL_ERR; 1389 } 1390 1391 rc = cil_combine_policy(file_arr, policy_file); 1392 if (rc != SEPOL_OK) { 1393 cil_log(CIL_ERR, "Error creating policy.conf\n"); 1394 return SEPOL_ERR; 1395 } 1396 1397 // Remove temp files 1398 int i; 1399 for (i=0; i<NUM_POLICY_FILES; i++) { 1400 rc = fclose(file_arr[i]); 1401 if (rc != 0) { 1402 cil_log(CIL_ERR, "Error closing temporary file\n"); 1403 return SEPOL_ERR; 1404 } 1405 rc = unlink(file_path_arr[i]); 1406 if (rc != 0) { 1407 cil_log(CIL_ERR, "Error unlinking temporary files\n"); 1408 return SEPOL_ERR; 1409 } 1410 } 1411 1412 rc = fclose(policy_file); 1413 if (rc != 0) { 1414 cil_log(CIL_ERR, "Error closing policy.conf\n"); 1415 return SEPOL_ERR; 1416 } 1417 free(file_arr); 1418 1419 cil_list_destroy(&users, CIL_FALSE); 1420 cil_list_destroy(&cats, CIL_FALSE); 1421 cil_list_destroy(&sens, CIL_FALSE); 1422 1423 return SEPOL_OK; 1424} 1425