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 <assert.h>
33#include <netinet/in.h>
34
35#include <sepol/policydb/policydb.h>
36#include <sepol/policydb/polcaps.h>
37#include <sepol/policydb/conditional.h>
38#include <sepol/policydb/constraint.h>
39#include <sepol/policydb/flask.h>
40
41#include "cil_internal.h"
42#include "cil_flavor.h"
43#include "cil_log.h"
44#include "cil_mem.h"
45#include "cil_tree.h"
46#include "cil_binary.h"
47#include "cil_symtab.h"
48
49/* There are 44000 filename_trans in current fedora policy. 1.33 times this is the recommended
50 * size of a hashtable. The next power of 2 of this is 2 ** 16.
51 */
52#define FILENAME_TRANS_TABLE_SIZE 1 << 16
53#define RANGE_TRANS_TABLE_SIZE 1 << 13
54#define ROLE_TRANS_TABLE_SIZE 1 << 10
55
56struct cil_args_binary {
57	const struct cil_db *db;
58	policydb_t *pdb;
59	struct cil_list *neverallows;
60	int pass;
61	hashtab_t filename_trans_table;
62	hashtab_t range_trans_table;
63	hashtab_t role_trans_table;
64};
65
66struct cil_args_booleanif {
67	const struct cil_db *db;
68	policydb_t *pdb;
69	cond_node_t *cond_node;
70	enum cil_flavor cond_flavor;
71	struct cil_list *neverallows;
72	hashtab_t filename_trans_table;
73};
74
75struct cil_neverallow {
76	struct cil_tree_node *node;
77	struct cil_list *rules;
78};
79
80struct cil_neverallow_rule {
81	struct cil_symtab_datum *src;
82	struct cil_symtab_datum *tgt;
83	uint32_t class;
84	uint32_t perms;
85};
86
87void cil_neverallows_list_destroy(struct cil_list *neverallows)
88{
89	struct cil_list_item *i;
90	struct cil_list_item *j;
91
92	cil_list_for_each(i, neverallows) {
93		struct cil_neverallow *neverallow = i->data;
94		cil_list_for_each(j, neverallow->rules) {
95			struct cil_neverallow_rule *rule = j->data;
96			free(rule);
97		}
98		cil_list_destroy(&neverallow->rules, CIL_FALSE);
99		free(neverallow);
100	}
101	cil_list_destroy(&neverallows, CIL_FALSE);
102}
103
104static int __cil_get_sepol_user_datum(policydb_t *pdb, struct cil_symtab_datum *datum, user_datum_t **sepol_user)
105{
106	*sepol_user = hashtab_search(pdb->p_users.table, datum->fqn);
107	if (*sepol_user == NULL) {
108		cil_log(CIL_INFO, "Failed to find user %s in sepol hashtab\n", datum->fqn);
109		return SEPOL_ERR;
110	}
111
112	return SEPOL_OK;
113}
114
115static int __cil_get_sepol_role_datum(policydb_t *pdb, struct cil_symtab_datum *datum, role_datum_t **sepol_role)
116{
117	*sepol_role = hashtab_search(pdb->p_roles.table, datum->fqn);
118	if (*sepol_role == NULL) {
119		cil_log(CIL_INFO, "Failed to find role %s in sepol hashtab\n", datum->fqn);
120		return SEPOL_ERR;
121	}
122
123	return SEPOL_OK;
124}
125
126static int __cil_get_sepol_type_datum(policydb_t *pdb, struct cil_symtab_datum *datum, type_datum_t **sepol_type)
127{
128	*sepol_type = hashtab_search(pdb->p_types.table, datum->fqn);
129	if (*sepol_type == NULL) {
130		cil_log(CIL_INFO, "Failed to find type %s in sepol hashtab\n", datum->fqn);
131		return SEPOL_ERR;
132	}
133
134	return SEPOL_OK;
135}
136
137static int __cil_get_sepol_class_datum(policydb_t *pdb, struct cil_symtab_datum *datum, class_datum_t **sepol_class)
138{
139	*sepol_class = hashtab_search(pdb->p_classes.table, datum->fqn);
140	if (*sepol_class == NULL) {
141		cil_log(CIL_INFO, "Failed to find class %s in sepol hashtab\n", datum->fqn);
142		return SEPOL_ERR;
143	}
144
145	return SEPOL_OK;
146}
147
148static int __cil_get_sepol_cat_datum(policydb_t *pdb, struct cil_symtab_datum *datum, cat_datum_t **sepol_cat)
149{
150	*sepol_cat = hashtab_search(pdb->p_cats.table, datum->fqn);
151	if (*sepol_cat == NULL) {
152		cil_log(CIL_INFO, "Failed to find category %s in sepol hashtab\n", datum->fqn);
153		return SEPOL_ERR;
154	}
155
156	return SEPOL_OK;
157}
158
159static int __cil_get_sepol_level_datum(policydb_t *pdb, struct cil_symtab_datum *datum, level_datum_t **sepol_level)
160{
161	*sepol_level = hashtab_search(pdb->p_levels.table, datum->fqn);
162	if (*sepol_level == NULL) {
163		cil_log(CIL_INFO, "Failed to find level %s in sepol hashtab\n", datum->fqn);
164		return SEPOL_ERR;
165	}
166
167	return SEPOL_OK;
168}
169
170static int __cil_expand_role(struct cil_symtab_datum *datum, ebitmap_t *new)
171{
172	struct cil_tree_node *node = datum->nodes->head->data;
173
174	if (node->flavor == CIL_ROLEATTRIBUTE) {
175		struct cil_roleattribute *attr = (struct cil_roleattribute *)datum;
176		if (ebitmap_cpy(new, attr->roles)) {
177			cil_log(CIL_ERR, "Failed to copy role bits\n");
178			goto exit;
179		}
180	} else {
181		struct cil_role *role = (struct cil_role *)datum;
182		ebitmap_init(new);
183		if (ebitmap_set_bit(new, role->value, 1)) {
184			cil_log(CIL_ERR, "Failed to set role bit\n");
185			ebitmap_destroy(new);
186			goto exit;
187		}
188	}
189
190	return SEPOL_OK;
191
192exit:
193	return SEPOL_ERR;
194}
195
196static int __cil_expand_type(struct cil_symtab_datum *datum, ebitmap_t *new)
197{
198	struct cil_tree_node *node = datum->nodes->head->data;
199
200	if (node->flavor == CIL_TYPEATTRIBUTE) {
201		struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
202		if (ebitmap_cpy(new, attr->types)) {
203			cil_log(CIL_ERR, "Failed to copy type bits\n");
204			goto exit;
205		}
206	} else {
207		struct cil_type *type = (struct cil_type *)datum;
208		ebitmap_init(new);
209		if (ebitmap_set_bit(new, type->value, 1)) {
210			cil_log(CIL_ERR, "Failed to set type bit\n");
211			ebitmap_destroy(new);
212			goto exit;
213		}
214	}
215
216	return SEPOL_OK;
217
218exit:
219	return SEPOL_ERR;
220}
221
222static ocontext_t *cil_add_ocontext(ocontext_t **head, ocontext_t **tail)
223{
224	ocontext_t *new = cil_malloc(sizeof(ocontext_t));
225	memset(new, 0, sizeof(ocontext_t));
226	if (*tail) {
227		(*tail)->next = new;
228	} else {
229		*head = new;
230	}
231	*tail = new;
232
233	return new;
234}
235
236static void __add_classes_from_classperms_list(struct cil_list *classperms, struct cil_list *class_list)
237{
238	struct cil_list_item *curr;
239
240	cil_list_for_each(curr, classperms) {
241		if (curr->flavor == CIL_CLASSPERMS) {
242			struct cil_classperms *cp = curr->data;
243			if (FLAVOR(cp->class) == CIL_CLASS) {
244				cil_list_append(class_list, CIL_CLASS, cp->class);
245			} else { /* MAP */
246				struct cil_list_item *i = NULL;
247				cil_list_for_each(i, cp->perms) {
248					struct cil_perm *cmp = i->data;
249					__add_classes_from_classperms_list(cmp->classperms, class_list);
250				}
251			}
252		} else { /* SET */
253			struct cil_classperms_set *cp_set = curr->data;
254			struct cil_classpermission *cp = cp_set->set;
255			__add_classes_from_classperms_list(cp->classperms, class_list);
256		}
257	}
258}
259
260static int __add_classes_from_map_perms(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
261{
262	struct cil_list *class_list = args;
263	struct cil_perm *cmp = (struct cil_perm *)d;
264
265	__add_classes_from_classperms_list(cmp->classperms, class_list);
266
267	return SEPOL_OK;
268}
269
270static struct cil_list *cil_expand_class(struct cil_class *class)
271{
272	struct cil_list *class_list;
273
274	cil_list_init(&class_list, CIL_CLASS);
275
276	if (FLAVOR(class) == CIL_CLASS) {
277		cil_list_append(class_list, CIL_CLASS, class);
278	} else { /* MAP */
279		cil_symtab_map(&class->perms, __add_classes_from_map_perms, class_list);
280	}
281
282	return class_list;
283}
284
285int cil_common_to_policydb(policydb_t *pdb, struct cil_class *cil_common, common_datum_t **common_out)
286{
287	int rc = SEPOL_ERR;
288	uint32_t value = 0;
289	char *key = NULL;
290	struct cil_tree_node *node = cil_common->datum.nodes->head->data;
291	struct cil_tree_node *cil_perm = node->cl_head;
292	common_datum_t *sepol_common = cil_malloc(sizeof(*sepol_common));
293	memset(sepol_common, 0, sizeof(common_datum_t));
294
295	key = cil_strdup(cil_common->datum.fqn);
296	rc = symtab_insert(pdb, SYM_COMMONS, key, sepol_common, SCOPE_DECL, 0, &value);
297	if (rc != SEPOL_OK) {
298		free(sepol_common);
299		goto exit;
300	}
301	sepol_common->s.value = value;
302
303	rc = symtab_init(&sepol_common->permissions, PERM_SYMTAB_SIZE);
304	if (rc != SEPOL_OK) {
305		goto exit;
306	}
307
308	while (cil_perm != NULL) {
309		struct cil_perm *curr = cil_perm->data;
310		perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm));
311		memset(sepol_perm, 0, sizeof(perm_datum_t));
312
313		key = cil_strdup(curr->datum.fqn);
314		rc = hashtab_insert(sepol_common->permissions.table, key, sepol_perm);
315		if (rc != SEPOL_OK) {
316			free(sepol_perm);
317			goto exit;
318		}
319		sepol_perm->s.value = sepol_common->permissions.nprim + 1;
320		sepol_common->permissions.nprim++;
321		cil_perm = cil_perm->next;
322	}
323
324	*common_out = sepol_common;
325
326	return SEPOL_OK;
327
328exit:
329	free(key);
330	return rc;
331}
332
333int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
334{
335	int rc = SEPOL_ERR;
336	struct cil_list_item *curr_class;
337
338	cil_list_for_each(curr_class, db->classorder) {
339		struct cil_class *cil_class = curr_class->data;
340		uint32_t value = 0;
341		char *key = NULL;
342		struct cil_tree_node *node = cil_class->datum.nodes->head->data;
343		struct cil_tree_node *cil_perm = node->cl_head;
344		common_datum_t *sepol_common = NULL;
345		class_datum_t *sepol_class = cil_malloc(sizeof(*sepol_class));
346		memset(sepol_class, 0, sizeof(class_datum_t));
347
348		key = cil_strdup(cil_class->datum.fqn);
349		rc = symtab_insert(pdb, SYM_CLASSES, key, sepol_class, SCOPE_DECL, 0, &value);
350		if (rc != SEPOL_OK) {
351			free(sepol_class);
352			free(key);
353			goto exit;
354		}
355		sepol_class->s.value = value;
356
357		rc = symtab_init(&sepol_class->permissions, PERM_SYMTAB_SIZE);
358		if (rc != SEPOL_OK) {
359			goto exit;
360		}
361
362		if (cil_class->common != NULL) {
363			struct cil_class *cil_common = cil_class->common;
364
365			key = cil_class->common->datum.fqn;
366			sepol_common = hashtab_search(pdb->p_commons.table, key);
367			if (sepol_common == NULL) {
368				rc = cil_common_to_policydb(pdb, cil_common, &sepol_common);
369				if (rc != SEPOL_OK) {
370					goto exit;
371				}
372			}
373			sepol_class->comdatum = sepol_common;
374			sepol_class->comkey = cil_strdup(key);
375			sepol_class->permissions.nprim += sepol_common->permissions.nprim;
376		}
377
378		while (cil_perm != NULL) {
379			struct cil_perm *curr_perm = cil_perm->data;
380			perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm));
381			memset(sepol_perm, 0, sizeof(perm_datum_t));
382
383			key = cil_strdup(curr_perm->datum.fqn);
384			rc = hashtab_insert(sepol_class->permissions.table, key, sepol_perm);
385			if (rc != SEPOL_OK) {
386				free(sepol_perm);
387				free(key);
388				goto exit;
389			}
390			sepol_perm->s.value = sepol_class->permissions.nprim + 1;
391			sepol_class->permissions.nprim++;
392			cil_perm = cil_perm->next;
393		}
394	}
395
396	return SEPOL_OK;
397
398exit:
399	return rc;
400}
401
402int cil_role_to_policydb(policydb_t *pdb, struct cil_role *cil_role)
403{
404	int rc = SEPOL_ERR;
405	uint32_t value = 0;
406	char *key = NULL;
407	role_datum_t *sepol_role = cil_malloc(sizeof(*sepol_role));
408	role_datum_init(sepol_role);
409
410	if (cil_role->datum.fqn == CIL_KEY_OBJECT_R) {
411		/* special case
412		 * object_r defaults to 1 in libsepol symtab */
413		rc = SEPOL_OK;
414		goto exit;
415	}
416
417	key = cil_strdup(cil_role->datum.fqn);
418	rc = symtab_insert(pdb, SYM_ROLES, (hashtab_key_t)key, sepol_role, SCOPE_DECL, 0, &value);
419	if (rc != SEPOL_OK) {
420		goto exit;
421	}
422	if (ebitmap_set_bit(&sepol_role->dominates, value - 1, 1)) {
423		cil_log(CIL_INFO, "Failed to set dominates bit for role\n");
424		rc = SEPOL_ERR;
425		goto exit;
426	}
427	sepol_role->s.value = value;
428	return SEPOL_OK;
429
430exit:
431	free(key);
432	role_datum_destroy(sepol_role);
433	free(sepol_role);
434	return rc;
435}
436
437int cil_role_bounds_to_policydb(policydb_t *pdb, struct cil_role *cil_role)
438{
439	int rc = SEPOL_ERR;
440	role_datum_t *sepol_role = NULL;
441	role_datum_t *sepol_parent = NULL;
442
443	if (cil_role->bounds) {
444		rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_role), &sepol_role);
445		if (rc != SEPOL_OK) goto exit;
446
447		rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_role->bounds), &sepol_parent);
448		if (rc != SEPOL_OK) goto exit;
449
450		sepol_role->bounds = sepol_parent->s.value;
451	}
452
453	return SEPOL_OK;
454
455exit:
456	cil_log(CIL_ERR, "Failed to insert role bounds for role %s\n", cil_role->datum.fqn);
457	return SEPOL_ERR;
458}
459
460int cil_roletype_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_role *role)
461{
462	int rc = SEPOL_ERR;
463
464	if (role->types) {
465		role_datum_t *sepol_role = NULL;
466		type_datum_t *sepol_type = NULL;
467		ebitmap_node_t *tnode;
468		unsigned int i;
469
470		rc = __cil_get_sepol_role_datum(pdb, DATUM(role), &sepol_role);
471		if (rc != SEPOL_OK) goto exit;
472
473		ebitmap_for_each_bit(role->types, tnode, i) {
474			if (!ebitmap_get_bit(role->types, i)) continue;
475
476			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type);
477			if (rc != SEPOL_OK) goto exit;
478
479			if (ebitmap_set_bit(&sepol_role->types.types, sepol_type->s.value - 1, 1)) {
480				cil_log(CIL_INFO, "Failed to set type bit for role\n");
481				rc = SEPOL_ERR;
482				goto exit;
483			}
484		}
485	}
486
487	return SEPOL_OK;
488
489exit:
490	return rc;
491}
492
493int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type)
494{
495	int rc = SEPOL_ERR;
496	uint32_t value = 0;
497	char *key = NULL;
498	type_datum_t *sepol_type = cil_malloc(sizeof(*sepol_type));
499	type_datum_init(sepol_type);
500
501	sepol_type->flavor = TYPE_TYPE;
502
503	key = cil_strdup(cil_type->datum.fqn);
504	rc = symtab_insert(pdb, SYM_TYPES, key, sepol_type, SCOPE_DECL, 0, &value);
505	if (rc != SEPOL_OK) {
506		goto exit;
507	}
508	sepol_type->s.value = value;
509	sepol_type->primary = 1;
510
511	return SEPOL_OK;
512
513exit:
514	free(key);
515	type_datum_destroy(sepol_type);
516	free(sepol_type);
517	return rc;
518}
519
520int cil_type_bounds_to_policydb(policydb_t *pdb, struct cil_type *cil_type)
521{
522	int rc = SEPOL_ERR;
523	type_datum_t *sepol_type = NULL;
524	type_datum_t *sepol_parent = NULL;
525
526	if (cil_type->bounds) {
527		rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_type), &sepol_type);
528		if (rc != SEPOL_OK) goto exit;
529
530		rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_type->bounds), &sepol_parent);
531		if (rc != SEPOL_OK) goto exit;
532
533		sepol_type->bounds = sepol_parent->s.value;
534	}
535
536	return SEPOL_OK;
537
538exit:
539	cil_log(CIL_ERR, "Failed to insert type bounds for type %s\n", cil_type->datum.fqn);
540	return SEPOL_ERR;
541}
542
543int cil_typealias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias)
544{
545	int rc = SEPOL_ERR;
546	char *key = NULL;
547	type_datum_t *sepol_type = NULL;
548	type_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_alias));
549	type_datum_init(sepol_alias);
550
551	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_alias->actual), &sepol_type);
552	if (rc != SEPOL_OK) goto exit;
553
554	sepol_alias->flavor = TYPE_TYPE;
555
556	key = cil_strdup(cil_alias->datum.fqn);
557	rc = symtab_insert(pdb, SYM_TYPES, key, sepol_alias, SCOPE_DECL, 0, NULL);
558	if (rc != SEPOL_OK) {
559		goto exit;
560	}
561	sepol_alias->s.value = sepol_type->s.value;
562	sepol_alias->primary = 0;
563
564	return SEPOL_OK;
565
566exit:
567	free(key);
568	type_datum_destroy(sepol_alias);
569	free(sepol_alias);
570	return rc;
571}
572
573int cil_typepermissive_to_policydb(policydb_t *pdb, struct cil_typepermissive *cil_typeperm)
574{
575	int rc = SEPOL_ERR;
576	type_datum_t *sepol_type = NULL;
577
578	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_typeperm->type), &sepol_type);
579	if (rc != SEPOL_OK) goto exit;
580
581	if (ebitmap_set_bit(&pdb->permissive_map, sepol_type->s.value, 1)) {
582		goto exit;
583	}
584
585	return SEPOL_OK;
586
587exit:
588	type_datum_destroy(sepol_type);
589	free(sepol_type);
590	return rc;
591
592}
593
594int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr)
595{
596	int rc = SEPOL_ERR;
597	uint32_t value = 0;
598	char *key = NULL;
599	type_datum_t *sepol_attr = NULL;
600
601	if (cil_attr->used == CIL_FALSE) {
602		return SEPOL_OK;
603	}
604
605	sepol_attr = cil_malloc(sizeof(*sepol_attr));
606	type_datum_init(sepol_attr);
607
608	sepol_attr->flavor = TYPE_ATTRIB;
609
610	key = cil_strdup(cil_attr->datum.fqn);
611	rc = symtab_insert(pdb, SYM_TYPES, key, sepol_attr, SCOPE_DECL, 0, &value);
612	if (rc != SEPOL_OK) {
613		goto exit;
614	}
615	sepol_attr->s.value = value;
616	sepol_attr->primary = 1;
617
618	return SEPOL_OK;
619
620exit:
621	type_datum_destroy(sepol_attr);
622	free(sepol_attr);
623	return rc;
624}
625
626int __cil_typeattr_bitmap_init(policydb_t *pdb)
627{
628	int rc = SEPOL_ERR;
629
630	pdb->type_attr_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t));
631
632	uint32_t i = 0;
633	for (i = 0; i < pdb->p_types.nprim; i++) {
634		ebitmap_init(&pdb->type_attr_map[i]);
635		if (ebitmap_set_bit(&pdb->type_attr_map[i], i, 1)) {
636			rc = SEPOL_ERR;
637			goto exit;
638		}
639	}
640
641	return SEPOL_OK;
642
643exit:
644	return rc;
645}
646
647int cil_typeattribute_to_bitmap(policydb_t *pdb, const struct cil_db *db, struct cil_typeattribute *cil_attr)
648{
649	int rc = SEPOL_ERR;
650	uint32_t value = 0;
651	type_datum_t *sepol_type = NULL;
652	ebitmap_node_t *tnode;
653	unsigned int i;
654
655	if (cil_attr->used == CIL_FALSE) {
656		return SEPOL_OK;
657	}
658
659	if (pdb->type_attr_map == NULL) {
660		rc = __cil_typeattr_bitmap_init(pdb);
661		if (rc != SEPOL_OK) {
662			goto exit;
663		}
664	}
665
666	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_attr), &sepol_type);
667	if (rc != SEPOL_OK) goto exit;
668
669	value = sepol_type->s.value;
670
671	ebitmap_for_each_bit(cil_attr->types, tnode, i) {
672		if (!ebitmap_get_bit(cil_attr->types, i)) continue;
673
674		rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type);
675		if (rc != SEPOL_OK) goto exit;
676
677		ebitmap_set_bit(&pdb->type_attr_map[sepol_type->s.value - 1], value - 1, 1);
678	}
679
680	rc = SEPOL_OK;
681exit:
682	return rc;
683}
684
685int cil_policycap_to_policydb(policydb_t *pdb, struct cil_policycap *cil_polcap)
686{
687	int rc = SEPOL_ERR;
688	int capnum;
689
690	capnum = sepol_polcap_getnum(cil_polcap->datum.fqn);
691	if (capnum == -1) {
692		goto exit;
693	}
694
695	if (ebitmap_set_bit(&pdb->policycaps, capnum, 1)) {
696		goto exit;
697	}
698
699	return SEPOL_OK;
700
701exit:
702	return rc;
703}
704
705int cil_user_to_policydb(policydb_t *pdb, struct cil_user *cil_user)
706{
707	int rc = SEPOL_ERR;
708	uint32_t value = 0;
709	char *key = NULL;
710	user_datum_t *sepol_user = cil_malloc(sizeof(*sepol_user));
711	user_datum_init(sepol_user);
712
713	key = cil_strdup(cil_user->datum.fqn);
714	rc = symtab_insert(pdb, SYM_USERS, key, sepol_user, SCOPE_DECL, 0, &value);
715	if (rc != SEPOL_OK) {
716		goto exit;
717	}
718	sepol_user->s.value = value;
719
720	return SEPOL_OK;
721
722exit:
723	free(key);
724	user_datum_destroy(sepol_user);
725	free(sepol_user);
726	return rc;
727}
728
729int cil_user_bounds_to_policydb(policydb_t *pdb, struct cil_user *cil_user)
730{
731	int rc = SEPOL_ERR;
732	user_datum_t *sepol_user = NULL;
733	user_datum_t *sepol_parent = NULL;
734
735	if (cil_user->bounds) {
736		rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user), &sepol_user);
737		if (rc != SEPOL_OK) goto exit;
738
739		rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user->bounds), &sepol_parent);
740		if (rc != SEPOL_OK) goto exit;
741
742		sepol_user->bounds = sepol_parent->s.value;
743	}
744
745	return SEPOL_OK;
746
747exit:
748	cil_log(CIL_ERR, "Failed to insert user bounds for user %s\n", cil_user->datum.fqn);
749	return SEPOL_ERR;
750}
751
752int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_userrole *userrole)
753{
754	int rc = SEPOL_ERR;
755	user_datum_t *sepol_user = NULL;
756	role_datum_t *sepol_role = NULL;
757	ebitmap_t role_bitmap;
758	ebitmap_node_t *rnode;
759	unsigned int i;
760
761	rc = __cil_get_sepol_user_datum(pdb, DATUM(userrole->user), &sepol_user);
762	if (rc != SEPOL_OK) goto exit;
763
764	rc = __cil_expand_role(userrole->role, &role_bitmap);
765	if (rc != SEPOL_OK) goto exit;
766
767	ebitmap_for_each_bit(&role_bitmap, rnode, i) {
768		if (!ebitmap_get_bit(&role_bitmap, i)) continue;
769
770		rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role);
771		if (rc != SEPOL_OK) goto exit;
772
773		if (sepol_role->s.value == 1) {
774			// role is object_r, ignore it since it is implicitly associated
775			// with all users
776			continue;
777		}
778
779		if (ebitmap_set_bit(&sepol_user->roles.roles, sepol_role->s.value - 1, 1)) {
780			cil_log(CIL_INFO, "Failed to set role bit for user\n");
781			goto exit;
782		}
783	}
784
785	rc = SEPOL_OK;
786
787exit:
788	ebitmap_destroy(&role_bitmap);
789	return rc;
790}
791
792int cil_bool_to_policydb(policydb_t *pdb, struct cil_bool *cil_bool)
793{
794	int rc = SEPOL_ERR;
795	uint32_t value = 0;
796	char *key = NULL;
797	cond_bool_datum_t *sepol_bool = cil_malloc(sizeof(*sepol_bool));
798	memset(sepol_bool, 0, sizeof(cond_bool_datum_t));
799
800	key = cil_strdup(cil_bool->datum.fqn);
801	rc = symtab_insert(pdb, SYM_BOOLS, key, sepol_bool, SCOPE_DECL, 0, &value);
802	if (rc != SEPOL_OK) {
803		goto exit;
804	}
805	sepol_bool->s.value = value;
806	sepol_bool->state = cil_bool->value;
807
808	return SEPOL_OK;
809
810exit:
811	free(key);
812	free(sepol_bool);
813	return rc;
814}
815
816int cil_catorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
817{
818	int rc = SEPOL_ERR;
819	uint32_t value = 0;
820	char *key = NULL;
821	struct cil_list_item *curr_cat;
822	struct cil_cat *cil_cat = NULL;
823	cat_datum_t *sepol_cat = NULL;
824
825	cil_list_for_each(curr_cat, db->catorder) {
826		cil_cat = curr_cat->data;
827		sepol_cat = cil_malloc(sizeof(*sepol_cat));
828		cat_datum_init(sepol_cat);
829
830		key = cil_strdup(cil_cat->datum.fqn);
831		rc = symtab_insert(pdb, SYM_CATS, key, sepol_cat, SCOPE_DECL, 0, &value);
832		if (rc != SEPOL_OK) {
833			goto exit;
834		}
835		sepol_cat->s.value = value;
836	}
837
838	return SEPOL_OK;
839
840exit:
841	free(key);
842	cat_datum_destroy(sepol_cat);
843	free(sepol_cat);
844	return rc;
845}
846
847int cil_catalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias)
848{
849	int rc = SEPOL_ERR;
850	char *key = NULL;
851	cat_datum_t *sepol_cat;
852	cat_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_cat));
853	cat_datum_init(sepol_alias);
854
855	rc = __cil_get_sepol_cat_datum(pdb, DATUM(cil_alias->actual), &sepol_cat);
856	if (rc != SEPOL_OK) goto exit;
857
858	key = cil_strdup(cil_alias->datum.fqn);
859	rc = symtab_insert(pdb, SYM_CATS, key, sepol_alias, SCOPE_DECL, 0, NULL);
860	if (rc != SEPOL_OK) {
861		free(key);
862		goto exit;
863	}
864	sepol_alias->s.value = sepol_cat->s.value;
865	sepol_alias->isalias = 1;
866
867	return SEPOL_OK;
868
869exit:
870	free(key);
871	cat_datum_destroy(sepol_alias);
872	free(sepol_alias);
873	return rc;
874}
875
876int cil_sensitivityorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
877{
878	int rc = SEPOL_ERR;
879	uint32_t value = 0;
880	char *key = NULL;
881	struct cil_list_item *curr;
882	struct cil_sens *cil_sens = NULL;
883	level_datum_t *sepol_level = NULL;
884	mls_level_t *mls_level = NULL;
885
886	cil_list_for_each(curr, db->sensitivityorder) {
887		cil_sens = curr->data;
888		sepol_level = cil_malloc(sizeof(*sepol_level));
889		mls_level = cil_malloc(sizeof(*mls_level));
890		level_datum_init(sepol_level);
891		mls_level_init(mls_level);
892
893		key = cil_strdup(cil_sens->datum.fqn);
894		rc = symtab_insert(pdb, SYM_LEVELS, key, sepol_level, SCOPE_DECL, 0, &value);
895		if (rc != SEPOL_OK) {
896			goto exit;
897		}
898		mls_level->sens = value;
899		sepol_level->level = mls_level;
900	}
901
902	return SEPOL_OK;
903
904exit:
905	level_datum_destroy(sepol_level);
906	mls_level_destroy(mls_level);
907	free(sepol_level);
908	free(mls_level);
909	free(key);
910	return rc;
911}
912
913int cil_sensalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias)
914{
915	int rc = SEPOL_ERR;
916	char *key = NULL;
917	mls_level_t *mls_level = NULL;
918	level_datum_t *sepol_level = NULL;
919	level_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_alias));
920	level_datum_init(sepol_alias);
921
922	rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_alias->actual), &sepol_level);
923	if (rc != SEPOL_OK) goto exit;
924
925	key = cil_strdup(cil_alias->datum.fqn);
926	rc = symtab_insert(pdb, SYM_LEVELS, key, sepol_alias, SCOPE_DECL, 0, NULL);
927	if (rc != SEPOL_OK) {
928		goto exit;
929	}
930
931	mls_level = cil_malloc(sizeof(*mls_level));
932	mls_level_init(mls_level);
933
934	rc = mls_level_cpy(mls_level, sepol_level->level);
935	if (rc != SEPOL_OK) {
936		goto exit;
937	}
938	sepol_alias->level = mls_level;
939	sepol_alias->defined = 1;
940	sepol_alias->isalias = 1;
941
942	return SEPOL_OK;
943
944exit:
945	level_datum_destroy(sepol_alias);
946	free(sepol_level);
947	free(key);
948	return rc;
949}
950
951int __cil_cond_insert_rule(avtab_t *avtab, avtab_key_t *avtab_key, avtab_datum_t *avtab_datum, cond_node_t *cond_node, enum cil_flavor cond_flavor)
952{
953	int rc = SEPOL_OK;
954	avtab_ptr_t avtab_ptr = NULL;
955	cond_av_list_t *cond_list = NULL;
956
957	avtab_ptr = avtab_insert_nonunique(avtab, avtab_key, avtab_datum);
958	if (!avtab_ptr) {
959		rc = SEPOL_ERR;
960		goto exit;
961	}
962
963	// parse_context needs to be non-NULL for conditional rules to be
964	// written to the binary. it is normally used for finding duplicates,
965	// but cil checks that earlier, so we don't use it. it just needs to be
966	// set
967	avtab_ptr->parse_context = (void*)1;
968
969	cond_list = cil_malloc(sizeof(cond_av_list_t));
970	memset(cond_list, 0, sizeof(cond_av_list_t));
971
972	cond_list->node = avtab_ptr;
973
974	if (cond_flavor == CIL_CONDTRUE) {
975      cond_list->next = cond_node->true_list;
976      cond_node->true_list = cond_list;
977	} else {
978      cond_list->next = cond_node->false_list;
979      cond_node->false_list = cond_list;
980	}
981
982exit:
983	return rc;
984}
985
986avtab_datum_t *cil_cond_av_list_search(avtab_key_t *key, cond_av_list_t *cond_list)
987{
988	cond_av_list_t *cur_av;
989
990	for (cur_av = cond_list; cur_av != NULL; cur_av = cur_av->next) {
991		if (cur_av->node->key.source_type == key->source_type &&
992		    cur_av->node->key.target_type == key->target_type &&
993		    cur_av->node->key.target_class == key->target_class &&
994			(cur_av->node->key.specified & key->specified))
995
996			return &cur_av->node->datum;
997
998	}
999	return NULL;
1000}
1001
1002int __cil_insert_type_rule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_t tgt, uint32_t obj, uint32_t res, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1003{
1004	int rc = SEPOL_OK;
1005	avtab_key_t avtab_key;
1006	avtab_datum_t avtab_datum;
1007	avtab_ptr_t existing;
1008
1009	avtab_key.source_type = src;
1010	avtab_key.target_type = tgt;
1011	avtab_key.target_class = obj;
1012
1013	switch (kind) {
1014	case CIL_TYPE_TRANSITION:
1015		avtab_key.specified = AVTAB_TRANSITION;
1016		break;
1017	case CIL_TYPE_CHANGE:
1018		avtab_key.specified = AVTAB_CHANGE;
1019		break;
1020	case CIL_TYPE_MEMBER:
1021		avtab_key.specified = AVTAB_MEMBER;
1022		break;
1023	default:
1024		rc = SEPOL_ERR;
1025		goto exit;
1026	}
1027
1028	avtab_datum.data = res;
1029
1030	existing = avtab_search_node(&pdb->te_avtab, &avtab_key);
1031	if (existing) {
1032		/* Don't add duplicate type rule and warn if they conflict.
1033		 * A warning should have been previously given if there is a
1034		 * non-duplicate rule using the same key.
1035		 */
1036		if (existing->datum.data != res) {
1037			cil_log(CIL_ERR, "Conflicting type rules\n");
1038			rc = SEPOL_ERR;
1039		}
1040		goto exit;
1041	}
1042
1043	if (!cond_node) {
1044		rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum);
1045	} else {
1046		existing = avtab_search_node(&pdb->te_cond_avtab, &avtab_key);
1047		if (existing) {
1048			cond_av_list_t *this_list;
1049			cond_av_list_t *other_list;
1050			avtab_datum_t *search_datum;
1051
1052			if (cond_flavor == CIL_CONDTRUE) {
1053				this_list = cond_node->true_list;
1054				other_list = cond_node->false_list;
1055			} else {
1056				this_list = cond_node->false_list;
1057				other_list = cond_node->true_list;
1058			}
1059
1060			search_datum = cil_cond_av_list_search(&avtab_key, other_list);
1061			if (search_datum == NULL) {
1062				if (existing->datum.data != res) {
1063					cil_log(CIL_ERR, "Conflicting type rules\n");
1064					rc = SEPOL_ERR;
1065					goto exit;
1066				}
1067
1068				search_datum = cil_cond_av_list_search(&avtab_key, this_list);
1069				if (search_datum) {
1070					goto exit;
1071				}
1072			}
1073		}
1074		rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor);
1075	}
1076
1077exit:
1078	return rc;
1079}
1080
1081int __cil_type_rule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_type_rule *cil_rule, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1082{
1083	int rc = SEPOL_ERR;
1084	uint16_t kind = cil_rule->rule_kind;
1085	type_datum_t *sepol_src = NULL;
1086	type_datum_t *sepol_tgt = NULL;
1087	class_datum_t *sepol_obj = NULL;
1088	struct cil_list *class_list;
1089	type_datum_t *sepol_result = NULL;
1090	ebitmap_t src_bitmap, tgt_bitmap;
1091	ebitmap_node_t *node1, *node2;
1092	unsigned int i, j;
1093	struct cil_list_item *c;
1094
1095	rc = __cil_expand_type(cil_rule->src, &src_bitmap);
1096	if (rc != SEPOL_OK) goto exit;
1097
1098	rc = __cil_expand_type(cil_rule->tgt, &tgt_bitmap);
1099	if (rc != SEPOL_OK) goto exit;
1100
1101	class_list = cil_expand_class(cil_rule->obj);
1102
1103	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_rule->result), &sepol_result);
1104	if (rc != SEPOL_OK) goto exit;
1105
1106	ebitmap_for_each_bit(&src_bitmap, node1, i) {
1107		if (!ebitmap_get_bit(&src_bitmap, i)) continue;
1108
1109		rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src);
1110		if (rc != SEPOL_OK) goto exit;
1111
1112		ebitmap_for_each_bit(&tgt_bitmap, node2, j) {
1113			if (!ebitmap_get_bit(&tgt_bitmap, j)) continue;
1114
1115			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
1116			if (rc != SEPOL_OK) goto exit;
1117
1118			cil_list_for_each(c, class_list) {
1119				rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
1120				if (rc != SEPOL_OK) goto exit;
1121
1122				rc = __cil_insert_type_rule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, sepol_result->s.value, cond_node, cond_flavor);
1123				if (rc != SEPOL_OK) goto exit;
1124			}
1125		}
1126	}
1127
1128	rc = SEPOL_OK;
1129
1130exit:
1131	ebitmap_destroy(&src_bitmap);
1132	ebitmap_destroy(&tgt_bitmap);
1133	cil_list_destroy(&class_list, CIL_FALSE);
1134	return rc;
1135}
1136
1137int cil_type_rule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_type_rule *cil_rule)
1138{
1139	return  __cil_type_rule_to_avtab(pdb, db, cil_rule, NULL, CIL_FALSE);
1140}
1141
1142int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans, cond_node_t *cond_node, enum cil_flavor cond_flavor, hashtab_t filename_trans_table)
1143{
1144	int rc = SEPOL_ERR;
1145	type_datum_t *sepol_src = NULL;
1146	type_datum_t *sepol_tgt = NULL;
1147	class_datum_t *sepol_obj = NULL;
1148	struct cil_list *class_list;
1149	type_datum_t *sepol_result = NULL;
1150	filename_trans_t *new = NULL;
1151	ebitmap_t src_bitmap, tgt_bitmap;
1152	ebitmap_node_t *node1, *node2;
1153	unsigned int i, j;
1154	struct cil_list_item *c;
1155	char *name = DATUM(typetrans->name)->name;
1156	uint32_t *otype = NULL;
1157
1158	if (name == CIL_KEY_STAR) {
1159		struct cil_type_rule trans;
1160		trans.rule_kind = CIL_TYPE_TRANSITION;
1161		trans.src = typetrans->src;
1162		trans.tgt = typetrans->tgt;
1163		trans.obj = typetrans->obj;
1164		trans.result = typetrans->result;
1165		return __cil_type_rule_to_avtab(pdb, db, &trans, cond_node, cond_flavor);
1166	}
1167
1168	rc = __cil_expand_type(typetrans->src, &src_bitmap);
1169	if (rc != SEPOL_OK) goto exit;
1170
1171	rc = __cil_expand_type(typetrans->tgt, &tgt_bitmap);
1172	if (rc != SEPOL_OK) goto exit;
1173
1174	class_list = cil_expand_class(typetrans->obj);
1175
1176	rc = __cil_get_sepol_type_datum(pdb, DATUM(typetrans->result), &sepol_result);
1177	if (rc != SEPOL_OK) goto exit;
1178
1179	ebitmap_for_each_bit(&src_bitmap, node1, i) {
1180		if (!ebitmap_get_bit(&src_bitmap, i)) continue;
1181
1182		rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src);
1183		if (rc != SEPOL_OK) goto exit;
1184
1185		ebitmap_for_each_bit(&tgt_bitmap, node2, j) {
1186			if (!ebitmap_get_bit(&tgt_bitmap, j)) continue;
1187
1188			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
1189			if (rc != SEPOL_OK) goto exit;
1190
1191			cil_list_for_each(c, class_list) {
1192				int add = CIL_TRUE;
1193				rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
1194				if (rc != SEPOL_OK) goto exit;
1195
1196				new = cil_malloc(sizeof(*new));
1197				memset(new, 0, sizeof(*new));
1198				new->stype = sepol_src->s.value;
1199				new->ttype = sepol_tgt->s.value;
1200				new->tclass = sepol_obj->s.value;
1201				new->otype = sepol_result->s.value;
1202				new->name = cil_strdup(name);
1203
1204				rc = hashtab_insert(filename_trans_table, (hashtab_key_t)new, &(new->otype));
1205				if (rc != SEPOL_OK) {
1206					if (rc == SEPOL_EEXIST) {
1207						add = CIL_FALSE;
1208						otype = hashtab_search(filename_trans_table, (hashtab_key_t)new);
1209						if (new->otype != *otype) {
1210							cil_log(CIL_ERR, "Conflicting name type transition rules\n");
1211						} else {
1212							rc = SEPOL_OK;
1213						}
1214					} else {
1215						cil_log(CIL_ERR, "Out of memory\n");
1216					}
1217				}
1218
1219				if (add == CIL_TRUE) {
1220					new->next = pdb->filename_trans;
1221					pdb->filename_trans = new;
1222				} else {
1223					free(new->name);
1224					free(new);
1225					if (rc != SEPOL_OK) {
1226						goto exit;
1227					}
1228				}
1229			}
1230		}
1231	}
1232
1233	rc = SEPOL_OK;
1234
1235exit:
1236	ebitmap_destroy(&src_bitmap);
1237	ebitmap_destroy(&tgt_bitmap);
1238	cil_list_destroy(&class_list, CIL_FALSE);
1239	return rc;
1240}
1241
1242int cil_typetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans, hashtab_t filename_trans_table)
1243{
1244	return  __cil_typetransition_to_avtab(pdb, db, typetrans, NULL, CIL_FALSE, filename_trans_table);
1245}
1246
1247int __cil_perms_to_datum(struct cil_list *perms, class_datum_t *sepol_class, uint32_t *datum)
1248{
1249	int rc = SEPOL_ERR;
1250	char *key = NULL;
1251	struct cil_list_item *curr_perm;
1252	struct cil_perm *cil_perm;
1253	uint32_t data = 0;
1254
1255	cil_list_for_each(curr_perm, perms) {
1256		perm_datum_t *sepol_perm;
1257		cil_perm = curr_perm->data;
1258		key = cil_perm->datum.fqn;
1259		sepol_perm = hashtab_search(sepol_class->permissions.table, key);
1260		if (sepol_perm == NULL) {
1261			common_datum_t *sepol_common = sepol_class->comdatum;
1262			sepol_perm = hashtab_search(sepol_common->permissions.table, key);
1263			if (sepol_perm == NULL) {
1264				cil_log(CIL_ERR, "Failed to find datum for perm %s\n", key);
1265				rc = SEPOL_ERR;
1266				goto exit;
1267			}
1268		}
1269		data |= 1 << (sepol_perm->s.value - 1);
1270	}
1271
1272	*datum = data;
1273
1274	return SEPOL_OK;
1275
1276exit:
1277	return rc;
1278}
1279
1280int __cil_insert_avrule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_t tgt, uint32_t obj, uint32_t data, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1281{
1282	int rc = SEPOL_OK;
1283	avtab_key_t avtab_key;
1284	avtab_datum_t avtab_datum;
1285	avtab_datum_t *avtab_dup = NULL;
1286
1287	avtab_key.source_type = src;
1288	avtab_key.target_type = tgt;
1289	avtab_key.target_class = obj;
1290
1291	switch (kind) {
1292	case CIL_AVRULE_ALLOWED:
1293		avtab_key.specified = AVTAB_ALLOWED;
1294		break;
1295	case CIL_AVRULE_AUDITALLOW:
1296		avtab_key.specified = AVTAB_AUDITALLOW;
1297		break;
1298	case CIL_AVRULE_DONTAUDIT:
1299		avtab_key.specified = AVTAB_AUDITDENY;
1300		break;
1301	default:
1302		rc = SEPOL_ERR;
1303		goto exit;
1304		break;
1305	}
1306
1307	if (!cond_node) {
1308		avtab_dup = avtab_search(&pdb->te_avtab, &avtab_key);
1309		if (!avtab_dup) {
1310			avtab_datum.data = data;
1311			rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum);
1312		} else {
1313			if (kind == CIL_AVRULE_DONTAUDIT)
1314				avtab_dup->data &= data;
1315			else
1316				avtab_dup->data |= data;
1317		}
1318	} else {
1319		avtab_datum.data = data;
1320		rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor);
1321	}
1322
1323exit:
1324	return rc;
1325}
1326
1327static void __cil_neverallow_handle(struct cil_list *neverallows, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, uint32_t class, uint32_t perms)
1328{
1329	struct cil_neverallow *neverallow = neverallows->head->data;
1330	struct cil_list *neverallow_rules = neverallow->rules;
1331	struct cil_neverallow_rule *new = NULL;
1332
1333	new = cil_malloc(sizeof(*new));
1334	new->src = src;
1335	new->tgt = tgt;
1336	new->class = class;
1337	new->perms = perms;
1338
1339	cil_list_append(neverallow_rules, CIL_LIST_ITEM, new);
1340}
1341
1342static int __cil_is_type_match(enum cil_flavor f1, struct cil_symtab_datum *t1, enum cil_flavor f2, struct cil_symtab_datum *t2)
1343{
1344	if (t1->fqn == t2->fqn) {
1345		return CIL_TRUE;
1346	} else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
1347		struct cil_typeattribute *a = (struct cil_typeattribute *)t1;
1348		struct cil_type *t = (struct cil_type *)t2;
1349		if (ebitmap_get_bit(a->types, t->value)) {
1350			return CIL_TRUE;
1351		}
1352	} else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
1353		struct cil_typeattribute *a = (struct cil_typeattribute *)t2;
1354		struct cil_type *t = (struct cil_type *)t1;
1355		if (ebitmap_get_bit(a->types, t->value)) {
1356			return CIL_TRUE;
1357		}
1358	} else if (f1 == CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
1359		struct cil_typeattribute *a1 = (struct cil_typeattribute *)t2;
1360		struct cil_typeattribute *a2 = (struct cil_typeattribute *)t1;
1361		/* abusing the ebitmap abstraction for speed */
1362		ebitmap_node_t *n1 = a1->types->node;
1363		ebitmap_node_t *n2 = a2->types->node;
1364		while (n1 && n2) {
1365			if (n1->startbit < n2->startbit) {
1366				n1 = n1->next;
1367			} else if (n2->startbit < n1->startbit) {
1368				n2 = n2->next;
1369			} else {
1370				if (n1->map & n2->map) {
1371					return CIL_TRUE;
1372				}
1373				n1 = n1->next;
1374				n2 = n2->next;
1375			}
1376		}
1377	}
1378	return CIL_FALSE;
1379}
1380
1381static int __cil_check_neverallows(struct cil_list *neverallows, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, uint32_t class, uint32_t perms)
1382{
1383	struct cil_list_item *curr = NULL;
1384	enum cil_flavor al_src_flavor = ((struct cil_tree_node*)src->nodes->head->data)->flavor;
1385	enum cil_flavor al_tgt_flavor = ((struct cil_tree_node*)tgt->nodes->head->data)->flavor;
1386	cil_list_for_each(curr, neverallows) {
1387		struct cil_neverallow *neverallow = curr->data;
1388		struct cil_tree_node *node = neverallow->node;
1389		struct cil_list_item *curr_item = NULL;
1390		cil_list_for_each(curr_item, neverallow->rules) {
1391			struct cil_neverallow_rule *curr_rule = curr_item->data;
1392			enum cil_flavor nv_src_flavor = ((struct cil_tree_node*)curr_rule->src->nodes->head->data)->flavor;
1393			enum cil_flavor nv_tgt_flavor = ((struct cil_tree_node*)curr_rule->tgt->nodes->head->data)->flavor;
1394			if ((curr_rule->perms & perms) && (class == curr_rule->class)) {
1395				int src_match = __cil_is_type_match(al_src_flavor, src, nv_src_flavor, curr_rule->src);
1396				if (src_match) {
1397					int tgt_match = __cil_is_type_match(al_tgt_flavor, tgt, nv_tgt_flavor, curr_rule->tgt);
1398					if (tgt_match) {
1399						cil_log(CIL_ERR, "Neverallow found that matches avrule at line %d of %s\n", node->line, node->path);
1400						return SEPOL_ERR;
1401					}
1402				}
1403			}
1404		}
1405	}
1406	return SEPOL_OK;
1407}
1408
1409int __cil_avrule_expand_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_classperms *cp, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1410{
1411	int rc = SEPOL_ERR;
1412	type_datum_t *sepol_src = NULL;
1413	type_datum_t *sepol_tgt = NULL;
1414	class_datum_t *sepol_class = NULL;
1415	uint32_t data = 0;
1416
1417	rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class);
1418	if (rc != SEPOL_OK) goto exit;
1419
1420	rc = __cil_perms_to_datum(cp->perms, sepol_class, &data);
1421	if (rc != SEPOL_OK) goto exit;
1422
1423	if (data == 0) {
1424		/* No permissions, so don't insert rule. Maybe should return an error? */
1425		return SEPOL_OK;
1426	}
1427
1428	if (kind == CIL_AVRULE_NEVERALLOW) {
1429		__cil_neverallow_handle(neverallows, src, tgt, sepol_class->s.value, data);
1430	} else {
1431		if (kind == CIL_AVRULE_DONTAUDIT) {
1432			data = ~data;
1433		} else if (neverallows != NULL && kind == CIL_AVRULE_ALLOWED) {
1434			rc = __cil_check_neverallows(neverallows, src, tgt, sepol_class->s.value, data);
1435			if (rc != SEPOL_OK) {
1436				goto exit;
1437			}
1438		}
1439
1440		rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src);
1441		if (rc != SEPOL_OK) goto exit;
1442
1443		rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt);
1444		if (rc != SEPOL_OK) goto exit;
1445
1446		rc = __cil_insert_avrule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_class->s.value, data, cond_node, cond_flavor);
1447		if (rc != SEPOL_OK) {
1448			goto exit;
1449		}
1450	}
1451
1452	return SEPOL_OK;
1453
1454exit:
1455	return rc;
1456}
1457
1458
1459int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_list *classperms, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1460{
1461	int rc = SEPOL_ERR;
1462	struct cil_list_item *curr;
1463
1464	cil_list_for_each(curr, classperms) {
1465		if (curr->flavor == CIL_CLASSPERMS) {
1466			struct cil_classperms *cp = curr->data;
1467			if (FLAVOR(cp->class) == CIL_CLASS) {
1468				rc = __cil_avrule_expand_helper(pdb, kind, src, tgt, cp, neverallows, cond_node, cond_flavor);
1469				if (rc != SEPOL_OK) {
1470					goto exit;
1471				}
1472			} else { /* MAP */
1473				struct cil_list_item *i = NULL;
1474				cil_list_for_each(i, cp->perms) {
1475					struct cil_perm *cmp = i->data;
1476					rc = __cil_avrule_expand(pdb, kind, src, tgt, cmp->classperms, neverallows, cond_node, cond_flavor);
1477					if (rc != SEPOL_OK) {
1478						goto exit;
1479					}
1480				}
1481			}
1482		} else { /* SET */
1483			struct cil_classperms_set *cp_set = curr->data;
1484			struct cil_classpermission *cp = cp_set->set;
1485			rc = __cil_avrule_expand(pdb, kind, src, tgt, cp->classperms, neverallows, cond_node, cond_flavor);
1486			if (rc != SEPOL_OK) {
1487				goto exit;
1488			}
1489		}
1490	}
1491
1492	return SEPOL_OK;
1493
1494exit:
1495	return rc;
1496}
1497
1498int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1499{
1500	int rc = SEPOL_ERR;
1501	uint16_t kind = cil_avrule->rule_kind;
1502	struct cil_symtab_datum *src = NULL;
1503	struct cil_symtab_datum *tgt = NULL;
1504	struct cil_list *classperms = cil_avrule->classperms;
1505
1506	if (cil_avrule->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) {
1507		// Do not add dontaudit rules to binary
1508		rc = SEPOL_OK;
1509		goto exit;
1510	}
1511
1512	if (cil_avrule->rule_kind == CIL_AVRULE_NEVERALLOW && db->disable_neverallow == CIL_TRUE) {
1513		// ignore neverallow rules
1514		rc = SEPOL_OK;
1515		goto exit;
1516	}
1517
1518	src = cil_avrule->src;
1519	tgt = cil_avrule->tgt;
1520
1521	if (tgt->fqn == CIL_KEY_SELF) {
1522		ebitmap_t type_bitmap;
1523		ebitmap_node_t *tnode;
1524		unsigned int i;
1525
1526		rc = __cil_expand_type(src, &type_bitmap);
1527		if (rc != SEPOL_OK) goto exit;
1528
1529		ebitmap_for_each_bit(&type_bitmap, tnode, i) {
1530			if (!ebitmap_get_bit(&type_bitmap, i)) continue;
1531
1532			src = DATUM(db->val_to_type[i]);
1533			rc = __cil_avrule_expand(pdb, kind, src, src, classperms, neverallows, cond_node, cond_flavor);
1534			if (rc != SEPOL_OK) {
1535				ebitmap_destroy(&type_bitmap);
1536				goto exit;
1537			}
1538		}
1539		ebitmap_destroy(&type_bitmap);
1540	} else {
1541		rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, neverallows, cond_node, cond_flavor);
1542		if (rc != SEPOL_OK) goto exit;
1543	}
1544
1545	return SEPOL_OK;
1546
1547exit:
1548	return rc;
1549}
1550
1551int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows)
1552{
1553	return __cil_avrule_to_avtab(pdb, db, cil_avrule, neverallows, NULL, CIL_FALSE);
1554}
1555
1556int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
1557{
1558	int rc;
1559	enum cil_flavor flavor;
1560	struct cil_args_booleanif *args = extra_args;
1561	const struct cil_db *db = args->db;
1562	policydb_t *pdb = args->pdb;
1563	cond_node_t *cond_node = args->cond_node;
1564	enum cil_flavor cond_flavor = args->cond_flavor;
1565	struct cil_type_rule *cil_type_rule;
1566	struct cil_avrule *cil_avrule;
1567	struct cil_nametypetransition *cil_typetrans;
1568	hashtab_t filename_trans_table = args->filename_trans_table;
1569
1570	flavor = node->flavor;
1571	switch (flavor) {
1572	case CIL_NAMETYPETRANSITION:
1573		cil_typetrans = (struct cil_nametypetransition*)node->data;
1574		if (DATUM(cil_typetrans->name)->fqn != CIL_KEY_STAR) {
1575			cil_log(CIL_ERR, "typetransition with file name not allowed within a booleanif block.\n");
1576			cil_log(CIL_ERR,"Invalid typetransition statement at line %d of %s\n",
1577			node->line, node->path);
1578			goto exit;
1579		}
1580		rc = __cil_typetransition_to_avtab(pdb, db, cil_typetrans, cond_node, cond_flavor, filename_trans_table);
1581		if (rc != SEPOL_OK) {
1582			cil_log(CIL_ERR, "Failed to insert type transition into avtab at line %d of %s\n", node->line, node->path);
1583			goto exit;
1584		}
1585		break;
1586	case CIL_TYPE_RULE:
1587		cil_type_rule = node->data;
1588		rc = __cil_type_rule_to_avtab(pdb, db, cil_type_rule, cond_node, cond_flavor);
1589		if (rc != SEPOL_OK) {
1590			cil_log(CIL_ERR, "Failed to insert typerule into avtab at line %d of %s\n", node->line, node->path);
1591			goto exit;
1592		}
1593		break;
1594	case CIL_AVRULE:
1595		cil_avrule = node->data;
1596		rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, args->neverallows, cond_node, cond_flavor);
1597		if (rc != SEPOL_OK) {
1598			cil_log(CIL_ERR, "Failed to insert avrule into avtab at line %d of %s\n", node->line, node->path);
1599			goto exit;
1600		}
1601		break;
1602	case CIL_CALL:
1603	case CIL_TUNABLEIF:
1604		break;
1605	default:
1606		cil_log(CIL_ERR, "Invalid statement within booleanif at line %d of %s\n",
1607			node->line, node->path);
1608		goto exit;
1609	}
1610
1611	return SEPOL_OK;
1612
1613exit:
1614	return SEPOL_ERR;
1615}
1616
1617static int __cil_cond_expr_to_sepol_expr_helper(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **head, cond_expr_t **tail);
1618
1619static int __cil_cond_item_to_sepol_expr(policydb_t *pdb, struct cil_list_item *item, cond_expr_t **head, cond_expr_t **tail)
1620{
1621	if (item == NULL) {
1622		goto exit;
1623	} else if (item->flavor == CIL_DATUM) {
1624		char *key = DATUM(item->data)->fqn;
1625		cond_bool_datum_t *sepol_bool = hashtab_search(pdb->p_bools.table, key);
1626		if (sepol_bool == NULL) {
1627			cil_log(CIL_INFO, "Failed to find boolean\n");
1628			goto exit;
1629		}
1630		*head = cil_malloc(sizeof(cond_expr_t));
1631		(*head)->next = NULL;
1632		(*head)->expr_type = COND_BOOL;
1633		(*head)->bool = sepol_bool->s.value;
1634		*tail = *head;
1635	} else if (item->flavor == CIL_LIST) {
1636		struct cil_list *l = item->data;
1637		int rc = __cil_cond_expr_to_sepol_expr_helper(pdb, l, head, tail);
1638		if (rc != SEPOL_OK) {
1639			goto exit;
1640		}
1641	} else {
1642		goto exit;
1643	}
1644
1645	return SEPOL_OK;
1646
1647exit:
1648	return SEPOL_ERR;
1649}
1650
1651static int __cil_cond_expr_to_sepol_expr_helper(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **head, cond_expr_t **tail)
1652{
1653	int rc = SEPOL_ERR;
1654	struct cil_list_item *item = cil_expr->head;
1655	enum cil_flavor flavor = cil_expr->flavor;
1656	cond_expr_t *op, *h1, *h2, *t1, *t2;
1657
1658	if (flavor != CIL_BOOL) {
1659		cil_log(CIL_INFO, "Expected boolean expression\n");
1660		goto exit;
1661	}
1662
1663	if (item == NULL) {
1664		goto exit;
1665	} else if (item->flavor == CIL_OP) {
1666		enum cil_flavor cil_op = (enum cil_flavor)item->data;
1667
1668		op = cil_malloc(sizeof(*op));
1669		op->bool = 0;
1670		op->next = NULL;
1671
1672		switch (cil_op) {
1673		case CIL_NOT:
1674			op->expr_type = COND_NOT;
1675			break;
1676		case CIL_OR:
1677			op->expr_type = COND_OR;
1678			break;
1679		case CIL_AND:
1680			op->expr_type = COND_AND;
1681			break;
1682		case CIL_XOR:
1683			op->expr_type = COND_XOR;
1684			break;
1685		case CIL_EQ:
1686			op->expr_type = COND_EQ;
1687			break;
1688		case CIL_NEQ:
1689			op->expr_type = COND_NEQ;
1690			break;
1691		default:
1692			goto exit;
1693		}
1694
1695		rc = __cil_cond_item_to_sepol_expr(pdb, item->next, &h1, &t1);
1696		if (rc != SEPOL_OK) {
1697			cil_log(CIL_INFO, "Failed to get first operand of conditional expression\n");
1698			free(op);
1699			goto exit;
1700		}
1701
1702		if (cil_op == CIL_NOT) {
1703			*head = h1;
1704			t1->next = op;
1705			*tail = op;
1706		} else {
1707			rc = __cil_cond_item_to_sepol_expr(pdb, item->next->next, &h2, &t2);
1708			if (rc != SEPOL_OK) {
1709				cil_log(CIL_INFO, "Failed to get second operand of conditional expression\n");
1710				free(op);
1711				cond_expr_destroy(h1);
1712				goto exit;
1713			}
1714
1715			*head = h1;
1716			t1->next = h2;
1717			t2->next = op;
1718			*tail = op;
1719		}
1720	} else {
1721		rc = __cil_cond_item_to_sepol_expr(pdb, item, &h1, &t1);
1722		if (rc != SEPOL_OK) {
1723			cil_log(CIL_INFO, "Failed to get initial item in conditional list\n");
1724			goto exit;
1725		}
1726		*head = h1;
1727		for (item = item->next; item; item = item->next) {
1728			rc = __cil_cond_item_to_sepol_expr(pdb, item, &h2, &t2);
1729			if (rc != SEPOL_OK) {
1730				cil_log(CIL_INFO, "Failed to get item in conditional list\n");
1731				cond_expr_destroy(*head);
1732				goto exit;
1733			}
1734			op = cil_malloc(sizeof(*op));
1735			op->bool = 0;
1736			op->next = NULL;
1737			op->expr_type = COND_OR;
1738			t1->next = h2;
1739			t2->next = op;
1740			t1 = op;
1741		}
1742		*tail = t1;
1743	}
1744
1745	return SEPOL_OK;
1746
1747exit:
1748	return SEPOL_ERR;
1749}
1750
1751static int __cil_cond_expr_to_sepol_expr(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **sepol_expr)
1752{
1753	int rc;
1754	cond_expr_t *head, *tail;
1755
1756	rc = __cil_cond_expr_to_sepol_expr_helper(pdb, cil_expr, &head, &tail);
1757	if (rc != SEPOL_OK) {
1758		return SEPOL_ERR;
1759	}
1760	*sepol_expr = head;
1761
1762	return SEPOL_OK;
1763}
1764
1765int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, struct cil_list *neverallows, hashtab_t filename_trans_table)
1766{
1767	int rc = SEPOL_ERR;
1768	struct cil_args_booleanif bool_args;
1769	struct cil_booleanif *cil_boolif = (struct cil_booleanif*)node->data;
1770	struct cil_tree_node *cb_node = node->cl_head;
1771	struct cil_tree_node *true_node = NULL;
1772	struct cil_tree_node *false_node = NULL;
1773	struct cil_tree_node *tmp_node = NULL;
1774	cond_node_t *tmp_cond = NULL;
1775	cond_node_t *cond_node = NULL;
1776	int was_created;
1777	int swapped = CIL_FALSE;
1778	cond_av_list_t tmp_cl;
1779
1780	tmp_cond = cond_node_create(pdb, NULL);
1781	if (tmp_cond == NULL) {
1782		rc = SEPOL_ERR;
1783		cil_log(CIL_INFO, "Failed to create sepol conditional node at line %d of %s\n",
1784			node->line, node->path);
1785		goto exit;
1786	}
1787
1788	rc = __cil_cond_expr_to_sepol_expr(pdb, cil_boolif->datum_expr, &tmp_cond->expr);
1789	if (rc != SEPOL_OK) {
1790		cil_log(CIL_INFO, "Failed to convert CIL conditional expression to sepol expression at line %d of %s\n", node->line, node->path);
1791		goto exit;
1792	}
1793
1794	tmp_cond->true_list = &tmp_cl;
1795
1796	rc = cond_normalize_expr(pdb, tmp_cond);
1797	if (rc != SEPOL_OK) {
1798		goto exit;
1799	}
1800
1801	if (tmp_cond->false_list != NULL) {
1802		tmp_cond->true_list = NULL;
1803		swapped = CIL_TRUE;
1804	}
1805
1806	cond_node = cond_node_find(pdb, tmp_cond, pdb->cond_list, &was_created);
1807	if (cond_node == NULL) {
1808		rc = SEPOL_ERR;
1809		goto exit;
1810	}
1811
1812	if (was_created) {
1813		cond_node->next = pdb->cond_list;
1814		pdb->cond_list = cond_node;
1815	}
1816
1817	cond_expr_destroy(tmp_cond->expr);
1818	free(tmp_cond);
1819
1820	for (cb_node = node->cl_head; cb_node != NULL; cb_node = cb_node->next) {
1821		if (cb_node->flavor == CIL_CONDBLOCK) {
1822			struct cil_condblock *cb = cb_node->data;
1823			if (cb->flavor == CIL_CONDTRUE) {
1824					true_node = cb_node;
1825			} else if (cb->flavor == CIL_CONDFALSE) {
1826					false_node = cb_node;
1827			}
1828		}
1829	}
1830
1831	if (swapped) {
1832		tmp_node = true_node;
1833		true_node = false_node;
1834		false_node = tmp_node;
1835	}
1836
1837	bool_args.db = db;
1838	bool_args.pdb = pdb;
1839	bool_args.cond_node = cond_node;
1840	bool_args.neverallows = neverallows;
1841	bool_args.filename_trans_table = filename_trans_table;
1842
1843	if (true_node != NULL) {
1844		bool_args.cond_flavor = CIL_CONDTRUE;
1845		rc = cil_tree_walk(true_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args);
1846		if (rc != SEPOL_OK) {
1847			cil_log(CIL_ERR, "Failure while walking true conditional block at line %d of %s\n", true_node->line, true_node->path);
1848			goto exit;
1849		}
1850	}
1851
1852	if (false_node != NULL) {
1853		bool_args.cond_flavor = CIL_CONDFALSE;
1854		rc = cil_tree_walk(false_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args);
1855		if (rc != SEPOL_OK) {
1856			cil_log(CIL_ERR, "Failure while walking false conditional block at line %d of %s\n", false_node->line, false_node->path);
1857			goto exit;
1858		}
1859	}
1860
1861	return SEPOL_OK;
1862
1863exit:
1864	return rc;
1865}
1866
1867int cil_roletrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roletransition *roletrans, hashtab_t role_trans_table)
1868{
1869	int rc = SEPOL_ERR;
1870	role_datum_t *sepol_src = NULL;
1871	type_datum_t *sepol_tgt = NULL;
1872	class_datum_t *sepol_obj = NULL;
1873	struct cil_list *class_list;
1874	role_datum_t *sepol_result = NULL;
1875	role_trans_t *new = NULL;
1876	uint32_t *new_role = NULL;
1877	ebitmap_t role_bitmap, type_bitmap;
1878	ebitmap_node_t *rnode, *tnode;
1879	unsigned int i, j;
1880	struct cil_list_item *c;
1881
1882	rc = __cil_expand_role(DATUM(roletrans->src), &role_bitmap);
1883	if (rc != SEPOL_OK) goto exit;
1884
1885	rc = __cil_expand_type(roletrans->tgt, &type_bitmap);
1886	if (rc != SEPOL_OK) goto exit;
1887
1888	class_list = cil_expand_class(roletrans->obj);
1889
1890	rc = __cil_get_sepol_role_datum(pdb, DATUM(roletrans->result), &sepol_result);
1891	if (rc != SEPOL_OK) goto exit;
1892
1893	ebitmap_for_each_bit(&role_bitmap, rnode, i) {
1894		if (!ebitmap_get_bit(&role_bitmap, i)) continue;
1895
1896		rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src);
1897		if (rc != SEPOL_OK) goto exit;
1898
1899		ebitmap_for_each_bit(&type_bitmap, tnode, j) {
1900			if (!ebitmap_get_bit(&type_bitmap, j)) continue;
1901
1902			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
1903			if (rc != SEPOL_OK) goto exit;
1904
1905			cil_list_for_each(c, class_list) {
1906				int add = CIL_TRUE;
1907				rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
1908				if (rc != SEPOL_OK) goto exit;
1909
1910				new = cil_malloc(sizeof(*new));
1911				memset(new, 0, sizeof(*new));
1912				new->role = sepol_src->s.value;
1913				new->type = sepol_tgt->s.value;
1914				new->tclass = sepol_obj->s.value;
1915				new->new_role = sepol_result->s.value;
1916
1917				rc = SEPOL_OK;
1918				rc = hashtab_insert(role_trans_table, (hashtab_key_t)new, &(new->new_role));
1919				if (rc != SEPOL_OK) {
1920					if (rc == SEPOL_EEXIST) {
1921						add = CIL_FALSE;
1922						new_role = hashtab_search(role_trans_table, (hashtab_key_t)new);
1923						if (new->new_role != *new_role) {
1924							cil_log(CIL_ERR, "Conflicting role transition rules\n");
1925						} else {
1926							rc = SEPOL_OK;
1927						}
1928					} else {
1929						cil_log(CIL_ERR, "Out of memory\n");
1930					}
1931				}
1932
1933				if (add == CIL_TRUE) {
1934					new->next = pdb->role_tr;
1935					pdb->role_tr = new;
1936				} else {
1937					free(new);
1938					if (rc != SEPOL_OK) {
1939						goto exit;
1940					}
1941				}
1942			}
1943		}
1944	}
1945
1946	rc = SEPOL_OK;
1947
1948exit:
1949	ebitmap_destroy(&role_bitmap);
1950	ebitmap_destroy(&type_bitmap);
1951	cil_list_destroy(&class_list, CIL_FALSE);
1952	return rc;
1953}
1954
1955int cil_roleallow_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roleallow *roleallow)
1956{
1957	int rc = SEPOL_ERR;
1958	role_datum_t *sepol_src = NULL;
1959	role_datum_t *sepol_tgt = NULL;
1960	role_allow_t *sepol_roleallow = NULL;
1961	ebitmap_t src_bitmap, tgt_bitmap;
1962	ebitmap_node_t *node1, *node2;
1963	unsigned int i, j;
1964
1965	rc = __cil_expand_role(roleallow->src, &src_bitmap);
1966	if (rc != SEPOL_OK) goto exit;
1967
1968	rc = __cil_expand_role(roleallow->tgt, &tgt_bitmap);
1969	if (rc != SEPOL_OK) goto exit;
1970
1971	ebitmap_for_each_bit(&src_bitmap, node1, i) {
1972		if (!ebitmap_get_bit(&src_bitmap, i)) continue;
1973
1974		rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src);
1975		if (rc != SEPOL_OK) goto exit;
1976
1977		ebitmap_for_each_bit(&tgt_bitmap, node2, j) {
1978			if (!ebitmap_get_bit(&tgt_bitmap, j)) continue;
1979
1980			rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[j]), &sepol_tgt);
1981			if (rc != SEPOL_OK) goto exit;
1982
1983			sepol_roleallow = cil_malloc(sizeof(*sepol_roleallow));
1984			memset(sepol_roleallow, 0, sizeof(role_allow_t));
1985			sepol_roleallow->role = sepol_src->s.value;
1986			sepol_roleallow->new_role = sepol_tgt->s.value;
1987
1988			sepol_roleallow->next = pdb->role_allow;
1989			pdb->role_allow = sepol_roleallow;
1990		}
1991	}
1992
1993	rc = SEPOL_OK;
1994
1995exit:
1996	ebitmap_destroy(&src_bitmap);
1997	ebitmap_destroy(&tgt_bitmap);
1998	return rc;
1999}
2000
2001int __cil_constrain_expr_datum_to_sepol_expr(policydb_t *pdb, const struct cil_db *db, struct cil_list_item *item, enum cil_flavor expr_flavor, constraint_expr_t *expr)
2002{
2003	int rc = SEPOL_ERR;
2004
2005	if (expr_flavor == CIL_USER) {
2006		user_datum_t *sepol_user = NULL;
2007		rc = __cil_get_sepol_user_datum(pdb, item->data, &sepol_user);
2008		if (rc != SEPOL_OK) goto exit;
2009
2010		if (ebitmap_set_bit(&expr->names, sepol_user->s.value - 1, 1)) {
2011			goto exit;
2012		}
2013	} else if (expr_flavor == CIL_ROLE) {
2014		role_datum_t *sepol_role = NULL;
2015		ebitmap_t role_bitmap;
2016		ebitmap_node_t *rnode;
2017		unsigned int i;
2018
2019		rc = __cil_expand_role(item->data, &role_bitmap);
2020		if (rc != SEPOL_OK) goto exit;
2021
2022		ebitmap_for_each_bit(&role_bitmap, rnode, i) {
2023			if (!ebitmap_get_bit(&role_bitmap, i)) continue;
2024
2025			rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role);
2026			if (rc != SEPOL_OK) {
2027				ebitmap_destroy(&role_bitmap);
2028				goto exit;
2029			}
2030
2031			if (ebitmap_set_bit(&expr->names, sepol_role->s.value - 1, 1)) {
2032				ebitmap_destroy(&role_bitmap);
2033				goto exit;
2034			}
2035		}
2036		ebitmap_destroy(&role_bitmap);
2037	} else if (expr_flavor == CIL_TYPE) {
2038		type_datum_t *sepol_type = NULL;
2039		ebitmap_t type_bitmap;
2040		ebitmap_node_t *tnode;
2041		unsigned int i;
2042
2043		if (pdb->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) {
2044			rc = __cil_get_sepol_type_datum(pdb, item->data, &sepol_type);
2045			if (rc != SEPOL_OK) {
2046				ebitmap_destroy(&type_bitmap);
2047				goto exit;
2048			}
2049
2050			if (ebitmap_set_bit(&expr->type_names->types, sepol_type->s.value - 1, 1)) {
2051				ebitmap_destroy(&type_bitmap);
2052				goto exit;
2053			}
2054		}
2055
2056		rc = __cil_expand_type(item->data, &type_bitmap);
2057		if (rc != SEPOL_OK) goto exit;
2058
2059		ebitmap_for_each_bit(&type_bitmap, tnode, i) {
2060			if (!ebitmap_get_bit(&type_bitmap, i)) continue;
2061
2062			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type);
2063			if (rc != SEPOL_OK) {
2064				ebitmap_destroy(&type_bitmap);
2065				goto exit;
2066			}
2067
2068			if (ebitmap_set_bit(&expr->names, sepol_type->s.value - 1, 1)) {
2069				ebitmap_destroy(&type_bitmap);
2070				goto exit;
2071			}
2072		}
2073		ebitmap_destroy(&type_bitmap);
2074	} else {
2075		goto exit;
2076	}
2077
2078	return SEPOL_OK;
2079
2080exit:
2081	return SEPOL_ERR;
2082}
2083
2084int __cil_constrain_expr_leaf_to_sepol_expr(policydb_t *pdb, const struct cil_db *db, struct cil_list_item *op_item, enum cil_flavor expr_flavor, constraint_expr_t *expr)
2085{
2086	int rc = SEPOL_ERR;
2087	struct cil_list_item *l_item = op_item->next;
2088	struct cil_list_item *r_item = op_item->next->next;
2089
2090	enum cil_flavor l_operand = (enum cil_flavor)l_item->data;
2091
2092	switch (l_operand) {
2093	case CIL_CONS_U1:
2094		expr->attr = CEXPR_USER;
2095		break;
2096	case CIL_CONS_U2:
2097		expr->attr = CEXPR_USER | CEXPR_TARGET;
2098		break;
2099	case CIL_CONS_U3:
2100		expr->attr = CEXPR_USER | CEXPR_XTARGET;
2101		break;
2102	case CIL_CONS_R1:
2103		expr->attr = CEXPR_ROLE;
2104		break;
2105	case CIL_CONS_R2:
2106		expr->attr = CEXPR_ROLE | CEXPR_TARGET;
2107		break;
2108	case CIL_CONS_R3:
2109		expr->attr = CEXPR_ROLE | CEXPR_XTARGET;
2110		break;
2111	case CIL_CONS_T1:
2112		expr->attr = CEXPR_TYPE;
2113		break;
2114	case CIL_CONS_T2:
2115		expr->attr = CEXPR_TYPE | CEXPR_TARGET;
2116		break;
2117	case CIL_CONS_T3:
2118		expr->attr = CEXPR_TYPE | CEXPR_XTARGET;
2119		break;
2120	case CIL_CONS_L1: {
2121		enum cil_flavor r_operand = (enum cil_flavor)r_item->data;
2122
2123		if (r_operand == CIL_CONS_L2) {
2124			expr->attr = CEXPR_L1L2;
2125		} else if (r_operand == CIL_CONS_H1) {
2126			expr->attr = CEXPR_L1H1;
2127		} else {
2128			expr->attr = CEXPR_L1H2;
2129		}
2130		break;
2131	}
2132	case CIL_CONS_L2:
2133		expr->attr = CEXPR_L2H2;
2134		break;
2135	case CIL_CONS_H1: {
2136		enum cil_flavor r_operand = (enum cil_flavor)r_item->data;
2137		if (r_operand == CIL_CONS_L2) {
2138			expr->attr = CEXPR_H1L2;
2139		} else {
2140			expr->attr = CEXPR_H1H2;
2141		}
2142		break;
2143	}
2144	default:
2145		goto exit;
2146		break;
2147	}
2148
2149	if (r_item->flavor == CIL_CONS_OPERAND) {
2150		expr->expr_type = CEXPR_ATTR;
2151	} else {
2152		expr->expr_type = CEXPR_NAMES;
2153		if (r_item->flavor == CIL_DATUM) {
2154			rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, r_item, expr_flavor, expr);
2155			if (rc != SEPOL_OK) {
2156				goto exit;
2157			}
2158		} else if (r_item->flavor == CIL_LIST) {
2159			struct cil_list *r_expr = r_item->data;
2160			struct cil_list_item *curr;
2161			cil_list_for_each(curr, r_expr) {
2162				rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, curr, expr_flavor, expr);
2163				if (rc != SEPOL_OK) {
2164					goto exit;
2165				}
2166			}
2167		} else {
2168			rc = SEPOL_ERR;
2169			goto exit;
2170		}
2171	}
2172
2173	return SEPOL_OK;
2174
2175exit:
2176	return rc;
2177}
2178
2179int __cil_constrain_expr_to_sepol_expr_helper(policydb_t *pdb, const struct cil_db *db, const struct cil_list *cil_expr, constraint_expr_t **head, constraint_expr_t **tail)
2180{
2181	int rc = SEPOL_ERR;
2182	struct cil_list_item *item;
2183	enum cil_flavor flavor;
2184	constraint_expr_t *op, *h1, *h2, *t1, *t2;
2185	int is_leaf = CIL_FALSE;
2186
2187	if (cil_expr == NULL) {
2188		return SEPOL_ERR;
2189	}
2190
2191	item = cil_expr->head;
2192	flavor = cil_expr->flavor;
2193
2194	op = cil_malloc(sizeof(constraint_expr_t));
2195	rc = constraint_expr_init(op);
2196	if (rc != SEPOL_OK) {
2197		goto exit;
2198	}
2199
2200	enum cil_flavor cil_op = (enum cil_flavor)item->data;
2201	switch (cil_op) {
2202	case CIL_NOT:
2203		op->expr_type = CEXPR_NOT;
2204		break;
2205	case CIL_AND:
2206		op->expr_type = CEXPR_AND;
2207		break;
2208	case CIL_OR:
2209		op->expr_type = CEXPR_OR;
2210		break;
2211	case CIL_EQ:
2212		op->op = CEXPR_EQ;
2213		is_leaf = CIL_TRUE;
2214		break;
2215	case CIL_NEQ:
2216		op->op = CEXPR_NEQ;
2217		is_leaf = CIL_TRUE;
2218		break;
2219	case CIL_CONS_DOM:
2220		op->op = CEXPR_DOM;
2221		is_leaf = CIL_TRUE;
2222		break;
2223	case CIL_CONS_DOMBY:
2224		op->op = CEXPR_DOMBY;
2225		is_leaf = CIL_TRUE;
2226		break;
2227	case CIL_CONS_INCOMP:
2228		op->op = CEXPR_INCOMP;
2229		is_leaf = CIL_TRUE;
2230		break;
2231	default:
2232		goto exit;
2233	}
2234
2235	if (is_leaf == CIL_TRUE) {
2236		rc = __cil_constrain_expr_leaf_to_sepol_expr(pdb, db, item, flavor, op);
2237		if (rc != SEPOL_OK) {
2238			goto exit;
2239		}
2240		*head = op;
2241		*tail = op;
2242	} else if (cil_op == CIL_NOT) {
2243		struct cil_list *l_expr = item->next->data;
2244		rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1);
2245		if (rc != SEPOL_OK) {
2246			goto exit;
2247		}
2248		t1->next = op;
2249		*head = h1;
2250		*tail = op;
2251	} else {
2252		struct cil_list *l_expr = item->next->data;
2253		struct cil_list *r_expr = item->next->next->data;
2254		rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1);
2255		if (rc != SEPOL_OK) {
2256			goto exit;
2257		}
2258		rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, r_expr, &h2, &t2);
2259		if (rc != SEPOL_OK) {
2260			constraint_expr_destroy(h1);
2261			goto exit;
2262		}
2263		t1->next = h2;
2264		t2->next = op;
2265		*head = h1;
2266		*tail = op;
2267	}
2268
2269	return SEPOL_OK;
2270
2271exit:
2272	constraint_expr_destroy(op);
2273	return SEPOL_ERR;
2274}
2275
2276int __cil_constrain_expr_to_sepol_expr(policydb_t *pdb, const struct cil_db *db, const struct cil_list *cil_expr, constraint_expr_t **sepol_expr)
2277{
2278	int rc;
2279	constraint_expr_t *head, *tail;
2280
2281	rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, cil_expr, &head, &tail);
2282	if (rc != SEPOL_OK) {
2283		return SEPOL_ERR;
2284	}
2285
2286	*sepol_expr = head;
2287
2288	return SEPOL_OK;
2289}
2290
2291int cil_constrain_to_policydb_helper(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *class, struct cil_list *perms, struct cil_list *expr)
2292{
2293	int rc = SEPOL_ERR;
2294	constraint_node_t *sepol_constrain = NULL;
2295	constraint_expr_t *sepol_expr = NULL;
2296	class_datum_t *sepol_class = NULL;
2297
2298	sepol_constrain = cil_malloc(sizeof(*sepol_constrain));
2299	memset(sepol_constrain, 0, sizeof(constraint_node_t));
2300
2301	rc = __cil_get_sepol_class_datum(pdb, class, &sepol_class);
2302	if (rc != SEPOL_OK) goto exit;
2303
2304	rc = __cil_perms_to_datum(perms, sepol_class, &sepol_constrain->permissions);
2305	if (rc != SEPOL_OK) {
2306		goto exit;
2307	}
2308
2309	rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr);
2310	if (rc != SEPOL_OK) {
2311		goto exit;
2312	}
2313
2314	sepol_constrain->expr = sepol_expr;
2315	sepol_constrain->next = sepol_class->constraints;
2316	sepol_class->constraints = sepol_constrain;
2317
2318	return SEPOL_OK;
2319
2320exit:
2321	free(sepol_constrain);
2322	return rc;
2323}
2324
2325int cil_constrain_expand(policydb_t *pdb, const struct cil_db *db, struct cil_list *classperms, struct cil_list *expr)
2326{
2327	int rc = SEPOL_ERR;
2328	struct cil_list_item *curr;
2329
2330	cil_list_for_each(curr, classperms) {
2331		if (curr->flavor == CIL_CLASSPERMS) {
2332			struct cil_classperms *cp = curr->data;
2333			if (FLAVOR(cp->class) == CIL_CLASS) {
2334				rc = cil_constrain_to_policydb_helper(pdb, db, DATUM(cp->class), cp->perms, expr);
2335				if (rc != SEPOL_OK) {
2336					goto exit;
2337				}
2338			} else { /* MAP */
2339				struct cil_list_item *i = NULL;
2340				cil_list_for_each(i, cp->perms) {
2341					struct cil_perm *cmp = i->data;
2342					rc = cil_constrain_expand(pdb, db, cmp->classperms, expr);
2343					if (rc != SEPOL_OK) {
2344						goto exit;
2345					}
2346				}
2347			}
2348		} else { /* SET */
2349			struct cil_classperms_set *cp_set = curr->data;
2350			struct cil_classpermission *cp = cp_set->set;
2351			rc = cil_constrain_expand(pdb, db, cp->classperms, expr);
2352			if (rc != SEPOL_OK) {
2353				goto exit;
2354			}
2355		}
2356	}
2357
2358	return SEPOL_OK;
2359
2360exit:
2361	return rc;
2362}
2363
2364int cil_constrain_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_constrain *cil_constrain)
2365{
2366	int rc = SEPOL_ERR;
2367	rc = cil_constrain_expand(pdb, db, cil_constrain->classperms, cil_constrain->datum_expr);
2368	if (rc != SEPOL_OK) {
2369		goto exit;
2370	}
2371
2372	return SEPOL_OK;
2373
2374exit:
2375	cil_log(CIL_ERR, "Failed to insert constraint into policydb\n");
2376	return rc;
2377}
2378
2379int cil_validatetrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_validatetrans *cil_validatetrans)
2380{
2381	int rc = SEPOL_ERR;
2382	struct cil_list *expr = cil_validatetrans->datum_expr;
2383	class_datum_t *sepol_class = NULL;
2384	struct cil_list *class_list;
2385	constraint_node_t *sepol_validatetrans = NULL;
2386	constraint_expr_t *sepol_expr = NULL;
2387	struct cil_list_item *c;
2388
2389	class_list = cil_expand_class(cil_validatetrans->class);
2390
2391	cil_list_for_each(c, class_list) {
2392		rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
2393		if (rc != SEPOL_OK) goto exit;
2394
2395		sepol_validatetrans = cil_malloc(sizeof(*sepol_validatetrans));
2396		memset(sepol_validatetrans, 0, sizeof(constraint_node_t));
2397
2398		rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr);
2399		if (rc != SEPOL_OK) {
2400			free(sepol_validatetrans);
2401			goto exit;
2402		}
2403		sepol_validatetrans->expr = sepol_expr;
2404
2405		sepol_validatetrans->next = sepol_class->validatetrans;
2406		sepol_class->validatetrans = sepol_validatetrans;
2407	}
2408
2409	rc = SEPOL_OK;
2410
2411exit:
2412	cil_list_destroy(&class_list, CIL_FALSE);
2413	return rc;
2414}
2415
2416int __cil_cats_to_mls_level(policydb_t *pdb, struct cil_cats *cats, mls_level_t *mls_level)
2417{
2418	int rc = SEPOL_ERR;
2419	struct cil_list_item *i;
2420	cat_datum_t *sepol_cat = NULL;
2421
2422	cil_list_for_each(i, cats->datum_expr) {
2423		struct cil_tree_node *node = DATUM(i->data)->nodes->head->data;
2424		if (node->flavor == CIL_CATSET) {
2425			struct cil_list_item *j;
2426			struct cil_catset *cs = i->data;
2427			cil_list_for_each(j, cs->cats->datum_expr) {
2428				rc = __cil_get_sepol_cat_datum(pdb, j->data, &sepol_cat);
2429				if (rc != SEPOL_OK) goto exit;
2430
2431				rc = ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1);
2432				if (rc != SEPOL_OK) goto exit;
2433			}
2434		} else {
2435			rc = __cil_get_sepol_cat_datum(pdb, i->data, &sepol_cat);
2436			if (rc != SEPOL_OK) goto exit;
2437
2438			rc = ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1);
2439			if (rc != SEPOL_OK) goto exit;
2440		}
2441	}
2442
2443	return SEPOL_OK;
2444
2445exit:
2446	return SEPOL_ERR;
2447}
2448
2449int cil_sepol_level_define(policydb_t *pdb, struct cil_sens *cil_sens)
2450{
2451	int rc = SEPOL_ERR;
2452	struct cil_list_item *curr;
2453	level_datum_t *sepol_level = NULL;
2454	mls_level_t *mls_level = NULL;
2455
2456	rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level);
2457	if (rc != SEPOL_OK) goto exit;
2458
2459	mls_level = sepol_level->level;
2460
2461	ebitmap_init(&mls_level->cat);
2462
2463	if (cil_sens->cats_list) {
2464		cil_list_for_each(curr, cil_sens->cats_list) {
2465			struct cil_cats *cats = curr->data;
2466			rc = __cil_cats_to_mls_level(pdb, cats, mls_level);
2467			if (rc != SEPOL_OK) {
2468				cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n");
2469				goto exit;
2470			}
2471		}
2472	}
2473
2474	sepol_level->defined = 1;
2475
2476	return SEPOL_OK;
2477
2478exit:
2479	return rc;
2480}
2481
2482int cil_level_to_mls_level(policydb_t *pdb, struct cil_level *cil_level, mls_level_t *mls_level)
2483{
2484	int rc = SEPOL_ERR;
2485	struct cil_sens *cil_sens = cil_level->sens;
2486	struct cil_cats *cats = cil_level->cats;
2487	level_datum_t *sepol_level = NULL;
2488
2489	rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level);
2490	if (rc != SEPOL_OK) goto exit;
2491
2492	mls_level->sens = sepol_level->level->sens;
2493
2494	ebitmap_init(&mls_level->cat);
2495
2496	if (cats != NULL) {
2497		rc = __cil_cats_to_mls_level(pdb, cats, mls_level);
2498		if (rc != SEPOL_OK) {
2499			cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n");
2500			goto exit;
2501		}
2502	}
2503
2504	rc = SEPOL_OK;
2505exit:
2506	return rc;
2507}
2508
2509int __cil_levelrange_to_mls_range(policydb_t *pdb, struct cil_levelrange *cil_lvlrange, mls_range_t *mls_range)
2510{
2511	int rc = SEPOL_ERR;
2512	struct cil_level *low = cil_lvlrange->low;
2513	struct cil_level *high = cil_lvlrange->high;
2514	mls_level_t *mls_level = NULL;
2515
2516	mls_level = &mls_range->level[0];
2517
2518	rc = cil_level_to_mls_level(pdb, low, mls_level);
2519	if (rc != SEPOL_OK) {
2520		goto exit;
2521	}
2522
2523	mls_level = &mls_range->level[1];
2524
2525	rc = cil_level_to_mls_level(pdb, high, mls_level);
2526	if (rc != SEPOL_OK) {
2527		goto exit;
2528	}
2529
2530	return SEPOL_OK;
2531
2532exit:
2533	return rc;
2534}
2535
2536int cil_userlevel_userrange_to_policydb(policydb_t *pdb, struct cil_user *cil_user)
2537{
2538	int rc = SEPOL_ERR;
2539	struct cil_level *cil_level = cil_user->dftlevel;
2540	struct cil_levelrange *cil_levelrange = cil_user->range;
2541	user_datum_t *sepol_user = NULL;
2542
2543	rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user), &sepol_user);
2544	if (rc != SEPOL_OK) goto exit;
2545
2546	rc = cil_level_to_mls_level(pdb, cil_level, &sepol_user->exp_dfltlevel);
2547	if (rc != SEPOL_OK) {
2548		goto exit;
2549	}
2550
2551	rc = __cil_levelrange_to_mls_range(pdb, cil_levelrange, &sepol_user->exp_range);
2552	if (rc != SEPOL_OK) {
2553		goto exit;
2554	}
2555
2556	return SEPOL_OK;
2557
2558exit:
2559	return rc;
2560}
2561
2562int __cil_context_to_sepol_context(policydb_t *pdb, struct cil_context *cil_context, context_struct_t *sepol_context)
2563{
2564	int rc = SEPOL_ERR;
2565	struct cil_levelrange *cil_lvlrange = cil_context->range;
2566	user_datum_t *sepol_user = NULL;
2567	role_datum_t *sepol_role = NULL;
2568	type_datum_t *sepol_type = NULL;
2569
2570	rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_context->user), &sepol_user);
2571	if (rc != SEPOL_OK) goto exit;
2572
2573	rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_context->role), &sepol_role);
2574	if (rc != SEPOL_OK) goto exit;
2575
2576	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_context->type), &sepol_type);
2577	if (rc != SEPOL_OK) goto exit;
2578
2579	sepol_context->user = sepol_user->s.value;
2580	sepol_context->role = sepol_role->s.value;
2581	sepol_context->type = sepol_type->s.value;
2582
2583	if (pdb->mls == CIL_TRUE) {
2584		mls_context_init(sepol_context);
2585
2586		rc = __cil_levelrange_to_mls_range(pdb, cil_lvlrange, &sepol_context->range);
2587		if (rc != SEPOL_OK) {
2588			cil_log(CIL_ERR,"Problem with MLS\n");
2589			mls_context_destroy(sepol_context);
2590			goto exit;
2591		}
2592	}
2593
2594	return SEPOL_OK;
2595
2596exit:
2597	return rc;
2598}
2599
2600int cil_sidorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
2601{
2602	int rc = SEPOL_ERR;
2603	struct cil_list_item *curr;
2604	unsigned count = 0;
2605	ocontext_t *tail = NULL;
2606
2607	if (db->sidorder == NULL || db->sidorder->head == NULL) {
2608		cil_log(CIL_WARN, "No sidorder statement in policy\n");
2609		return SEPOL_OK;
2610	}
2611
2612	cil_list_for_each(curr, db->sidorder) {
2613		struct cil_sid *cil_sid = (struct cil_sid*)curr->data;
2614		struct cil_context *cil_context = cil_sid->context;
2615
2616		if (cil_context != NULL) {
2617			ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_ISID], &tail);
2618			count++;
2619			new_ocon->sid[0] = count;
2620			new_ocon->u.name = cil_strdup(cil_sid->datum.fqn);
2621			rc = __cil_context_to_sepol_context(pdb, cil_context, &new_ocon->context[0]);
2622			if (rc != SEPOL_OK) {
2623				cil_log(CIL_ERR,"Problem with context for SID %s\n",cil_sid->datum.fqn);
2624				goto exit;
2625			}
2626		}
2627	}
2628
2629	return SEPOL_OK;
2630
2631exit:
2632	return rc;
2633}
2634
2635int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_rangetransition *rangetrans, hashtab_t range_trans_table)
2636{
2637	int rc = SEPOL_ERR;
2638	type_datum_t *sepol_src = NULL;
2639	type_datum_t *sepol_tgt = NULL;
2640	class_datum_t *sepol_class = NULL;
2641	struct cil_list *class_list;
2642	range_trans_t *new;
2643	ebitmap_t src_bitmap, tgt_bitmap;
2644	ebitmap_node_t *node1, *node2;
2645	unsigned int i, j;
2646	struct cil_list_item *c;
2647	struct mls_range *o_range = NULL;
2648
2649	rc = __cil_expand_type(rangetrans->src, &src_bitmap);
2650	if (rc != SEPOL_OK) goto exit;
2651
2652	rc = __cil_expand_type(rangetrans->exec, &tgt_bitmap);
2653	if (rc != SEPOL_OK) goto exit;
2654
2655	class_list = cil_expand_class(rangetrans->obj);
2656
2657	ebitmap_for_each_bit(&src_bitmap, node1, i) {
2658		if (!ebitmap_get_bit(&src_bitmap, i)) continue;
2659
2660		rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src);
2661		if (rc != SEPOL_OK) goto exit;
2662
2663		ebitmap_for_each_bit(&tgt_bitmap, node2, j) {
2664			if (!ebitmap_get_bit(&tgt_bitmap, j)) continue;
2665
2666			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
2667			if (rc != SEPOL_OK) goto exit;
2668
2669			cil_list_for_each(c, class_list) {
2670				int add = CIL_TRUE;
2671				rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
2672				if (rc != SEPOL_OK) goto exit;
2673
2674				new = cil_malloc(sizeof(*new));
2675				memset(new, 0, sizeof(range_trans_t));
2676				new->source_type = sepol_src->s.value;
2677				new->target_type = sepol_tgt->s.value;
2678				new->target_class = sepol_class->s.value;
2679				rc = __cil_levelrange_to_mls_range(pdb, rangetrans->range, &new->target_range);
2680				if (rc != SEPOL_OK) {
2681					free(new);
2682					goto exit;
2683				}
2684
2685				rc = SEPOL_OK;
2686				rc = hashtab_insert(range_trans_table, (hashtab_key_t)new, &(new->target_range));
2687				if (rc != SEPOL_OK) {
2688					if (rc == SEPOL_EEXIST) {
2689						add = CIL_FALSE;
2690						o_range = hashtab_search(range_trans_table, (hashtab_key_t)new);
2691						if (!mls_range_eq(&new->target_range, o_range)) {
2692							cil_log(CIL_ERR, "Conflicting Range transition rules\n");
2693						} else {
2694							rc = SEPOL_OK;
2695						}
2696					} else {
2697						cil_log(CIL_ERR, "Out of memory\n");
2698					}
2699				}
2700
2701				if (add == CIL_TRUE) {
2702					new->next = pdb->range_tr;
2703					pdb->range_tr = new;
2704				} else {
2705					mls_range_destroy(&new->target_range);
2706					free(new);
2707					if (rc != SEPOL_OK) {
2708						goto exit;
2709					}
2710				}
2711			}
2712		}
2713	}
2714
2715	rc = SEPOL_OK;
2716
2717exit:
2718	ebitmap_destroy(&src_bitmap);
2719	ebitmap_destroy(&tgt_bitmap);
2720	cil_list_destroy(&class_list, CIL_FALSE);
2721	return rc;
2722}
2723
2724int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons)
2725{
2726	int rc = SEPOL_ERR;
2727	uint32_t i = 0;
2728	ocontext_t *tail = NULL;
2729
2730	for (i = 0; i < portcons->count; i++) {
2731		struct cil_portcon *cil_portcon = portcons->array[i];
2732		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_PORT], &tail);
2733
2734		switch (cil_portcon->proto) {
2735		case CIL_PROTOCOL_UDP:
2736			new_ocon->u.port.protocol = IPPROTO_UDP;
2737			break;
2738		case CIL_PROTOCOL_TCP:
2739			new_ocon->u.port.protocol = IPPROTO_TCP;
2740			break;
2741		default:
2742			/* should not get here */
2743			rc = SEPOL_ERR;
2744			goto exit;
2745		}
2746
2747		new_ocon->u.port.low_port = cil_portcon->port_low;
2748		new_ocon->u.port.high_port = cil_portcon->port_high;
2749
2750		rc = __cil_context_to_sepol_context(pdb, cil_portcon->context, &new_ocon->context[0]);
2751		if (rc != SEPOL_OK) {
2752			goto exit;
2753		}
2754	}
2755
2756	return SEPOL_OK;
2757
2758exit:
2759	return rc;
2760}
2761
2762int cil_netifcon_to_policydb(policydb_t *pdb, struct cil_sort *netifcons)
2763{
2764	int rc = SEPOL_ERR;
2765	uint32_t i = 0;
2766	ocontext_t *tail = NULL;
2767
2768	for (i = 0; i < netifcons->count; i++) {
2769		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NETIF], &tail);
2770		struct cil_netifcon *cil_netifcon = netifcons->array[i];
2771
2772		new_ocon->u.name = cil_strdup(cil_netifcon->interface_str);
2773
2774		rc = __cil_context_to_sepol_context(pdb, cil_netifcon->if_context, &new_ocon->context[0]);
2775		if (rc != SEPOL_OK) {
2776			goto exit;
2777		}
2778
2779		rc = __cil_context_to_sepol_context(pdb, cil_netifcon->packet_context, &new_ocon->context[1]);
2780		if (rc != SEPOL_OK) {
2781			context_destroy(&new_ocon->context[0]);
2782			goto exit;
2783		}
2784	}
2785
2786	return SEPOL_OK;
2787
2788exit:
2789	return rc;
2790}
2791
2792int cil_nodecon_to_policydb(policydb_t *pdb, struct cil_sort *nodecons)
2793{
2794	int rc = SEPOL_ERR;
2795	uint32_t i = 0;
2796	ocontext_t *tail = NULL;
2797	ocontext_t *tail6 = NULL;
2798
2799	for (i = 0; i < nodecons->count; i++) {
2800		ocontext_t *new_ocon = NULL;
2801		struct cil_nodecon *cil_nodecon = nodecons->array[i];
2802
2803		if (cil_nodecon->addr->family == AF_INET) {
2804			new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE], &tail);
2805			new_ocon->u.node.addr = cil_nodecon->addr->ip.v4.s_addr;
2806			new_ocon->u.node.mask = cil_nodecon->mask->ip.v4.s_addr;
2807		} else if (cil_nodecon->addr->family == AF_INET6) {
2808			new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE6], &tail6);
2809			memcpy(new_ocon->u.node6.addr, &cil_nodecon->addr->ip.v6.s6_addr[0], 16);
2810			memcpy(new_ocon->u.node6.mask, &cil_nodecon->mask->ip.v6.s6_addr[0], 16);
2811		} else {
2812			/* should not get here */
2813			rc = SEPOL_ERR;
2814			goto exit;
2815		}
2816
2817		rc = __cil_context_to_sepol_context(pdb, cil_nodecon->context, &new_ocon->context[0]);
2818		if (rc != SEPOL_OK) {
2819			goto exit;
2820		}
2821	}
2822
2823	return SEPOL_OK;
2824
2825exit:
2826	return rc;
2827}
2828
2829int cil_fsuse_to_policydb(policydb_t *pdb, struct cil_sort *fsuses)
2830{
2831	int rc = SEPOL_ERR;
2832	uint32_t i = 0;
2833	ocontext_t *tail = NULL;
2834
2835	for (i = 0; i < fsuses->count; i++) {
2836		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_FSUSE], &tail);
2837		struct cil_fsuse *cil_fsuse = fsuses->array[i];
2838
2839		new_ocon->u.name = cil_strdup(cil_fsuse->fs_str);
2840		new_ocon->v.behavior = cil_fsuse->type;
2841
2842		rc = __cil_context_to_sepol_context(pdb, cil_fsuse->context, &new_ocon->context[0]);
2843		if (rc != SEPOL_OK) {
2844			goto exit;
2845		}
2846	}
2847
2848	return SEPOL_OK;
2849
2850exit:
2851	return rc;
2852}
2853
2854int cil_genfscon_to_policydb(policydb_t *pdb, struct cil_sort *genfscons)
2855{
2856	int rc = SEPOL_ERR;
2857	uint32_t i = 0;
2858	genfs_t *genfs_tail = NULL;
2859	ocontext_t *ocon_tail = NULL;
2860
2861	for (i = 0; i < genfscons->count; i++) {
2862		struct cil_genfscon *cil_genfscon = genfscons->array[i];
2863		ocontext_t *new_ocon = cil_malloc(sizeof(ocontext_t));
2864		memset(new_ocon, 0, sizeof(ocontext_t));
2865
2866		if (genfs_tail && strcmp(genfs_tail->fstype, cil_genfscon->fs_str) == 0) {
2867			ocon_tail->next = new_ocon;
2868		} else {
2869			genfs_t *new_genfs = cil_malloc(sizeof(genfs_t));
2870			memset(new_genfs, 0, sizeof(genfs_t));
2871			new_genfs->fstype = cil_strdup(cil_genfscon->fs_str);
2872			new_genfs->head = new_ocon;
2873
2874			if (genfs_tail) {
2875				genfs_tail->next = new_genfs;
2876			} else {
2877				pdb->genfs = new_genfs;
2878			}
2879			genfs_tail = new_genfs;
2880		}
2881
2882		ocon_tail = new_ocon;
2883
2884		new_ocon->u.name = cil_strdup(cil_genfscon->path_str);
2885
2886		rc = __cil_context_to_sepol_context(pdb, cil_genfscon->context, &new_ocon->context[0]);
2887		if (rc != SEPOL_OK) {
2888			goto exit;
2889		}
2890	}
2891
2892	return SEPOL_OK;
2893
2894exit:
2895	return rc;
2896}
2897
2898int cil_pirqcon_to_policydb(policydb_t *pdb, struct cil_sort *pirqcons)
2899{
2900	int rc = SEPOL_ERR;
2901	uint32_t i = 0;
2902	ocontext_t *tail = NULL;
2903
2904	for (i = 0; i < pirqcons->count; i++) {
2905		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PIRQ], &tail);
2906		struct cil_pirqcon *cil_pirqcon = pirqcons->array[i];
2907
2908		new_ocon->u.pirq = cil_pirqcon->pirq;
2909
2910		rc = __cil_context_to_sepol_context(pdb, cil_pirqcon->context, &new_ocon->context[0]);
2911		if (rc != SEPOL_OK) {
2912			goto exit;
2913		}
2914	}
2915
2916	return SEPOL_OK;
2917
2918exit:
2919	return rc;
2920}
2921
2922int cil_iomemcon_to_policydb(policydb_t *pdb, struct cil_sort *iomemcons)
2923{
2924	int rc = SEPOL_ERR;
2925	uint32_t i = 0;
2926	ocontext_t *tail = NULL;
2927
2928	for (i = 0; i < iomemcons->count; i++) {
2929		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOMEM], &tail);
2930		struct cil_iomemcon *cil_iomemcon = iomemcons->array[i];
2931
2932		new_ocon->u.iomem.low_iomem = cil_iomemcon->iomem_low;
2933		new_ocon->u.iomem.high_iomem = cil_iomemcon->iomem_high;
2934
2935		rc = __cil_context_to_sepol_context(pdb, cil_iomemcon->context, &new_ocon->context[0]);
2936		if (rc != SEPOL_OK) {
2937			goto exit;
2938		}
2939	}
2940
2941	return SEPOL_OK;
2942
2943exit:
2944	return rc;
2945}
2946
2947int cil_ioportcon_to_policydb(policydb_t *pdb, struct cil_sort *ioportcons)
2948{
2949	int rc = SEPOL_ERR;
2950	uint32_t i = 0;
2951	ocontext_t *tail = NULL;
2952
2953	for (i = 0; i < ioportcons->count; i++) {
2954		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOPORT], &tail);
2955		struct cil_ioportcon *cil_ioportcon = ioportcons->array[i];
2956
2957		new_ocon->u.ioport.low_ioport = cil_ioportcon->ioport_low;
2958		new_ocon->u.ioport.high_ioport = cil_ioportcon->ioport_high;
2959
2960		rc = __cil_context_to_sepol_context(pdb, cil_ioportcon->context, &new_ocon->context[0]);
2961		if (rc != SEPOL_OK) {
2962			goto exit;
2963		}
2964	}
2965
2966	return SEPOL_OK;
2967
2968exit:
2969	return rc;
2970}
2971
2972int cil_pcidevicecon_to_policydb(policydb_t *pdb, struct cil_sort *pcidevicecons)
2973{
2974	int rc = SEPOL_ERR;
2975	uint32_t i = 0;
2976	ocontext_t *tail = NULL;
2977
2978	for (i = 0; i < pcidevicecons->count; i++) {
2979		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PCIDEVICE], &tail);
2980		struct cil_pcidevicecon *cil_pcidevicecon = pcidevicecons->array[i];
2981
2982		new_ocon->u.device = cil_pcidevicecon->dev;
2983
2984		rc = __cil_context_to_sepol_context(pdb, cil_pcidevicecon->context, &new_ocon->context[0]);
2985		if (rc != SEPOL_OK) {
2986			goto exit;
2987		}
2988	}
2989
2990	return SEPOL_OK;
2991
2992exit:
2993	return rc;
2994}
2995
2996int cil_devicetreecon_to_policydb(policydb_t *pdb, struct cil_sort *devicetreecons)
2997{
2998	int rc = SEPOL_ERR;
2999	uint32_t i = 0;
3000	ocontext_t *tail = NULL;
3001
3002	for (i = 0; i < devicetreecons->count; i++) {
3003		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_DEVICETREE], &tail);
3004		struct cil_devicetreecon *cil_devicetreecon = devicetreecons->array[i];
3005
3006		new_ocon->u.name = cil_strdup(cil_devicetreecon->path);
3007
3008		rc = __cil_context_to_sepol_context(pdb, cil_devicetreecon->context, &new_ocon->context[0]);
3009		if (rc != SEPOL_OK) {
3010			goto exit;
3011		}
3012	}
3013
3014	return SEPOL_OK;
3015
3016exit:
3017	return rc;
3018}
3019
3020int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def)
3021{
3022	struct cil_list_item *curr;
3023	class_datum_t *sepol_class;
3024	struct cil_list *class_list;
3025
3026	cil_list_for_each(curr, def->class_datums) {
3027		struct cil_list_item *c;
3028
3029		class_list = cil_expand_class(curr->data);
3030
3031		cil_list_for_each(c, class_list) {
3032			int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
3033			if (rc != SEPOL_OK) goto exit;
3034
3035			switch (def->flavor) {
3036			case CIL_DEFAULTUSER:
3037				if (!sepol_class->default_user) {
3038					sepol_class->default_user = def->object;
3039				} else if (sepol_class->default_user != (char)def->object) {
3040					cil_log(CIL_ERR,"User default labeling for class %s already specified\n",DATUM(c->data)->fqn);
3041					goto exit;
3042				}
3043				break;
3044			case CIL_DEFAULTROLE:
3045				if (!sepol_class->default_role) {
3046					sepol_class->default_role = def->object;
3047				} else if (sepol_class->default_role != (char)def->object) {
3048					cil_log(CIL_ERR,"Role default labeling for class %s already specified\n",DATUM(c->data)->fqn);
3049					goto exit;
3050				}
3051				break;
3052			case CIL_DEFAULTTYPE:
3053				if (!sepol_class->default_type) {
3054					sepol_class->default_type = def->object;
3055				} else if (sepol_class->default_type != (char)def->object) {
3056					cil_log(CIL_ERR,"Type default labeling for class %s already specified\n",DATUM(c->data)->fqn);
3057					goto exit;
3058				}
3059				break;
3060			default:
3061				goto exit;
3062			}
3063		}
3064
3065		cil_list_destroy(&class_list, CIL_FALSE);
3066	}
3067
3068	return SEPOL_OK;
3069
3070exit:
3071	cil_list_destroy(&class_list, CIL_FALSE);
3072	return SEPOL_ERR;
3073}
3074
3075int cil_defaultrange_to_policydb(policydb_t *pdb, struct cil_defaultrange *def)
3076{
3077	struct cil_list_item *curr;
3078	class_datum_t *sepol_class;
3079	struct cil_list *class_list;
3080
3081	cil_list_for_each(curr, def->class_datums) {
3082		struct cil_list_item *c;
3083
3084		class_list = cil_expand_class(curr->data);
3085
3086		cil_list_for_each(c, class_list) {
3087			int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
3088			if (rc != SEPOL_OK) goto exit;
3089
3090			if (!sepol_class->default_range) {
3091				sepol_class->default_range = def->object_range;
3092			} else if (sepol_class->default_range != (char)def->object_range) {
3093				cil_log(CIL_ERR,"Range default labeling for class %s already specified\n", DATUM(curr->data)->fqn);
3094				goto exit;
3095			}
3096		}
3097
3098		cil_list_destroy(&class_list, CIL_FALSE);
3099	}
3100
3101	return SEPOL_OK;
3102
3103exit:
3104	cil_list_destroy(&class_list, CIL_FALSE);
3105	return SEPOL_ERR;
3106}
3107
3108int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
3109{
3110	int rc = SEPOL_OK;
3111	int pass;
3112	struct cil_args_binary *args = extra_args;
3113	const struct cil_db *db;
3114	policydb_t *pdb;
3115	hashtab_t filename_trans_table;
3116	hashtab_t range_trans_table;
3117	hashtab_t role_trans_table;
3118	db = args->db;
3119	pdb = args->pdb;
3120	pass = args->pass;
3121	filename_trans_table = args->filename_trans_table;
3122	range_trans_table = args->range_trans_table;
3123	role_trans_table = args->role_trans_table;
3124
3125	if (node->flavor >= CIL_MIN_DECLARATIVE) {
3126		if (node != DATUM(node->data)->nodes->head->data) {
3127			goto exit;
3128		}
3129	}
3130
3131	switch (pass) {
3132	case 1:
3133		switch (node->flavor) {
3134		case CIL_ROLE:
3135			rc = cil_role_to_policydb(pdb, node->data);
3136			break;
3137		case CIL_TYPE:
3138			rc = cil_type_to_policydb(pdb, node->data);
3139			break;
3140		case CIL_TYPEATTRIBUTE:
3141			rc = cil_typeattribute_to_policydb(pdb, node->data);
3142			break;
3143		case CIL_POLICYCAP:
3144			rc = cil_policycap_to_policydb(pdb, node->data);
3145			break;
3146		case CIL_USER:
3147			rc = cil_user_to_policydb(pdb, node->data);
3148			break;
3149		case CIL_BOOL:
3150			rc = cil_bool_to_policydb(pdb, node->data);
3151			break;
3152		case CIL_CATALIAS:
3153			if (pdb->mls == CIL_TRUE) {
3154				rc = cil_catalias_to_policydb(pdb, node->data);
3155			}
3156			break;
3157		case CIL_SENS:
3158			if (pdb->mls == CIL_TRUE) {
3159				rc = cil_sepol_level_define(pdb, node->data);
3160			}
3161			break;
3162		default:
3163			break;
3164		}
3165		break;
3166	case 2:
3167		switch (node->flavor) {
3168		case CIL_TYPE:
3169			rc = cil_type_bounds_to_policydb(pdb, node->data);
3170			break;
3171		case CIL_TYPEALIAS:
3172			rc = cil_typealias_to_policydb(pdb, node->data);
3173			break;
3174		case CIL_TYPEPERMISSIVE:
3175			rc = cil_typepermissive_to_policydb(pdb, node->data);
3176			break;
3177		case CIL_TYPEATTRIBUTE:
3178			rc = cil_typeattribute_to_bitmap(pdb, db, node->data);
3179			break;
3180		case CIL_SENSALIAS:
3181			if (pdb->mls == CIL_TRUE) {
3182				rc = cil_sensalias_to_policydb(pdb, node->data);
3183			}
3184			break;
3185		case CIL_ROLE:
3186			rc = cil_role_bounds_to_policydb(pdb, node->data);
3187			if (rc != SEPOL_OK) goto exit;
3188			rc = cil_roletype_to_policydb(pdb, db, node->data);
3189			break;
3190		case CIL_USER:
3191			rc = cil_user_bounds_to_policydb(pdb, node->data);
3192			if (rc != SEPOL_OK) goto exit;
3193			if (pdb->mls == CIL_TRUE) {
3194				rc = cil_userlevel_userrange_to_policydb(pdb, node->data);
3195			}
3196			break;
3197		case CIL_USERROLE:
3198			rc = cil_userrole_to_policydb(pdb, db, node->data);
3199			break;
3200		case CIL_TYPE_RULE:
3201			rc = cil_type_rule_to_policydb(pdb, db, node->data);
3202			break;
3203		case CIL_AVRULE: {
3204			struct cil_avrule *rule = node->data;
3205			struct cil_list *neverallows = args->neverallows;
3206			if (rule->rule_kind == CIL_AVRULE_NEVERALLOW) {
3207				struct cil_neverallow *new_rule = NULL;
3208
3209				new_rule = cil_malloc(sizeof(*new_rule));
3210				cil_list_init(&new_rule->rules, CIL_LIST_ITEM);
3211				new_rule->node = node;
3212
3213				cil_list_prepend(neverallows, CIL_LIST_ITEM, new_rule);
3214
3215				rc = cil_avrule_to_policydb(pdb, db, node->data, neverallows);
3216			}
3217			break;
3218		}
3219		case CIL_ROLETRANSITION:
3220			rc = cil_roletrans_to_policydb(pdb, db, node->data, role_trans_table);
3221			break;
3222		case CIL_ROLEATTRIBUTESET:
3223		  /*rc = cil_roleattributeset_to_policydb(pdb, node->data);*/
3224			break;
3225		case CIL_NAMETYPETRANSITION:
3226			rc = cil_typetransition_to_policydb(pdb, db, node->data, filename_trans_table);
3227			break;
3228		case CIL_CONSTRAIN:
3229			rc = cil_constrain_to_policydb(pdb, db, node->data);
3230			break;
3231		case CIL_MLSCONSTRAIN:
3232			if (pdb->mls == CIL_TRUE) {
3233				rc = cil_constrain_to_policydb(pdb, db, node->data);
3234			}
3235			break;
3236		case CIL_VALIDATETRANS:
3237			rc = cil_validatetrans_to_policydb(pdb, db, node->data);
3238			break;
3239		case CIL_MLSVALIDATETRANS:
3240			if (pdb->mls == CIL_TRUE) {
3241				rc = cil_validatetrans_to_policydb(pdb, db, node->data);
3242			}
3243			break;
3244		case CIL_RANGETRANSITION:
3245			if (pdb->mls == CIL_TRUE) {
3246				rc = cil_rangetransition_to_policydb(pdb, db, node->data, range_trans_table);
3247			}
3248			break;
3249		case CIL_DEFAULTUSER:
3250		case CIL_DEFAULTROLE:
3251		case CIL_DEFAULTTYPE:
3252			rc = cil_default_to_policydb(pdb, node->data);
3253			break;
3254		case CIL_DEFAULTRANGE:
3255			rc = cil_defaultrange_to_policydb(pdb, node->data);
3256			break;
3257		default:
3258			break;
3259		}
3260		break;
3261	case 3:
3262		switch (node->flavor) {
3263		case CIL_BOOLEANIF:
3264			rc = cil_booleanif_to_policydb(pdb, db, node, args->neverallows, filename_trans_table);
3265			break;
3266		case CIL_AVRULE: {
3267				struct cil_avrule *rule = node->data;
3268				if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) {
3269					rc = cil_avrule_to_policydb(pdb, db, node->data, args->neverallows);
3270				}
3271			}
3272			break;
3273		case CIL_ROLEALLOW:
3274			rc = cil_roleallow_to_policydb(pdb, db, node->data);
3275			break;
3276		default:
3277			break;
3278		}
3279	default:
3280		break;
3281	}
3282
3283exit:
3284	if (rc != SEPOL_OK) {
3285		cil_log(CIL_ERR, "Binary policy creation failed at line %d of %s\n", node->line, node->path);
3286	}
3287	return rc;
3288}
3289
3290int __cil_binary_create_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
3291{
3292	int rc = SEPOL_ERR;
3293
3294	if (node->flavor == CIL_BLOCK) {
3295		struct cil_block *blk = node->data;
3296		if (blk->is_abstract == CIL_TRUE) {
3297			*finished = CIL_TREE_SKIP_HEAD;
3298			rc = SEPOL_OK;
3299			goto exit;
3300		}
3301	} else if (node->flavor == CIL_MACRO) {
3302		*finished = CIL_TREE_SKIP_HEAD;
3303		rc = SEPOL_OK;
3304		goto exit;
3305	} else if (node->flavor == CIL_BOOLEANIF) {
3306		*finished = CIL_TREE_SKIP_HEAD;
3307	}
3308
3309	rc = __cil_node_to_policydb(node, extra_args);
3310	if (rc != SEPOL_OK) {
3311		goto exit;
3312	}
3313
3314exit:
3315	return rc;
3316}
3317
3318int __cil_contexts_to_policydb(policydb_t *pdb, const struct cil_db *db)
3319{
3320	int rc = SEPOL_ERR;
3321
3322	rc = cil_portcon_to_policydb(pdb, db->portcon);
3323	if (rc != SEPOL_OK) {
3324		goto exit;
3325	}
3326
3327	rc = cil_netifcon_to_policydb(pdb, db->netifcon);
3328	if (rc != SEPOL_OK) {
3329		goto exit;
3330	}
3331
3332	rc = cil_nodecon_to_policydb(pdb, db->nodecon);
3333	if (rc != SEPOL_OK) {
3334		goto exit;
3335	}
3336
3337	rc = cil_fsuse_to_policydb(pdb, db->fsuse);
3338	if (rc != SEPOL_OK) {
3339		goto exit;
3340	}
3341
3342	rc = cil_genfscon_to_policydb(pdb, db->genfscon);
3343	if (rc != SEPOL_OK) {
3344		goto exit;
3345	}
3346
3347	if (db->target_platform == SEPOL_TARGET_XEN) {
3348		rc = cil_pirqcon_to_policydb(pdb, db->pirqcon);
3349		if (rc != SEPOL_OK) {
3350			goto exit;
3351		}
3352
3353		rc = cil_iomemcon_to_policydb(pdb, db->iomemcon);
3354		if (rc != SEPOL_OK) {
3355			goto exit;
3356		}
3357
3358		rc = cil_ioportcon_to_policydb(pdb, db->ioportcon);
3359		if (rc != SEPOL_OK) {
3360			goto exit;
3361		}
3362
3363		rc = cil_pcidevicecon_to_policydb(pdb, db->pcidevicecon);
3364		if (rc != SEPOL_OK) {
3365			goto exit;
3366		}
3367
3368		rc = cil_devicetreecon_to_policydb(pdb, db->devicetreecon);
3369		if (rc != SEPOL_OK) {
3370			goto exit;
3371		}
3372	}
3373	return SEPOL_OK;
3374exit:
3375	return rc;
3376}
3377
3378int __cil_common_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3379{
3380	policydb_t *pdb = data;
3381	common_datum_t *common = (common_datum_t *)datum;
3382
3383	if (common->s.value < 1 || common->s.value > pdb->p_commons.nprim) {
3384		return -EINVAL;
3385	}
3386	pdb->p_common_val_to_name[common->s.value - 1] = (char *)key;
3387
3388	return 0;
3389}
3390
3391int __cil_class_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3392{
3393	policydb_t *pdb = data;
3394	class_datum_t *class = (class_datum_t *)datum;
3395
3396	if (class->s.value < 1 || class->s.value > pdb->p_classes.nprim) {
3397		return -EINVAL;
3398	}
3399	pdb->p_class_val_to_name[class->s.value - 1] = (char *)key;
3400	pdb->class_val_to_struct[class->s.value - 1] = class;
3401
3402	return 0;
3403}
3404
3405int __cil_role_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3406{
3407	policydb_t *pdb = data;
3408	role_datum_t *role = (role_datum_t *)datum;
3409
3410	if (role->s.value < 1 || role->s.value > pdb->p_roles.nprim) {
3411		return -EINVAL;
3412	}
3413	pdb->p_role_val_to_name[role->s.value - 1] = (char *)key;
3414	pdb->role_val_to_struct[role->s.value - 1] = role;
3415
3416	return 0;
3417}
3418
3419int __cil_type_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3420{
3421	policydb_t *pdb = data;
3422	type_datum_t *type = (type_datum_t *)datum;
3423
3424	if (type->s.value < 1 || type->s.value > pdb->p_types.nprim) {
3425		return -EINVAL;
3426	}
3427	pdb->p_type_val_to_name[type->s.value - 1] = (char *)key;
3428	pdb->type_val_to_struct[type->s.value - 1] = type;
3429
3430	return 0;
3431}
3432
3433int __cil_user_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3434{
3435	policydb_t *pdb = data;
3436	user_datum_t *user = (user_datum_t *)datum;
3437
3438	if (user->s.value < 1 || user->s.value > pdb->p_users.nprim) {
3439		return -EINVAL;
3440	}
3441	pdb->p_user_val_to_name[user->s.value - 1] = (char *)key;
3442	pdb->user_val_to_struct[user->s.value - 1] = user;
3443
3444	return 0;
3445}
3446
3447int __cil_bool_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3448{
3449	policydb_t *pdb = data;
3450	cond_bool_datum_t *bool = (cond_bool_datum_t *)datum;
3451
3452	if (bool->s.value < 1 || bool->s.value > pdb->p_bools.nprim) {
3453		return -EINVAL;
3454	}
3455	pdb->p_bool_val_to_name[bool->s.value - 1] = (char *)key;
3456	pdb->bool_val_to_struct[bool->s.value - 1] = bool;
3457
3458	return 0;
3459}
3460
3461int __cil_level_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3462{
3463	policydb_t *pdb = data;
3464	level_datum_t *level = (level_datum_t *)datum;
3465
3466	if (level->level->sens < 1 || level->level->sens > pdb->p_levels.nprim) {
3467		return -EINVAL;
3468	}
3469	pdb->p_sens_val_to_name[level->level->sens - 1] = (char *)key;
3470
3471	return 0;
3472}
3473
3474int __cil_cat_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3475{
3476	policydb_t *pdb = data;
3477	cat_datum_t *cat = (cat_datum_t *)datum;
3478
3479	if (cat->s.value < 1 || cat->s.value > pdb->p_cats.nprim) {
3480		return -EINVAL;
3481	}
3482	pdb->p_cat_val_to_name[cat->s.value - 1] = (char *)key;
3483
3484	return 0;
3485}
3486
3487int __cil_policydb_val_arrays_create(policydb_t *policydb)
3488{
3489	int rc = SEPOL_ERR;
3490
3491	policydb->p_common_val_to_name = cil_malloc(sizeof(char *) * policydb->p_commons.nprim);
3492	rc = hashtab_map(policydb->p_commons.table, &__cil_common_val_array_insert, policydb);
3493	if (rc != SEPOL_OK) {
3494		goto exit;
3495	}
3496
3497	policydb->p_class_val_to_name = cil_malloc(sizeof(char *) * policydb->p_classes.nprim);
3498	policydb->class_val_to_struct = cil_malloc(sizeof(class_datum_t *) * policydb->p_classes.nprim);
3499	rc = hashtab_map(policydb->p_classes.table, &__cil_class_val_array_insert, policydb);
3500	if (rc != SEPOL_OK) {
3501		goto exit;
3502	}
3503
3504	policydb->p_role_val_to_name = cil_malloc(sizeof(char *) * policydb->p_roles.nprim);
3505	policydb->role_val_to_struct = cil_malloc(sizeof(role_datum_t *) * policydb->p_roles.nprim);
3506	rc = hashtab_map(policydb->p_roles.table, &__cil_role_val_array_insert, policydb);
3507	if (rc != SEPOL_OK) {
3508		goto exit;
3509	}
3510
3511	policydb->p_type_val_to_name = cil_malloc(sizeof(char *) * policydb->p_types.nprim);
3512	policydb->type_val_to_struct = cil_malloc(sizeof(type_datum_t *) * policydb->p_types.nprim);
3513	rc = hashtab_map(policydb->p_types.table, &__cil_type_val_array_insert, policydb);
3514	if (rc != SEPOL_OK) {
3515		goto exit;
3516	}
3517
3518	policydb->p_user_val_to_name = cil_malloc(sizeof(char *) * policydb->p_users.nprim);
3519	policydb->user_val_to_struct = cil_malloc(sizeof(user_datum_t *) * policydb->p_users.nprim);
3520	rc = hashtab_map(policydb->p_users.table, &__cil_user_val_array_insert, policydb);
3521	if (rc != SEPOL_OK) {
3522		goto exit;
3523	}
3524
3525	policydb->p_bool_val_to_name = cil_malloc(sizeof(char *) * policydb->p_bools.nprim);
3526	policydb->bool_val_to_struct = cil_malloc(sizeof(cond_bool_datum_t *) * policydb->p_bools.nprim);
3527	rc = hashtab_map(policydb->p_bools.table, &__cil_bool_val_array_insert, policydb);
3528	if (rc != SEPOL_OK) {
3529		goto exit;
3530	}
3531
3532	policydb->p_sens_val_to_name = cil_malloc(sizeof(char *) * policydb->p_levels.nprim);
3533	rc = hashtab_map(policydb->p_levels.table, &__cil_level_val_array_insert, policydb);
3534	if (rc != SEPOL_OK) {
3535		goto exit;
3536	}
3537
3538	policydb->p_cat_val_to_name = cil_malloc(sizeof(char *) * policydb->p_cats.nprim);
3539	rc = hashtab_map(policydb->p_cats.table, &__cil_cat_val_array_insert, policydb);
3540	if (rc != SEPOL_OK) {
3541		goto exit;
3542	}
3543
3544exit:
3545	return rc;
3546}
3547
3548static void __cil_set_conditional_state_and_flags(policydb_t *pdb)
3549{
3550	cond_node_t *cur;
3551
3552	for (cur = pdb->cond_list; cur != NULL; cur = cur->next) {
3553		int new_state;
3554		cond_av_list_t *c;
3555
3556		new_state = cond_evaluate_expr(pdb, cur->expr);
3557
3558		cur->cur_state = new_state;
3559
3560		if (new_state == -1) {
3561			cil_log(CIL_WARN, "Expression result was undefined - disabling all rules\n");
3562		}
3563
3564		for (c = cur->true_list; c != NULL; c = c->next) {
3565			if (new_state <= 0) {
3566				c->node->key.specified &= ~AVTAB_ENABLED;
3567			} else {
3568				c->node->key.specified |= AVTAB_ENABLED;
3569			}
3570		}
3571
3572		for (c = cur->false_list; c != NULL; c = c->next) {
3573			if (new_state) { /* -1 or 1 */
3574				c->node->key.specified &= ~AVTAB_ENABLED;
3575			} else {
3576				c->node->key.specified |= AVTAB_ENABLED;
3577			}
3578		}
3579	}
3580}
3581
3582int __cil_policydb_create(const struct cil_db *db, struct sepol_policydb **spdb)
3583{
3584	int rc;
3585	struct policydb *pdb = NULL;
3586
3587	rc = sepol_policydb_create(spdb);
3588	if (rc < 0) {
3589		cil_log(CIL_ERR, "Failed to create policy db\n");
3590		// spdb could be a dangling pointer at this point, so reset it so
3591		// callers of this function don't need to worry about freeing garbage
3592		*spdb = NULL;
3593		goto exit;
3594	}
3595
3596	pdb = &(*spdb)->p;
3597
3598	pdb->policy_type = POLICY_KERN;
3599	pdb->target_platform = db->target_platform;
3600	pdb->policyvers = db->policy_version;
3601	pdb->handle_unknown = db->handle_unknown;
3602	pdb->mls = db->mls;
3603
3604	return SEPOL_OK;
3605
3606exit:
3607	return rc;
3608}
3609
3610
3611int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db)
3612{
3613	int rc = SEPOL_ERR;
3614
3615	// these flags should get set in __cil_policydb_create. However, for
3616	// backwards compatability, it is possible that __cil_policydb_create is
3617	// never called. So, they must also be set here.
3618	pdb->handle_unknown = db->handle_unknown;
3619	pdb->mls = db->mls;
3620
3621	rc = cil_classorder_to_policydb(pdb, db);
3622	if (rc != SEPOL_OK) {
3623		goto exit;
3624	}
3625
3626	if (pdb->mls == CIL_TRUE) {
3627		rc = cil_catorder_to_policydb(pdb, db);
3628		if (rc != SEPOL_OK) {
3629			goto exit;
3630		}
3631
3632		rc = cil_sensitivityorder_to_policydb(pdb, db);
3633		if (rc != SEPOL_OK) {
3634			goto exit;
3635		}
3636	}
3637
3638	rc = avtab_alloc(&pdb->te_avtab, MAX_AVTAB_SIZE);
3639	if (rc != SEPOL_OK) {
3640		goto exit;
3641	}
3642
3643	rc = avtab_alloc(&pdb->te_cond_avtab, MAX_AVTAB_SIZE);
3644	if (rc != SEPOL_OK) {
3645		goto exit;
3646	}
3647
3648	return SEPOL_OK;
3649
3650exit:
3651
3652	return rc;
3653}
3654
3655static unsigned int filename_trans_hash(hashtab_t h, hashtab_key_t key)
3656{
3657	filename_trans_t *k = (filename_trans_t *)key;
3658	return ((k->tclass + (k->ttype << 2) +
3659				(k->stype << 9)) & (h->size - 1));
3660}
3661
3662static int filename_trans_compare(hashtab_t h
3663             __attribute__ ((unused)), hashtab_key_t key1,
3664			              hashtab_key_t key2)
3665{
3666	filename_trans_t *a = (filename_trans_t *)key1;
3667	filename_trans_t *b = (filename_trans_t *)key2;
3668
3669	return a->stype != b->stype || a->ttype != b->ttype || a->tclass != b->tclass || strcmp(a->name, b->name);
3670}
3671
3672static unsigned int range_trans_hash(hashtab_t h, hashtab_key_t key)
3673{
3674	range_trans_t *k = (range_trans_t *)key;
3675	return ((k->target_class + (k->target_type << 2) +
3676				(k->source_type << 5)) & (h->size - 1));
3677}
3678
3679static int range_trans_compare(hashtab_t h
3680             __attribute__ ((unused)), hashtab_key_t key1,
3681			              hashtab_key_t key2)
3682{
3683	range_trans_t *a = (range_trans_t *)key1;
3684	range_trans_t *b = (range_trans_t *)key2;
3685
3686	return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class;
3687}
3688
3689static unsigned int role_trans_hash(hashtab_t h, hashtab_key_t key)
3690{
3691	role_trans_t *k = (role_trans_t *)key;
3692	return ((k->role + (k->type << 2) +
3693				(k->tclass << 5)) & (h->size - 1));
3694}
3695
3696static int role_trans_compare(hashtab_t h
3697             __attribute__ ((unused)), hashtab_key_t key1,
3698			              hashtab_key_t key2)
3699{
3700	role_trans_t *a = (role_trans_t *)key1;
3701	role_trans_t *b = (role_trans_t *)key2;
3702
3703	return a->role != b->role || a->type != b->type || a->tclass != b->tclass;
3704}
3705
3706int cil_binary_create(const struct cil_db *db, sepol_policydb_t **policydb)
3707{
3708	int rc = SEPOL_ERR;
3709	struct sepol_policydb *pdb = NULL;
3710
3711	rc = __cil_policydb_create(db, &pdb);
3712	if (rc != SEPOL_OK) {
3713		goto exit;
3714	}
3715
3716	rc = cil_binary_create_allocated_pdb(db, pdb);
3717	if (rc != SEPOL_OK) {
3718		goto exit;
3719	}
3720
3721	*policydb = pdb;
3722
3723	return SEPOL_OK;
3724
3725exit:
3726	sepol_policydb_free(pdb);
3727
3728	return rc;
3729}
3730
3731// assumes policydb is already allocated and initialized properly with things
3732// like policy type set to kernel and version set appropriately
3733int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *policydb)
3734{
3735	int rc = SEPOL_ERR;
3736	int i;
3737	struct cil_args_binary extra_args;
3738	policydb_t *pdb = &policydb->p;
3739	struct cil_list *neverallows = NULL;
3740	hashtab_t filename_trans_table = NULL;
3741	hashtab_t range_trans_table = NULL;
3742	hashtab_t role_trans_table = NULL;
3743
3744	if (db == NULL || policydb == NULL) {
3745		if (db == NULL) {
3746			cil_log(CIL_ERR,"db == NULL\n");
3747		} else if (policydb == NULL) {
3748			cil_log(CIL_ERR,"policydb == NULL\n");
3749		}
3750		return SEPOL_ERR;
3751	}
3752
3753	rc = __cil_policydb_init(pdb, db);
3754	if (rc != SEPOL_OK) {
3755		cil_log(CIL_ERR,"Problem in policydb_init\n");
3756		goto exit;
3757	}
3758
3759	filename_trans_table = hashtab_create(filename_trans_hash, filename_trans_compare, FILENAME_TRANS_TABLE_SIZE);
3760	if (!filename_trans_table) {
3761		cil_log(CIL_INFO, "Failure to create hashtab for filename_trans\n");
3762		goto exit;
3763	}
3764
3765	range_trans_table = hashtab_create(range_trans_hash, range_trans_compare, RANGE_TRANS_TABLE_SIZE);
3766	if (!range_trans_table) {
3767		cil_log(CIL_INFO, "Failure to create hashtab for range_trans\n");
3768		goto exit;
3769	}
3770
3771	role_trans_table = hashtab_create(role_trans_hash, role_trans_compare, ROLE_TRANS_TABLE_SIZE);
3772	if (!role_trans_table) {
3773		cil_log(CIL_INFO, "Failure to create hashtab for role_trans\n");
3774		goto exit;
3775	}
3776
3777	cil_list_init(&neverallows, CIL_LIST_ITEM);
3778
3779	extra_args.db = db;
3780	extra_args.pdb = pdb;
3781	extra_args.neverallows = neverallows;
3782	extra_args.filename_trans_table = filename_trans_table;
3783	extra_args.range_trans_table = range_trans_table;
3784	extra_args.role_trans_table = role_trans_table;
3785	for (i = 1; i <= 3; i++) {
3786		extra_args.pass = i;
3787
3788		rc = cil_tree_walk(db->ast->root, __cil_binary_create_helper, NULL, NULL, &extra_args);
3789		if (rc != SEPOL_OK) {
3790			cil_log(CIL_INFO, "Failure while walking cil database\n");
3791			goto exit;
3792		}
3793
3794		if (i == 1) {
3795			rc = __cil_policydb_val_arrays_create(pdb);
3796			if (rc != SEPOL_OK) {
3797				cil_log(CIL_INFO, "Failure creating val_to_{struct,name} arrays\n");
3798				goto exit;
3799			}
3800		}
3801	}
3802
3803	rc = cil_sidorder_to_policydb(pdb, db);
3804	if (rc != SEPOL_OK) {
3805		goto exit;
3806	}
3807
3808	rc = __cil_contexts_to_policydb(pdb, db);
3809	if (rc != SEPOL_OK) {
3810		cil_log(CIL_INFO, "Failure while inserting cil contexts into sepol policydb\n");
3811		goto exit;
3812	}
3813
3814	if (pdb->type_attr_map == NULL) {
3815		rc = __cil_typeattr_bitmap_init(pdb);
3816		if (rc != SEPOL_OK) {
3817			cil_log(CIL_INFO, "Failure while initializing typeattribute bitmap\n");
3818			goto exit;
3819		}
3820	}
3821
3822	cond_optimize_lists(pdb->cond_list);
3823	__cil_set_conditional_state_and_flags(pdb);
3824
3825	rc = SEPOL_OK;
3826
3827exit:
3828	hashtab_destroy(filename_trans_table);
3829	hashtab_destroy(range_trans_table);
3830	hashtab_destroy(role_trans_table);
3831	cil_neverallows_list_destroy(neverallows);
3832
3833	return rc;
3834}
3835