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
33#include <sepol/policydb/policydb.h>
34#include <sepol/policydb/symtab.h>
35
36#include "cil_internal.h"
37#include "cil_flavor.h"
38#include "cil_log.h"
39#include "cil_mem.h"
40#include "cil_tree.h"
41#include "cil_list.h"
42#include "cil_symtab.h"
43#include "cil_build_ast.h"
44
45#include "cil_parser.h"
46#include "cil_build_ast.h"
47#include "cil_resolve_ast.h"
48#include "cil_fqn.h"
49#include "cil_post.h"
50#include "cil_binary.h"
51#include "cil_policy.h"
52#include "cil_strpool.h"
53#include "dso.h"
54
55#ifndef DISABLE_SYMVER
56asm(".symver cil_build_policydb_pdb,        cil_build_policydb@");
57asm(".symver cil_build_policydb_create_pdb, cil_build_policydb@@LIBSEPOL_1.1");
58
59asm(".symver cil_compile_pdb,   cil_compile@");
60asm(".symver cil_compile_nopdb, cil_compile@@LIBSEPOL_1.1");
61
62asm(".symver cil_userprefixes_to_string_pdb,   cil_userprefixes_to_string@");
63asm(".symver cil_userprefixes_to_string_nopdb, cil_userprefixes_to_string@@LIBSEPOL_1.1");
64
65asm(".symver cil_selinuxusers_to_string_pdb,   cil_selinuxusers_to_string@");
66asm(".symver cil_selinuxusers_to_string_nopdb, cil_selinuxusers_to_string@@LIBSEPOL_1.1");
67
68asm(".symver cil_filecons_to_string_pdb,   cil_filecons_to_string@");
69asm(".symver cil_filecons_to_string_nopdb, cil_filecons_to_string@@LIBSEPOL_1.1");
70#endif
71
72int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM] = {
73	{64, 64, 64, 1 << 13, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
74	{64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
75	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
76	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
77	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
78};
79
80static void cil_init_keys(void)
81{
82	/* Initialize CIL Keys into strpool */
83	CIL_KEY_CONS_T1 = cil_strpool_add("t1");
84	CIL_KEY_CONS_T2 = cil_strpool_add("t2");
85	CIL_KEY_CONS_T3 = cil_strpool_add("t3");
86	CIL_KEY_CONS_R1 = cil_strpool_add("r1");
87	CIL_KEY_CONS_R2 = cil_strpool_add("r2");
88	CIL_KEY_CONS_R3 = cil_strpool_add("r3");
89	CIL_KEY_CONS_U1 = cil_strpool_add("u1");
90	CIL_KEY_CONS_U2 = cil_strpool_add("u2");
91	CIL_KEY_CONS_U3 = cil_strpool_add("u3");
92	CIL_KEY_CONS_L1 = cil_strpool_add("l1");
93	CIL_KEY_CONS_L2 = cil_strpool_add("l2");
94	CIL_KEY_CONS_H1 = cil_strpool_add("h1");
95	CIL_KEY_CONS_H2 = cil_strpool_add("h2");
96	CIL_KEY_AND = cil_strpool_add("and");
97	CIL_KEY_OR = cil_strpool_add("or");
98	CIL_KEY_NOT = cil_strpool_add("not");
99	CIL_KEY_EQ = cil_strpool_add("eq");
100	CIL_KEY_NEQ = cil_strpool_add("neq");
101	CIL_KEY_CONS_DOM = cil_strpool_add("dom");
102	CIL_KEY_CONS_DOMBY = cil_strpool_add("domby");
103	CIL_KEY_CONS_INCOMP = cil_strpool_add("incomp");
104	CIL_KEY_CONDTRUE = cil_strpool_add("true");
105	CIL_KEY_CONDFALSE = cil_strpool_add("false");
106	CIL_KEY_SELF = cil_strpool_add("self");
107	CIL_KEY_OBJECT_R = cil_strpool_add("object_r");
108	CIL_KEY_STAR = cil_strpool_add("*");
109	CIL_KEY_UDP = cil_strpool_add("udp");
110	CIL_KEY_TCP = cil_strpool_add("tcp");
111	CIL_KEY_AUDITALLOW = cil_strpool_add("auditallow");
112	CIL_KEY_TUNABLEIF = cil_strpool_add("tunableif");
113	CIL_KEY_ALLOW = cil_strpool_add("allow");
114	CIL_KEY_DONTAUDIT = cil_strpool_add("dontaudit");
115	CIL_KEY_TYPETRANSITION = cil_strpool_add("typetransition");
116	CIL_KEY_TYPECHANGE = cil_strpool_add("typechange");
117	CIL_KEY_CALL = cil_strpool_add("call");
118	CIL_KEY_TUNABLE = cil_strpool_add("tunable");
119	CIL_KEY_XOR = cil_strpool_add("xor");
120	CIL_KEY_ALL = cil_strpool_add("all");
121	CIL_KEY_RANGE = cil_strpool_add("range");
122	CIL_KEY_TYPE = cil_strpool_add("type");
123	CIL_KEY_ROLE = cil_strpool_add("role");
124	CIL_KEY_USER = cil_strpool_add("user");
125	CIL_KEY_SENSITIVITY = cil_strpool_add("sensitivity");
126	CIL_KEY_CATEGORY = cil_strpool_add("category");
127	CIL_KEY_CATSET = cil_strpool_add("categoryset");
128	CIL_KEY_LEVEL = cil_strpool_add("level");
129	CIL_KEY_LEVELRANGE = cil_strpool_add("levelrange");
130	CIL_KEY_CLASS = cil_strpool_add("class");
131	CIL_KEY_IPADDR = cil_strpool_add("ipaddr");
132	CIL_KEY_MAP_CLASS = cil_strpool_add("classmap");
133	CIL_KEY_CLASSPERMISSION = cil_strpool_add("classpermission");
134	CIL_KEY_BOOL = cil_strpool_add("boolean");
135	CIL_KEY_STRING = cil_strpool_add("string");
136	CIL_KEY_NAME = cil_strpool_add("name");
137	CIL_KEY_HANDLEUNKNOWN = cil_strpool_add("handleunknown");
138	CIL_KEY_HANDLEUNKNOWN_ALLOW = cil_strpool_add("allow");
139	CIL_KEY_HANDLEUNKNOWN_DENY = cil_strpool_add("deny");
140	CIL_KEY_HANDLEUNKNOWN_REJECT = cil_strpool_add("reject");
141	CIL_KEY_BLOCKINHERIT = cil_strpool_add("blockinherit");
142	CIL_KEY_BLOCKABSTRACT = cil_strpool_add("blockabstract");
143	CIL_KEY_CLASSORDER = cil_strpool_add("classorder");
144	CIL_KEY_CLASSMAPPING = cil_strpool_add("classmapping");
145	CIL_KEY_CLASSPERMISSIONSET = cil_strpool_add("classpermissionset");
146	CIL_KEY_COMMON = cil_strpool_add("common");
147	CIL_KEY_CLASSCOMMON = cil_strpool_add("classcommon");
148	CIL_KEY_SID = cil_strpool_add("sid");
149	CIL_KEY_SIDCONTEXT = cil_strpool_add("sidcontext");
150	CIL_KEY_SIDORDER = cil_strpool_add("sidorder");
151	CIL_KEY_USERLEVEL = cil_strpool_add("userlevel");
152	CIL_KEY_USERRANGE = cil_strpool_add("userrange");
153	CIL_KEY_USERBOUNDS = cil_strpool_add("userbounds");
154	CIL_KEY_USERPREFIX = cil_strpool_add("userprefix");
155	CIL_KEY_SELINUXUSER = cil_strpool_add("selinuxuser");
156	CIL_KEY_SELINUXUSERDEFAULT = cil_strpool_add("selinuxuserdefault");
157	CIL_KEY_TYPEATTRIBUTE = cil_strpool_add("typeattribute");
158	CIL_KEY_TYPEATTRIBUTESET = cil_strpool_add("typeattributeset");
159	CIL_KEY_TYPEALIAS = cil_strpool_add("typealias");
160	CIL_KEY_TYPEALIASACTUAL = cil_strpool_add("typealiasactual");
161	CIL_KEY_TYPEBOUNDS = cil_strpool_add("typebounds");
162	CIL_KEY_TYPEPERMISSIVE = cil_strpool_add("typepermissive");
163	CIL_KEY_RANGETRANSITION = cil_strpool_add("rangetransition");
164	CIL_KEY_USERROLE = cil_strpool_add("userrole");
165	CIL_KEY_ROLETYPE = cil_strpool_add("roletype");
166	CIL_KEY_ROLETRANSITION = cil_strpool_add("roletransition");
167	CIL_KEY_ROLEALLOW = cil_strpool_add("roleallow");
168	CIL_KEY_ROLEATTRIBUTE = cil_strpool_add("roleattribute");
169	CIL_KEY_ROLEATTRIBUTESET = cil_strpool_add("roleattributeset");
170	CIL_KEY_ROLEBOUNDS = cil_strpool_add("rolebounds");
171	CIL_KEY_BOOLEANIF = cil_strpool_add("booleanif");
172	CIL_KEY_NEVERALLOW = cil_strpool_add("neverallow");
173	CIL_KEY_TYPEMEMBER = cil_strpool_add("typemember");
174	CIL_KEY_SENSALIAS = cil_strpool_add("sensitivityalias");
175	CIL_KEY_SENSALIASACTUAL = cil_strpool_add("sensitivityaliasactual");
176	CIL_KEY_CATALIAS = cil_strpool_add("categoryalias");
177	CIL_KEY_CATALIASACTUAL = cil_strpool_add("categoryaliasactual");
178	CIL_KEY_CATORDER = cil_strpool_add("categoryorder");
179	CIL_KEY_SENSITIVITYORDER = cil_strpool_add("sensitivityorder");
180	CIL_KEY_SENSCAT = cil_strpool_add("sensitivitycategory");
181	CIL_KEY_CONSTRAIN = cil_strpool_add("constrain");
182	CIL_KEY_MLSCONSTRAIN = cil_strpool_add("mlsconstrain");
183	CIL_KEY_VALIDATETRANS = cil_strpool_add("validatetrans");
184	CIL_KEY_MLSVALIDATETRANS = cil_strpool_add("mlsvalidatetrans");
185	CIL_KEY_CONTEXT = cil_strpool_add("context");
186	CIL_KEY_FILECON = cil_strpool_add("filecon");
187	CIL_KEY_PORTCON = cil_strpool_add("portcon");
188	CIL_KEY_NODECON = cil_strpool_add("nodecon");
189	CIL_KEY_GENFSCON = cil_strpool_add("genfscon");
190	CIL_KEY_NETIFCON = cil_strpool_add("netifcon");
191	CIL_KEY_PIRQCON = cil_strpool_add("pirqcon");
192	CIL_KEY_IOMEMCON = cil_strpool_add("iomemcon");
193	CIL_KEY_IOPORTCON = cil_strpool_add("ioportcon");
194	CIL_KEY_PCIDEVICECON = cil_strpool_add("pcidevicecon");
195	CIL_KEY_DEVICETREECON = cil_strpool_add("devicetreecon");
196	CIL_KEY_FSUSE = cil_strpool_add("fsuse");
197	CIL_KEY_POLICYCAP = cil_strpool_add("policycap");
198	CIL_KEY_OPTIONAL = cil_strpool_add("optional");
199	CIL_KEY_DEFAULTUSER = cil_strpool_add("defaultuser");
200	CIL_KEY_DEFAULTROLE = cil_strpool_add("defaultrole");
201	CIL_KEY_DEFAULTTYPE = cil_strpool_add("defaulttype");
202	CIL_KEY_MACRO = cil_strpool_add("macro");
203	CIL_KEY_IN = cil_strpool_add("in");
204	CIL_KEY_MLS = cil_strpool_add("mls");
205	CIL_KEY_DEFAULTRANGE = cil_strpool_add("defaultrange");
206	CIL_KEY_GLOB = cil_strpool_add("*");
207	CIL_KEY_FILE = cil_strpool_add("file");
208	CIL_KEY_DIR = cil_strpool_add("dir");
209	CIL_KEY_CHAR = cil_strpool_add("char");
210	CIL_KEY_BLOCK = cil_strpool_add("block");
211	CIL_KEY_SOCKET = cil_strpool_add("socket");
212	CIL_KEY_PIPE = cil_strpool_add("pipe");
213	CIL_KEY_SYMLINK = cil_strpool_add("symlink");
214	CIL_KEY_ANY = cil_strpool_add("any");
215	CIL_KEY_XATTR = cil_strpool_add("xattr");
216	CIL_KEY_TASK = cil_strpool_add("task");
217	CIL_KEY_TRANS = cil_strpool_add("trans");
218	CIL_KEY_SOURCE = cil_strpool_add("source");
219	CIL_KEY_TARGET = cil_strpool_add("target");
220	CIL_KEY_LOW = cil_strpool_add("low");
221	CIL_KEY_HIGH = cil_strpool_add("high");
222	CIL_KEY_LOW_HIGH = cil_strpool_add("low-high");
223	CIL_KEY_ROOT = cil_strpool_add("<root>");
224	CIL_KEY_NODE = cil_strpool_add("<node>");
225	CIL_KEY_PERM = cil_strpool_add("perm");
226}
227
228void cil_db_init(struct cil_db **db)
229{
230	*db = cil_malloc(sizeof(**db));
231
232	cil_strpool_init();
233	cil_init_keys();
234
235	cil_tree_init(&(*db)->parse);
236	cil_tree_init(&(*db)->ast);
237	cil_root_init((struct cil_root **)&(*db)->ast->root->data);
238	(*db)->sidorder = NULL;
239	(*db)->classorder = NULL;
240	(*db)->catorder = NULL;
241	(*db)->sensitivityorder = NULL;
242	cil_sort_init(&(*db)->netifcon);
243	cil_sort_init(&(*db)->genfscon);
244	cil_sort_init(&(*db)->filecon);
245	cil_sort_init(&(*db)->nodecon);
246	cil_sort_init(&(*db)->portcon);
247	cil_sort_init(&(*db)->pirqcon);
248	cil_sort_init(&(*db)->iomemcon);
249	cil_sort_init(&(*db)->ioportcon);
250	cil_sort_init(&(*db)->pcidevicecon);
251	cil_sort_init(&(*db)->devicetreecon);
252	cil_sort_init(&(*db)->fsuse);
253	cil_list_init(&(*db)->userprefixes, CIL_LIST_ITEM);
254	cil_list_init(&(*db)->selinuxusers, CIL_LIST_ITEM);
255	cil_list_init(&(*db)->names, CIL_LIST_ITEM);
256
257	cil_type_init(&(*db)->selftype);
258	(*db)->selftype->datum.name = CIL_KEY_SELF;
259	(*db)->selftype->datum.fqn = CIL_KEY_SELF;
260
261	(*db)->num_types = 0;
262	(*db)->num_roles = 0;
263	(*db)->num_cats = 0;
264	(*db)->val_to_type = NULL;
265	(*db)->val_to_role = NULL;
266
267	(*db)->disable_dontaudit = CIL_FALSE;
268	(*db)->disable_neverallow = CIL_FALSE;
269	(*db)->preserve_tunables = CIL_FALSE;
270	(*db)->handle_unknown = -1;
271	(*db)->mls = -1;
272	(*db)->target_platform = SEPOL_TARGET_SELINUX;
273	(*db)->policy_version = POLICYDB_VERSION_MAX;
274}
275
276void cil_db_destroy(struct cil_db **db)
277{
278	if (db == NULL || *db == NULL) {
279		return;
280	}
281
282	cil_tree_destroy(&(*db)->parse);
283	cil_tree_destroy(&(*db)->ast);
284	cil_list_destroy(&(*db)->sidorder, CIL_FALSE);
285	cil_list_destroy(&(*db)->classorder, CIL_FALSE);
286	cil_list_destroy(&(*db)->catorder, CIL_FALSE);
287	cil_list_destroy(&(*db)->sensitivityorder, CIL_FALSE);
288	cil_sort_destroy(&(*db)->netifcon);
289	cil_sort_destroy(&(*db)->genfscon);
290	cil_sort_destroy(&(*db)->filecon);
291	cil_sort_destroy(&(*db)->nodecon);
292	cil_sort_destroy(&(*db)->portcon);
293	cil_sort_destroy(&(*db)->pirqcon);
294	cil_sort_destroy(&(*db)->iomemcon);
295	cil_sort_destroy(&(*db)->ioportcon);
296	cil_sort_destroy(&(*db)->pcidevicecon);
297	cil_sort_destroy(&(*db)->devicetreecon);
298	cil_sort_destroy(&(*db)->fsuse);
299	cil_list_destroy(&(*db)->userprefixes, CIL_FALSE);
300	cil_list_destroy(&(*db)->selinuxusers, CIL_FALSE);
301	cil_list_destroy(&(*db)->names, CIL_TRUE);
302
303	cil_destroy_type((*db)->selftype);
304
305	cil_strpool_destroy();
306	free((*db)->val_to_type);
307	free((*db)->val_to_role);
308
309	free(*db);
310	*db = NULL;
311}
312
313void cil_root_init(struct cil_root **root)
314{
315	struct cil_root *r = cil_malloc(sizeof(*r));
316	cil_symtab_array_init(r->symtab, cil_sym_sizes[CIL_SYM_ARRAY_ROOT]);
317
318	*root = r;
319}
320
321void cil_root_destroy(struct cil_root *root)
322{
323	if (root == NULL) {
324		return;
325	}
326	cil_symtab_array_destroy(root->symtab);
327	free(root);
328}
329
330int cil_add_file(cil_db_t *db, char *name, char *data, size_t size)
331{
332	char *buffer = NULL;
333	int rc;
334
335	cil_log(CIL_INFO, "Parsing %s\n", name);
336
337	buffer = cil_malloc(size + 2);
338	memcpy(buffer, data, size);
339	memset(buffer + size, 0, 2);
340
341	rc = cil_parser(name, buffer, size + 2, &db->parse);
342	if (rc != SEPOL_OK) {
343		cil_log(CIL_ERR, "Failed to parse %s\n", name);
344		goto exit;
345	}
346
347	free(buffer);
348	buffer = NULL;
349
350	rc = SEPOL_OK;
351
352exit:
353	free(buffer);
354
355	return rc;
356}
357
358#ifdef DISABLE_SYMVER
359int cil_compile(struct cil_db *db)
360#else
361int cil_compile_nopdb(struct cil_db *db)
362#endif
363{
364	int rc = SEPOL_ERR;
365
366	if (db == NULL) {
367		goto exit;
368	}
369
370	cil_log(CIL_INFO, "Building AST from Parse Tree\n");
371	rc = cil_build_ast(db, db->parse->root, db->ast->root);
372	if (rc != SEPOL_OK) {
373		cil_log(CIL_ERR, "Failed to build ast\n");
374		goto exit;
375	}
376
377	cil_log(CIL_INFO, "Destroying Parse Tree\n");
378	cil_tree_destroy(&db->parse);
379
380	cil_log(CIL_INFO, "Resolving AST\n");
381	rc = cil_resolve_ast(db, db->ast->root);
382	if (rc != SEPOL_OK) {
383		cil_log(CIL_ERR, "Failed to resolve ast\n");
384		goto exit;
385	}
386
387	cil_log(CIL_INFO, "Qualifying Names\n");
388	rc = cil_fqn_qualify(db->ast->root);
389	if (rc != SEPOL_OK) {
390		cil_log(CIL_ERR, "Failed to qualify names\n");
391		goto exit;
392	}
393
394	cil_log(CIL_INFO, "Compile post process\n");
395	rc = cil_post_process(db);
396	if (rc != SEPOL_OK ) {
397		cil_log(CIL_ERR, "Post process failed\n");
398		goto exit;
399	}
400
401exit:
402
403	return rc;
404}
405
406#ifndef DISABLE_SYMVER
407int cil_compile_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db)
408{
409	return cil_compile_nopdb(db);
410}
411
412int cil_build_policydb_pdb(cil_db_t *db, sepol_policydb_t *sepol_db)
413{
414	int rc;
415
416	cil_log(CIL_INFO, "Building policy binary\n");
417	rc = cil_binary_create_allocated_pdb(db, sepol_db);
418	if (rc != SEPOL_OK) {
419		cil_log(CIL_ERR, "Failed to generate binary\n");
420		goto exit;
421	}
422
423exit:
424	return rc;
425}
426#endif
427
428#ifdef DISABLE_SYMVER
429int cil_build_policydb(cil_db_t *db, sepol_policydb_t **sepol_db)
430#else
431int cil_build_policydb_create_pdb(cil_db_t *db, sepol_policydb_t **sepol_db)
432#endif
433{
434	int rc;
435
436	cil_log(CIL_INFO, "Building policy binary\n");
437	rc = cil_binary_create(db, sepol_db);
438	if (rc != SEPOL_OK) {
439		cil_log(CIL_ERR, "Failed to generate binary\n");
440		goto exit;
441	}
442
443exit:
444	return rc;
445}
446
447void cil_destroy_data(void **data, enum cil_flavor flavor)
448{
449	if (*data == NULL) {
450		return;
451	}
452
453	switch(flavor) {
454	case CIL_NONE:
455		break;
456	case CIL_ROOT:
457		cil_root_destroy(*data);
458		break;
459	case CIL_NODE:
460		break;
461	case CIL_STRING:
462		break;
463	case CIL_DATUM:
464		break;
465	case CIL_LIST:
466		cil_list_destroy(*data, CIL_FALSE);
467		break;
468	case CIL_LIST_ITEM:
469		break;
470	case CIL_PARAM:
471		cil_destroy_param(*data);
472		break;
473	case CIL_ARGS:
474		cil_destroy_args(*data);
475		break;
476	case CIL_BLOCK:
477		cil_destroy_block(*data);
478		break;
479	case CIL_BLOCKINHERIT:
480		cil_destroy_blockinherit(*data);
481		break;
482	case CIL_BLOCKABSTRACT:
483		cil_destroy_blockabstract(*data);
484		break;
485	case CIL_IN:
486		cil_destroy_in(*data);
487		break;
488	case CIL_MACRO:
489		cil_destroy_macro(*data);
490		break;
491	case CIL_CALL:
492		cil_destroy_call(*data);
493		break;
494	case CIL_OPTIONAL:
495		cil_destroy_optional(*data);
496		break;
497	case CIL_BOOL:
498		cil_destroy_bool(*data);
499		break;
500	case CIL_BOOLEANIF:
501		cil_destroy_boolif(*data);
502		break;
503	case CIL_TUNABLE:
504		cil_destroy_tunable(*data);
505		break;
506	case CIL_TUNABLEIF:
507		cil_destroy_tunif(*data);
508		break;
509	case CIL_CONDBLOCK:
510		cil_destroy_condblock(*data);
511		break;
512	case CIL_CONDTRUE:
513		break;
514	case CIL_CONDFALSE:
515		break;
516	case CIL_PERM:
517	case CIL_MAP_PERM:
518		cil_destroy_perm(*data);
519		break;
520	case CIL_COMMON:
521	case CIL_CLASS:
522	case CIL_MAP_CLASS:
523		cil_destroy_class(*data);
524		break;
525	case CIL_CLASSORDER:
526		cil_destroy_classorder(*data);
527		break;
528	case CIL_CLASSPERMISSION:
529		cil_destroy_classpermission(*data);
530		break;
531	case CIL_CLASSCOMMON:
532		cil_destroy_classcommon(*data);
533		break;
534	case CIL_CLASSMAPPING:
535		cil_destroy_classmapping(*data);
536		break;
537	case CIL_CLASSPERMS:
538		cil_destroy_classperms(*data);
539		break;
540	case CIL_CLASSPERMS_SET:
541		cil_destroy_classperms_set(*data);
542		break;
543	case CIL_CLASSPERMISSIONSET:
544		cil_destroy_classpermissionset(*data);
545		break;
546	case CIL_USER:
547		cil_destroy_user(*data);
548		break;
549	case CIL_USERPREFIX:
550		cil_destroy_userprefix(*data);
551		break;
552	case CIL_USERROLE:
553		cil_destroy_userrole(*data);
554		break;
555	case CIL_USERLEVEL:
556		cil_destroy_userlevel(*data);
557		break;
558	case CIL_USERRANGE:
559		cil_destroy_userrange(*data);
560		break;
561	case CIL_USERBOUNDS:
562		cil_destroy_bounds(*data);
563		break;
564	case CIL_SELINUXUSER:
565	case CIL_SELINUXUSERDEFAULT:
566		cil_destroy_selinuxuser(*data);
567		break;
568	case CIL_ROLE:
569		cil_destroy_role(*data);
570		break;
571	case CIL_ROLEATTRIBUTE:
572		cil_destroy_roleattribute(*data);
573		break;
574	case CIL_ROLEATTRIBUTESET:
575		cil_destroy_roleattributeset(*data);
576		break;
577	case CIL_ROLETYPE:
578		cil_destroy_roletype(*data);
579		break;
580	case CIL_ROLEBOUNDS:
581		cil_destroy_bounds(*data);
582		break;
583	case CIL_TYPE:
584		cil_destroy_type(*data);
585		break;
586	case CIL_TYPEATTRIBUTE:
587		cil_destroy_typeattribute(*data);
588		break;
589	case CIL_TYPEALIAS:
590		cil_destroy_alias(*data);
591		break;
592	case CIL_TYPEATTRIBUTESET:
593		cil_destroy_typeattributeset(*data);
594		break;
595	case CIL_TYPEALIASACTUAL:
596		cil_destroy_aliasactual(*data);
597		break;
598	case CIL_TYPEBOUNDS:
599		cil_destroy_bounds(*data);
600		break;
601	case CIL_TYPEPERMISSIVE:
602		cil_destroy_typepermissive(*data);
603		break;
604	case CIL_SENS:
605		cil_destroy_sensitivity(*data);
606		break;
607	case CIL_SENSALIAS:
608		cil_destroy_alias(*data);
609		break;
610	case CIL_SENSALIASACTUAL:
611		cil_destroy_aliasactual(*data);
612		break;
613	case CIL_SENSITIVITYORDER:
614		cil_destroy_sensitivityorder(*data);
615		break;
616	case CIL_SENSCAT:
617		cil_destroy_senscat(*data);
618		break;
619	case CIL_CAT:
620		cil_destroy_category(*data);
621		break;
622	case CIL_CATSET:
623		cil_destroy_catset(*data);
624		break;
625	case CIL_CATALIAS:
626		cil_destroy_alias(*data);
627		break;
628	case CIL_CATALIASACTUAL:
629		cil_destroy_aliasactual(*data);
630		break;
631	case CIL_CATORDER:
632		cil_destroy_catorder(*data);
633		break;
634	case CIL_LEVEL:
635		cil_destroy_level(*data);
636		break;
637	case CIL_LEVELRANGE:
638		cil_destroy_levelrange(*data);
639		break;
640	case CIL_SID:
641		cil_destroy_sid(*data);
642		break;
643	case CIL_SIDORDER:
644		cil_destroy_sidorder(*data);
645		break;
646	case CIL_NAME:
647		cil_destroy_name(*data);
648		break;
649	case CIL_ROLEALLOW:
650		cil_destroy_roleallow(*data);
651		break;
652	case CIL_AVRULE:
653		cil_destroy_avrule(*data);
654		break;
655	case CIL_ROLETRANSITION:
656		cil_destroy_roletransition(*data);
657		break;
658	case CIL_TYPE_RULE:
659		cil_destroy_type_rule(*data);
660		break;
661	case CIL_NAMETYPETRANSITION:
662		cil_destroy_typetransition(*data);
663		break;
664	case CIL_RANGETRANSITION:
665		cil_destroy_rangetransition(*data);
666		break;
667	case CIL_CONSTRAIN:
668		cil_destroy_constrain(*data);
669		break;
670	case CIL_MLSCONSTRAIN:
671		cil_destroy_constrain(*data);
672		break;
673	case CIL_VALIDATETRANS:
674	case CIL_MLSVALIDATETRANS:
675		cil_destroy_validatetrans(*data);
676		break;
677	case CIL_CONTEXT:
678		cil_destroy_context(*data);
679		break;
680	case CIL_IPADDR:
681		cil_destroy_ipaddr(*data);
682		break;
683	case CIL_SIDCONTEXT:
684		cil_destroy_sidcontext(*data);
685		break;
686	case CIL_FSUSE:
687		cil_destroy_fsuse(*data);
688		break;
689	case CIL_FILECON:
690		cil_destroy_filecon(*data);
691		break;
692	case CIL_PORTCON:
693		cil_destroy_portcon(*data);
694		break;
695	case CIL_NODECON:
696		cil_destroy_nodecon(*data);
697		break;
698	case CIL_GENFSCON:
699		cil_destroy_genfscon(*data);
700		break;
701	case CIL_NETIFCON:
702		cil_destroy_netifcon(*data);
703		break;
704	case CIL_PIRQCON:
705		cil_destroy_pirqcon(*data);
706		break;
707	case CIL_IOMEMCON:
708		cil_destroy_iomemcon(*data);
709		break;
710	case CIL_IOPORTCON:
711		cil_destroy_ioportcon(*data);
712		break;
713	case CIL_PCIDEVICECON:
714		cil_destroy_pcidevicecon(*data);
715		break;
716	case CIL_DEVICETREECON:
717		cil_destroy_devicetreecon(*data);
718		break;
719	case CIL_POLICYCAP:
720		cil_destroy_policycap(*data);
721		break;
722	case CIL_DEFAULTUSER:
723	case CIL_DEFAULTROLE:
724	case CIL_DEFAULTTYPE:
725		cil_destroy_default(*data);
726		break;
727	case CIL_DEFAULTRANGE:
728		cil_destroy_defaultrange(*data);
729		break;
730	case CIL_HANDLEUNKNOWN:
731		cil_destroy_handleunknown(*data);
732		break;
733	case CIL_MLS:
734		cil_destroy_mls(*data);
735		break;
736	case CIL_OP:
737	case CIL_CONS_OPERAND:
738		break;
739	default:
740		cil_log(CIL_INFO, "Unknown data flavor: %d\n", flavor);
741		break;
742	}
743
744	*data = NULL;
745}
746
747int cil_flavor_to_symtab_index(enum cil_flavor flavor, enum cil_sym_index *sym_index)
748{
749	if (flavor < CIL_MIN_DECLARATIVE) {
750		return SEPOL_ERR;
751	}
752
753	switch(flavor) {
754	case CIL_BLOCK:
755		*sym_index = CIL_SYM_BLOCKS;
756		break;
757	case CIL_MACRO:
758		*sym_index = CIL_SYM_BLOCKS;
759		break;
760	case CIL_OPTIONAL:
761		*sym_index = CIL_SYM_BLOCKS;
762		break;
763	case CIL_BOOL:
764		*sym_index = CIL_SYM_BOOLS;
765		break;
766	case CIL_TUNABLE:
767		*sym_index = CIL_SYM_TUNABLES;
768		break;
769	case CIL_PERM:
770	case CIL_MAP_PERM:
771		*sym_index = CIL_SYM_PERMS;
772		break;
773	case CIL_COMMON:
774		*sym_index = CIL_SYM_COMMONS;
775		break;
776	case CIL_CLASS:
777	case CIL_MAP_CLASS:
778		*sym_index = CIL_SYM_CLASSES;
779		break;
780	case CIL_CLASSPERMISSION:
781	case CIL_CLASSPERMISSIONSET:
782		*sym_index = CIL_SYM_CLASSPERMSETS;
783		break;
784	case CIL_USER:
785		*sym_index = CIL_SYM_USERS;
786		break;
787	case CIL_ROLE:
788	case CIL_ROLEATTRIBUTE:
789		*sym_index = CIL_SYM_ROLES;
790		break;
791	case CIL_TYPE:
792	case CIL_TYPEALIAS:
793	case CIL_TYPEATTRIBUTE:
794		*sym_index = CIL_SYM_TYPES;
795		break;
796	case CIL_SENS:
797	case CIL_SENSALIAS:
798		*sym_index = CIL_SYM_SENS;
799		break;
800	case CIL_CAT:
801	case CIL_CATSET:
802	case CIL_CATALIAS:
803		*sym_index = CIL_SYM_CATS;
804		break;
805	case CIL_LEVEL:
806		*sym_index = CIL_SYM_LEVELS;
807		break;
808	case CIL_LEVELRANGE:
809		*sym_index = CIL_SYM_LEVELRANGES;
810		break;
811	case CIL_SID:
812		*sym_index = CIL_SYM_SIDS;
813		break;
814	case CIL_NAME:
815		*sym_index = CIL_SYM_NAMES;
816		break;
817	case CIL_CONTEXT:
818		*sym_index = CIL_SYM_CONTEXTS;
819		break;
820	case CIL_IPADDR:
821		*sym_index = CIL_SYM_IPADDRS;
822		break;
823	case CIL_POLICYCAP:
824		*sym_index = CIL_SYM_POLICYCAPS;
825		break;
826	default:
827		*sym_index = CIL_SYM_UNKNOWN;
828		cil_log(CIL_INFO, "Failed to find flavor: %d\n", flavor);
829		return SEPOL_ERR;
830	}
831
832	return SEPOL_OK;
833}
834
835const char * cil_node_to_string(struct cil_tree_node *node)
836{
837	switch (node->flavor) {
838	case CIL_NONE:
839		return "<none>";
840	case CIL_ROOT:
841		return CIL_KEY_ROOT;
842	case CIL_NODE:
843		return CIL_KEY_NODE;
844	case CIL_STRING:
845		return "string";
846	case CIL_DATUM:
847		return "<datum>";
848	case CIL_LIST:
849		return "<list>";
850	case CIL_LIST_ITEM:
851		return "<list_item>";
852	case CIL_PARAM:
853		return "<param>";
854	case CIL_ARGS:
855		return "<args>";
856	case CIL_BLOCK:
857		return CIL_KEY_BLOCK;
858	case CIL_BLOCKINHERIT:
859		return CIL_KEY_BLOCKINHERIT;
860	case CIL_BLOCKABSTRACT:
861		return CIL_KEY_BLOCKABSTRACT;
862	case CIL_IN:
863		return CIL_KEY_IN;
864	case CIL_MACRO:
865		return CIL_KEY_MACRO;
866	case CIL_CALL:
867		return CIL_KEY_CALL;
868	case CIL_OPTIONAL:
869		return CIL_KEY_OPTIONAL;
870	case CIL_BOOL:
871		return CIL_KEY_BOOL;
872	case CIL_BOOLEANIF:
873		return CIL_KEY_BOOLEANIF;
874	case CIL_TUNABLE:
875		return CIL_KEY_TUNABLE;
876	case CIL_TUNABLEIF:
877		return CIL_KEY_TUNABLEIF;
878	case CIL_CONDBLOCK:
879		switch (((struct cil_condblock*)node->data)->flavor) {
880		case CIL_CONDTRUE:
881			return CIL_KEY_CONDTRUE;
882		case CIL_CONDFALSE:
883			return CIL_KEY_CONDFALSE;
884		default:
885			break;
886		}
887		break;
888	case CIL_CONDTRUE:
889		return CIL_KEY_CONDTRUE;
890	case CIL_CONDFALSE:
891		return CIL_KEY_CONDFALSE;
892	case CIL_PERM:
893		return CIL_KEY_PERM;
894	case CIL_COMMON:
895		return CIL_KEY_COMMON;
896	case CIL_CLASS:
897		return CIL_KEY_CLASS;
898	case CIL_CLASSORDER:
899		return CIL_KEY_CLASSORDER;
900	case CIL_MAP_CLASS:
901		return CIL_KEY_MAP_CLASS;
902	case CIL_CLASSPERMISSION:
903		return CIL_KEY_CLASSPERMISSION;
904	case CIL_CLASSCOMMON:
905		return CIL_KEY_CLASSCOMMON;
906	case CIL_CLASSMAPPING:
907		return CIL_KEY_CLASSMAPPING;
908	case CIL_CLASSPERMISSIONSET:
909		return CIL_KEY_CLASSPERMISSIONSET;
910	case CIL_USER:
911		return CIL_KEY_USER;
912	case CIL_USERPREFIX:
913		return CIL_KEY_USERPREFIX;
914	case CIL_USERROLE:
915		return CIL_KEY_USERROLE;
916	case CIL_USERLEVEL:
917		return CIL_KEY_USERLEVEL;
918	case CIL_USERRANGE:
919		return CIL_KEY_USERRANGE;
920	case CIL_USERBOUNDS:
921		return CIL_KEY_USERBOUNDS;
922	case CIL_SELINUXUSER:
923		return CIL_KEY_SELINUXUSER;
924	case CIL_SELINUXUSERDEFAULT:
925		return CIL_KEY_SELINUXUSERDEFAULT;
926	case CIL_ROLE:
927		return CIL_KEY_ROLE;
928	case CIL_ROLEATTRIBUTE:
929		return CIL_KEY_ROLEATTRIBUTE;
930	case CIL_ROLEATTRIBUTESET:
931		return CIL_KEY_ROLEATTRIBUTESET;
932	case CIL_ROLETYPE:
933		return CIL_KEY_ROLETYPE;
934	case CIL_ROLEBOUNDS:
935		return CIL_KEY_ROLEBOUNDS;
936	case CIL_TYPE:
937		return CIL_KEY_TYPE;
938	case CIL_TYPEATTRIBUTE:
939		return CIL_KEY_TYPEATTRIBUTE;
940	case CIL_TYPEALIAS:
941		return CIL_KEY_TYPEALIAS;
942	case CIL_TYPEATTRIBUTESET:
943		return CIL_KEY_TYPEATTRIBUTESET;
944	case CIL_TYPEALIASACTUAL:
945		return CIL_KEY_TYPEALIASACTUAL;
946	case CIL_TYPEBOUNDS:
947		return CIL_KEY_TYPEBOUNDS;
948	case CIL_TYPEPERMISSIVE:
949		return CIL_KEY_TYPEPERMISSIVE;
950	case CIL_SENS:
951		return CIL_KEY_SENSITIVITY;
952	case CIL_SENSALIAS:
953		return CIL_KEY_SENSALIAS;
954	case CIL_SENSALIASACTUAL:
955		return CIL_KEY_SENSALIASACTUAL;
956	case CIL_SENSITIVITYORDER:
957		return CIL_KEY_SENSITIVITYORDER;
958	case CIL_SENSCAT:
959		return CIL_KEY_SENSCAT;
960	case CIL_CAT:
961		return CIL_KEY_CATEGORY;
962	case CIL_CATSET:
963		return CIL_KEY_CATSET;
964	case CIL_CATALIAS:
965		return CIL_KEY_CATALIAS;
966	case CIL_CATALIASACTUAL:
967		return CIL_KEY_CATALIASACTUAL;
968	case CIL_CATORDER:
969		return CIL_KEY_CATORDER;
970	case CIL_LEVEL:
971		return CIL_KEY_LEVEL;
972	case CIL_LEVELRANGE:
973		return CIL_KEY_LEVELRANGE;
974	case CIL_SID:
975		return CIL_KEY_SID;
976	case CIL_SIDORDER:
977		return CIL_KEY_SIDORDER;
978	case CIL_NAME:
979		return CIL_KEY_NAME;
980	case CIL_ROLEALLOW:
981		return CIL_KEY_ROLEALLOW;
982	case CIL_AVRULE:
983		switch (((struct cil_avrule *)node->data)->rule_kind) {
984		case CIL_AVRULE_ALLOWED:
985			return CIL_KEY_ALLOW;
986		case CIL_AVRULE_AUDITALLOW:
987			return CIL_KEY_AUDITALLOW;
988		case CIL_AVRULE_DONTAUDIT:
989			return CIL_KEY_DONTAUDIT;
990		case CIL_AVRULE_NEVERALLOW:
991			return CIL_KEY_NEVERALLOW;
992		default:
993			break;
994		}
995		break;
996	case CIL_ROLETRANSITION:
997		return CIL_KEY_ROLETRANSITION;
998	case CIL_TYPE_RULE:
999		switch (((struct cil_type_rule *)node->data)->rule_kind) {
1000		case CIL_TYPE_TRANSITION:
1001			return CIL_KEY_TYPETRANSITION;
1002		case CIL_TYPE_MEMBER:
1003			return CIL_KEY_TYPEMEMBER;
1004		case CIL_TYPE_CHANGE:
1005			return CIL_KEY_TYPECHANGE;
1006		default:
1007			break;
1008		}
1009		break;
1010	case CIL_NAMETYPETRANSITION:
1011		return CIL_KEY_TYPETRANSITION;
1012	case CIL_RANGETRANSITION:
1013		return CIL_KEY_RANGETRANSITION;
1014	case CIL_CONSTRAIN:
1015		return CIL_KEY_CONSTRAIN;
1016	case CIL_MLSCONSTRAIN:
1017		return CIL_KEY_MLSCONSTRAIN;
1018	case CIL_VALIDATETRANS:
1019		return CIL_KEY_VALIDATETRANS;
1020	case CIL_MLSVALIDATETRANS:
1021		return CIL_KEY_MLSVALIDATETRANS;
1022	case CIL_CONTEXT:
1023		return CIL_KEY_CONTEXT;
1024	case CIL_IPADDR:
1025		return CIL_KEY_IPADDR;
1026	case CIL_SIDCONTEXT:
1027		return CIL_KEY_SIDCONTEXT;
1028	case CIL_FSUSE:
1029		return CIL_KEY_FSUSE;
1030	case CIL_FILECON:
1031		return CIL_KEY_FILECON;
1032	case CIL_PORTCON:
1033		return CIL_KEY_PORTCON;
1034	case CIL_NODECON:
1035		return CIL_KEY_NODECON;
1036	case CIL_GENFSCON:
1037		return CIL_KEY_GENFSCON;
1038	case CIL_NETIFCON:
1039		return CIL_KEY_NETIFCON;
1040	case CIL_PIRQCON:
1041		return CIL_KEY_PIRQCON;
1042	case CIL_IOMEMCON:
1043		return CIL_KEY_IOMEMCON;
1044	case CIL_IOPORTCON:
1045		return CIL_KEY_IOPORTCON;
1046	case CIL_PCIDEVICECON:
1047		return CIL_KEY_PCIDEVICECON;
1048	case CIL_DEVICETREECON:
1049		return CIL_KEY_DEVICETREECON;
1050	case CIL_POLICYCAP:
1051		return CIL_KEY_POLICYCAP;
1052	case CIL_DEFAULTUSER:
1053		return CIL_KEY_DEFAULTUSER;
1054	case CIL_DEFAULTROLE:
1055		return CIL_KEY_DEFAULTROLE;
1056	case CIL_DEFAULTTYPE:
1057		return CIL_KEY_DEFAULTTYPE;
1058	case CIL_DEFAULTRANGE:
1059		return CIL_KEY_DEFAULTRANGE;
1060	case CIL_HANDLEUNKNOWN:
1061		return CIL_KEY_HANDLEUNKNOWN;
1062	case CIL_MLS:
1063		return CIL_KEY_MLS;
1064	case CIL_ALL:
1065		return CIL_KEY_ALL;
1066	case CIL_RANGE:
1067		return CIL_KEY_RANGE;
1068	case CIL_AND:
1069		return CIL_KEY_AND;
1070	case CIL_OR:
1071		return CIL_KEY_OR;
1072	case CIL_XOR:
1073		return CIL_KEY_XOR;
1074	case CIL_NOT:
1075		return CIL_KEY_NOT;
1076	case CIL_EQ:
1077		return CIL_KEY_EQ;
1078	case CIL_NEQ:
1079		return CIL_KEY_NEQ;
1080	case CIL_CONS_DOM:
1081		return CIL_KEY_CONS_DOM;
1082	case CIL_CONS_DOMBY:
1083		return CIL_KEY_CONS_DOMBY;
1084	case CIL_CONS_INCOMP:
1085		return CIL_KEY_CONS_INCOMP;
1086	case CIL_CONS_U1:
1087		return CIL_KEY_CONS_U1;
1088	case CIL_CONS_U2:
1089		return CIL_KEY_CONS_U2;
1090	case CIL_CONS_U3:
1091		return CIL_KEY_CONS_U3;
1092	case CIL_CONS_T1:
1093		return CIL_KEY_CONS_T1;
1094	case CIL_CONS_T2:
1095		return CIL_KEY_CONS_T2;
1096	case CIL_CONS_T3:
1097		return CIL_KEY_CONS_T3;
1098	case CIL_CONS_R1:
1099		return CIL_KEY_CONS_R1;
1100	case CIL_CONS_R2:
1101		return CIL_KEY_CONS_R2;
1102	case CIL_CONS_R3:
1103		return CIL_KEY_CONS_R3;
1104	case CIL_CONS_L1:
1105		return CIL_KEY_CONS_L1;
1106	case CIL_CONS_L2:
1107		return CIL_KEY_CONS_L2;
1108	case CIL_CONS_H1:
1109		return CIL_KEY_CONS_H1;
1110	case CIL_CONS_H2:
1111		return CIL_KEY_CONS_H2;
1112
1113	default:
1114		break;
1115	}
1116
1117	return "<unknown>";
1118}
1119
1120#ifdef DISABLE_SYMVER
1121int cil_userprefixes_to_string(struct cil_db *db, char **out, size_t *size)
1122#else
1123int cil_userprefixes_to_string_nopdb(struct cil_db *db, char **out, size_t *size)
1124#endif
1125{
1126	int rc = SEPOL_ERR;
1127	size_t str_len = 0;
1128	int buf_pos = 0;
1129	char *str_tmp = NULL;
1130	struct cil_list_item *curr;
1131	struct cil_userprefix *userprefix = NULL;
1132	struct cil_user *user = NULL;
1133
1134	*out = NULL;
1135
1136	if (db->userprefixes->head == NULL) {
1137		rc = SEPOL_OK;
1138		*size = 0;
1139		goto exit;
1140	}
1141
1142	cil_list_for_each(curr, db->userprefixes) {
1143		userprefix = curr->data;
1144		user = userprefix->user;
1145		str_len += strlen("user ") + strlen(user->datum.fqn) + strlen(" prefix ") + strlen(userprefix->prefix_str) + 2;
1146	}
1147
1148	*size = str_len * sizeof(char);
1149	str_len++;
1150	str_tmp = cil_malloc(str_len * sizeof(char));
1151	*out = str_tmp;
1152
1153	cil_list_for_each(curr, db->userprefixes) {
1154		userprefix = curr->data;
1155		user = userprefix->user;
1156
1157		buf_pos = snprintf(str_tmp, str_len, "user %s prefix %s;\n", user->datum.fqn,
1158									userprefix->prefix_str);
1159		str_len -= buf_pos;
1160		str_tmp += buf_pos;
1161	}
1162
1163	rc = SEPOL_OK;
1164exit:
1165	return rc;
1166
1167}
1168
1169#ifndef DISABLE_SYMVER
1170int cil_userprefixes_to_string_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db, char **out, size_t *size)
1171{
1172	return cil_userprefixes_to_string_nopdb(db, out, size);
1173}
1174#endif
1175
1176static int cil_cats_to_ebitmap(struct cil_cats *cats, struct ebitmap* cats_ebitmap)
1177{
1178	int rc = SEPOL_ERR;
1179	struct cil_list_item *i;
1180	struct cil_list_item *j;
1181	struct cil_cat* cat;
1182	struct cil_catset *cs;
1183	struct cil_tree_node *node;
1184
1185	if (cats == NULL) {
1186		rc = SEPOL_OK;
1187		goto exit;
1188	}
1189
1190	cil_list_for_each(i, cats->datum_expr) {
1191		node = DATUM(i->data)->nodes->head->data;
1192		if (node->flavor == CIL_CATSET) {
1193			cs = (struct cil_catset*)i->data;
1194			cil_list_for_each(j, cs->cats->datum_expr) {
1195				cat = (struct cil_cat*)j->data;
1196				rc = ebitmap_set_bit(cats_ebitmap, cat->value, 1);
1197				if (rc != SEPOL_OK) {
1198					goto exit;
1199				}
1200			}
1201		} else {
1202			cat = (struct cil_cat*)i->data;
1203			rc = ebitmap_set_bit(cats_ebitmap, cat->value, 1);
1204			if (rc != SEPOL_OK) {
1205				goto exit;
1206			}
1207		}
1208	}
1209
1210	return SEPOL_OK;
1211
1212exit:
1213	return rc;
1214}
1215
1216static int cil_level_equals(struct cil_level *low, struct cil_level *high)
1217{
1218	int rc;
1219	struct ebitmap elow;
1220	struct ebitmap ehigh;
1221
1222	if (strcmp(low->sens->datum.fqn, high->sens->datum.fqn)) {
1223		rc = 0;
1224		goto exit;
1225	}
1226
1227	ebitmap_init(&elow);
1228	ebitmap_init(&ehigh);
1229
1230	rc = cil_cats_to_ebitmap(low->cats, &elow);
1231	if (rc != SEPOL_OK) {
1232		goto exit;
1233	}
1234
1235	rc = cil_cats_to_ebitmap(high->cats, &ehigh);
1236	if (rc != SEPOL_OK) {
1237		goto exit;
1238	}
1239
1240	return ebitmap_cmp(&elow, &ehigh);
1241
1242exit:
1243	return rc;
1244}
1245
1246static int __cil_level_strlen(struct cil_level *lvl)
1247{
1248	struct cil_list_item *item;
1249	struct cil_cats *cats = lvl->cats;
1250	int str_len = 0;
1251	char *str1 = NULL;
1252	char *str2 = NULL;
1253	int first = -1;
1254	int last = -1;
1255
1256	str_len += strlen(lvl->sens->datum.fqn);
1257
1258	if (cats && cats->datum_expr != NULL) {
1259		str_len++; /* initial ":" */
1260		cil_list_for_each(item, cats->datum_expr) {
1261			struct cil_cat *cat = item->data;
1262			if (first == -1) {
1263				str1 = cat->datum.fqn;
1264				first = cat->value;
1265				last = first;
1266			} else if (cat->value == last + 1) {
1267				last++;
1268				str2 = cat->datum.fqn;
1269			} else {
1270				if (first == last) {
1271					str_len += strlen(str1) + strlen(cat->datum.fqn) + 1;
1272				} else if (last == first + 1) {
1273					str_len += strlen(str1) + strlen(str2) + strlen(cat->datum.fqn) + 2;
1274				} else {
1275					str_len += strlen(str1) + strlen(str2) + strlen(cat->datum.fqn) + 2;
1276				}
1277				first = -1;
1278				last = -1;
1279				if (item->next != NULL) {
1280					str_len++; /* space for "," after */
1281				}
1282			}
1283		}
1284		if (first != -1) {
1285			if (first == last) {
1286				str_len += strlen(str1);
1287			} else if (last == first + 1) {
1288				str_len += strlen(str1) + strlen(str2) + 1;
1289			} else {
1290				str_len += strlen(str1) + strlen(str2) + 1;
1291			}
1292		}
1293	}
1294
1295	return str_len;
1296}
1297
1298static int __cil_level_to_string(struct cil_level *lvl, char *out)
1299{
1300	struct cil_list_item *item;
1301	struct cil_cats *cats = lvl->cats;
1302	int buf_pos = 0;
1303	char *str_tmp = out;
1304	char *str1 = NULL;
1305	char *str2 = NULL;
1306	int first = -1;
1307	int last = -1;
1308
1309	buf_pos = sprintf(str_tmp, "%s", lvl->sens->datum.fqn);
1310	str_tmp += buf_pos;
1311
1312	if (cats && cats->datum_expr != NULL) {
1313		buf_pos = sprintf(str_tmp, ":");
1314		str_tmp += buf_pos;
1315
1316		cil_list_for_each(item, cats->datum_expr) {
1317			struct cil_cat *cat = item->data;
1318			if (first == -1) {
1319				str1 = cat->datum.fqn;
1320				first = cat->value;
1321				last = first;
1322			} else if (cat->value == last + 1) {
1323				last++;
1324				str2 = cat->datum.fqn;
1325			} else {
1326				if (first == last) {
1327					buf_pos = sprintf(str_tmp, "%s,%s", str1, cat->datum.fqn);
1328					str_tmp += buf_pos;
1329				} else if (last == first + 1) {
1330					buf_pos = sprintf(str_tmp, "%s,%s,%s", str1, str2, cat->datum.fqn);
1331					str_tmp += buf_pos;
1332				} else {
1333					buf_pos = sprintf(str_tmp, "%s.%s,%s",str1, str2, cat->datum.fqn);
1334					str_tmp += buf_pos;
1335				}
1336				first = -1;
1337				last = -1;
1338				if (item->next != NULL) {
1339					buf_pos = sprintf(str_tmp, ",");
1340					str_tmp += buf_pos;
1341				}
1342			}
1343		}
1344		if (first != -1) {
1345			if (first == last) {
1346				buf_pos = sprintf(str_tmp, "%s", str1);
1347				str_tmp += buf_pos;
1348			} else if (last == first + 1) {
1349				buf_pos = sprintf(str_tmp, "%s,%s", str1, str2);
1350				str_tmp += buf_pos;
1351			} else {
1352				buf_pos = sprintf(str_tmp, "%s.%s",str1, str2);
1353				str_tmp += buf_pos;
1354			}
1355		}
1356	}
1357
1358	return str_tmp - out;
1359}
1360
1361#ifdef DISABLE_SYMVER
1362int cil_selinuxusers_to_string(struct cil_db *db, char **out, size_t *size)
1363#else
1364int cil_selinuxusers_to_string_nopdb(struct cil_db *db, char **out, size_t *size)
1365#endif
1366{
1367	size_t str_len = 0;
1368	int buf_pos = 0;
1369	char *str_tmp = NULL;
1370	struct cil_list_item *curr;
1371
1372	if (db->selinuxusers->head == NULL) {
1373		*size = 0;
1374		*out = NULL;
1375		return SEPOL_OK;
1376	}
1377
1378	cil_list_for_each(curr, db->selinuxusers) {
1379		struct cil_selinuxuser *selinuxuser = curr->data;
1380		struct cil_user *user = selinuxuser->user;
1381
1382		str_len += strlen(selinuxuser->name_str) + strlen(user->datum.fqn) + 1;
1383
1384		if (db->mls == CIL_TRUE) {
1385			struct cil_levelrange *range = selinuxuser->range;
1386			str_len += __cil_level_strlen(range->low) + __cil_level_strlen(range->high) + 2;
1387		}
1388
1389		str_len++;
1390	}
1391
1392	*size = str_len * sizeof(char);
1393	str_tmp = cil_malloc(*size+1);
1394	*out = str_tmp;
1395
1396	for(curr = db->selinuxusers->head; curr != NULL; curr = curr->next) {
1397		struct cil_selinuxuser *selinuxuser = curr->data;
1398		struct cil_user *user = selinuxuser->user;
1399
1400		buf_pos = sprintf(str_tmp, "%s:%s", selinuxuser->name_str, user->datum.fqn);
1401		str_tmp += buf_pos;
1402
1403		if (db->mls == CIL_TRUE) {
1404			struct cil_levelrange *range = selinuxuser->range;
1405			buf_pos = sprintf(str_tmp, ":");
1406			str_tmp += buf_pos;
1407			buf_pos = __cil_level_to_string(range->low, str_tmp);
1408			str_tmp += buf_pos;
1409			buf_pos = sprintf(str_tmp, "-");
1410			str_tmp += buf_pos;
1411			buf_pos = __cil_level_to_string(range->high, str_tmp);
1412			str_tmp += buf_pos;
1413		}
1414
1415		buf_pos = sprintf(str_tmp, "\n");
1416		str_tmp += buf_pos;
1417	}
1418
1419	return SEPOL_OK;
1420}
1421
1422#ifndef DISABLE_SYMVER
1423int cil_selinuxusers_to_string_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db, char **out, size_t *size)
1424{
1425	return cil_selinuxusers_to_string_nopdb(db, out, size);
1426}
1427#endif
1428
1429#ifdef DISABLE_SYMVER
1430int cil_filecons_to_string(struct cil_db *db, char **out, size_t *size)
1431#else
1432int cil_filecons_to_string_nopdb(struct cil_db *db, char **out, size_t *size)
1433#endif
1434{
1435	uint32_t i = 0;
1436	int buf_pos = 0;
1437	size_t str_len = 0;
1438	char *str_tmp = NULL;
1439	struct cil_sort *filecons = db->filecon;
1440
1441	for (i = 0; i < filecons->count; i++) {
1442		struct cil_filecon *filecon = filecons->array[i];
1443		struct cil_context *ctx = filecon->context;
1444
1445		str_len += strlen(filecon->path_str);
1446
1447		if (filecon->type != CIL_FILECON_ANY) {
1448			/* If a type is specified,
1449			   +2 for type string, +1 for tab */
1450			str_len += 3;
1451		}
1452
1453		if (ctx != NULL) {
1454			struct cil_user *user = ctx->user;
1455			struct cil_role *role = ctx->role;
1456			struct cil_type *type = ctx->type;
1457
1458			str_len += (strlen(user->datum.fqn) + strlen(role->datum.fqn) + strlen(type->datum.fqn) + 3);
1459
1460			if (db->mls == CIL_TRUE) {
1461				struct cil_levelrange *range = ctx->range;
1462				if (cil_level_equals(range->low, range->high)) {
1463					str_len += __cil_level_strlen(range->low) + 1;
1464				} else {
1465					str_len += __cil_level_strlen(range->low) + __cil_level_strlen(range->high) + 2;
1466				}
1467			}
1468		} else {
1469			str_len += strlen("\t<<none>>");
1470		}
1471
1472		str_len++;
1473	}
1474
1475	*size = str_len * sizeof(char);
1476	str_tmp = cil_malloc(*size+1);
1477	*out = str_tmp;
1478
1479	for (i = 0; i < filecons->count; i++) {
1480		struct cil_filecon *filecon = filecons->array[i];
1481		struct cil_context *ctx = filecon->context;
1482		const char *str_type = NULL;
1483
1484		buf_pos = sprintf(str_tmp, "%s", filecon->path_str);
1485		str_tmp += buf_pos;
1486
1487		switch(filecon->type) {
1488		case CIL_FILECON_FILE:
1489			str_type = "\t--";
1490			break;
1491		case CIL_FILECON_DIR:
1492			str_type = "\t-d";
1493			break;
1494		case CIL_FILECON_CHAR:
1495			str_type = "\t-c";
1496			break;
1497		case CIL_FILECON_BLOCK:
1498			str_type = "\t-b";
1499			break;
1500		case CIL_FILECON_SOCKET:
1501			str_type = "\t-s";
1502			break;
1503		case CIL_FILECON_PIPE:
1504			str_type = "\t-p";
1505			break;
1506		case CIL_FILECON_SYMLINK:
1507			str_type = "\t-l";
1508			break;
1509		default:
1510			str_type = "";
1511			break;
1512		}
1513		buf_pos = sprintf(str_tmp, "%s", str_type);
1514		str_tmp += buf_pos;
1515
1516		if (ctx != NULL) {
1517			struct cil_user *user = ctx->user;
1518			struct cil_role *role = ctx->role;
1519			struct cil_type *type = ctx->type;
1520
1521			buf_pos = sprintf(str_tmp, "\t%s:%s:%s", user->datum.fqn, role->datum.fqn,
1522							  type->datum.fqn);
1523			str_tmp += buf_pos;
1524
1525			if (db->mls == CIL_TRUE) {
1526				struct cil_levelrange *range = ctx->range;
1527				buf_pos = sprintf(str_tmp, ":");
1528				str_tmp += buf_pos;
1529				buf_pos = __cil_level_to_string(range->low, str_tmp);
1530				str_tmp += buf_pos;
1531
1532				if (!cil_level_equals(range->low, range->high)) {
1533					buf_pos = sprintf(str_tmp, "-");
1534					str_tmp += buf_pos;
1535					buf_pos = __cil_level_to_string(range->high, str_tmp);
1536					str_tmp += buf_pos;
1537				}
1538			}
1539		} else {
1540			buf_pos = sprintf(str_tmp, "\t<<none>>");
1541			str_tmp += buf_pos;
1542		}
1543
1544		buf_pos = sprintf(str_tmp, "\n");
1545		str_tmp += buf_pos;
1546	}
1547
1548	return SEPOL_OK;
1549}
1550
1551#ifndef DISABLE_SYMVER
1552int cil_filecons_to_string_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db, char **out, size_t *size)
1553{
1554	return cil_filecons_to_string_nopdb(db, out, size);
1555}
1556#endif
1557
1558void cil_set_disable_dontaudit(struct cil_db *db, int disable_dontaudit)
1559{
1560	db->disable_dontaudit = disable_dontaudit;
1561}
1562
1563void cil_set_disable_neverallow(struct cil_db *db, int disable_neverallow)
1564{
1565	db->disable_neverallow = disable_neverallow;
1566}
1567
1568void cil_set_preserve_tunables(struct cil_db *db, int preserve_tunables)
1569{
1570	db->preserve_tunables = preserve_tunables;
1571}
1572
1573int cil_set_handle_unknown(struct cil_db *db, int handle_unknown)
1574{
1575	int rc = 0;
1576
1577	switch (handle_unknown) {
1578		case SEPOL_DENY_UNKNOWN:
1579		case SEPOL_REJECT_UNKNOWN:
1580		case SEPOL_ALLOW_UNKNOWN:
1581			db->handle_unknown = handle_unknown;
1582			break;
1583		default:
1584			cil_log(CIL_ERR, "Unknown value for handle-unknown: %i\n", handle_unknown);
1585			rc = -1;
1586	}
1587
1588	return rc;
1589}
1590
1591void cil_set_mls(struct cil_db *db, int mls)
1592{
1593	db->mls = mls;
1594}
1595
1596void cil_set_target_platform(struct cil_db *db, int target_platform)
1597{
1598	db->target_platform = target_platform;
1599}
1600
1601void cil_set_policy_version(struct cil_db *db, int policy_version)
1602{
1603	db->policy_version = policy_version;
1604}
1605
1606void cil_symtab_array_init(symtab_t symtab[], int symtab_sizes[CIL_SYM_NUM])
1607{
1608	uint32_t i = 0;
1609	for (i = 0; i < CIL_SYM_NUM; i++) {
1610		cil_symtab_init(&symtab[i], symtab_sizes[i]);
1611	}
1612}
1613
1614void cil_symtab_array_destroy(symtab_t symtab[])
1615{
1616	int i = 0;
1617	for (i = 0; i < CIL_SYM_NUM; i++) {
1618		cil_symtab_destroy(&symtab[i]);
1619	}
1620}
1621
1622void cil_destroy_ast_symtabs(struct cil_tree_node *current)
1623{
1624	while (current) {
1625		switch (current->flavor) {
1626		case CIL_BLOCK:
1627			cil_symtab_array_destroy(((struct cil_block*)current->data)->symtab);
1628			break;
1629		case CIL_IN:
1630			cil_symtab_array_destroy(((struct cil_in*)current->data)->symtab);
1631			break;
1632		case CIL_CLASS:
1633		case CIL_COMMON:
1634		case CIL_MAP_CLASS:
1635			cil_symtab_destroy(&((struct cil_class*)current->data)->perms);
1636			break;
1637		case CIL_MACRO:
1638			cil_symtab_array_destroy(((struct cil_macro*)current->data)->symtab);
1639			break;
1640		case CIL_CONDBLOCK:
1641			cil_symtab_array_destroy(((struct cil_condblock*)current->data)->symtab);
1642			break;
1643		default:
1644			break;
1645		}
1646
1647		if (current->cl_head) {
1648			cil_destroy_ast_symtabs(current->cl_head);
1649		}
1650
1651		current = current->next;
1652	}
1653}
1654
1655int cil_get_symtab(struct cil_tree_node *ast_node, symtab_t **symtab, enum cil_sym_index sym_index)
1656{
1657	struct cil_tree_node *node = ast_node;
1658	*symtab = NULL;
1659
1660	if (sym_index == CIL_SYM_PERMS) {
1661		/* Class statements are not blocks, so the passed node should be the class */
1662		if (node->flavor == CIL_CLASS || node->flavor == CIL_MAP_CLASS ||
1663			node->flavor == CIL_COMMON) {
1664			*symtab = &((struct cil_class*)node->data)->perms;
1665			return SEPOL_OK;
1666		}
1667		goto exit;
1668	}
1669
1670	if (sym_index < CIL_SYM_BLOCKS || sym_index >= CIL_SYM_NUM) {
1671		cil_log(CIL_ERR, "Invalid symtab type\n");
1672		goto exit;
1673	}
1674
1675	while (node != NULL && *symtab == NULL) {
1676		switch (node->flavor) {
1677		case CIL_ROOT:
1678			*symtab = &((struct cil_root *)node->data)->symtab[sym_index];
1679			break;
1680		case CIL_BLOCK:
1681			*symtab = &((struct cil_block*)node->data)->symtab[sym_index];
1682			break;
1683		case CIL_MACRO:
1684			*symtab = &((struct cil_macro*)node->data)->symtab[sym_index];
1685			break;
1686		case CIL_IN:
1687			/* In blocks only exist before resolving the AST */
1688			*symtab = &((struct cil_in*)node->data)->symtab[sym_index];
1689			break;
1690		case CIL_CONDBLOCK: {
1691			if (node->parent->flavor == CIL_TUNABLEIF) {
1692				/* Cond blocks only exist before resolving the AST */
1693				*symtab = &((struct cil_condblock*)node->data)->symtab[sym_index];
1694			} else if (node->parent->flavor == CIL_BOOLEANIF) {
1695				node = node->parent->parent;
1696			}
1697			break;
1698		}
1699		default:
1700			node = node->parent;
1701		}
1702	}
1703
1704	if (*symtab == NULL) {
1705		goto exit;
1706	}
1707
1708	return SEPOL_OK;
1709
1710exit:
1711	cil_log(CIL_ERR, "Failed to get symtab from node at line %d of %s\n",
1712			ast_node->line, ast_node->path);
1713	return SEPOL_ERR;
1714}
1715
1716void cil_sort_init(struct cil_sort **sort)
1717{
1718	*sort = cil_malloc(sizeof(**sort));
1719
1720	(*sort)->flavor = CIL_NONE;
1721	(*sort)->count = 0;
1722	(*sort)->index = 0;
1723	(*sort)->array = NULL;
1724}
1725
1726void cil_sort_destroy(struct cil_sort **sort)
1727{
1728	(*sort)->flavor = CIL_NONE;
1729	(*sort)->count = 0;
1730	(*sort)->index = 0;
1731	if ((*sort)->array != NULL) {
1732		free((*sort)->array);
1733	}
1734	(*sort)->array = NULL;
1735
1736	free(*sort);
1737	*sort = NULL;
1738}
1739
1740void cil_netifcon_init(struct cil_netifcon **netifcon)
1741{
1742	*netifcon = cil_malloc(sizeof(**netifcon));
1743
1744	(*netifcon)->interface_str = NULL;
1745	(*netifcon)->if_context_str = NULL;
1746	(*netifcon)->if_context = NULL;
1747	(*netifcon)->packet_context_str = NULL;
1748	(*netifcon)->packet_context = NULL;
1749	(*netifcon)->context_str = NULL;
1750}
1751
1752void cil_context_init(struct cil_context **context)
1753{
1754	*context = cil_malloc(sizeof(**context));
1755
1756	cil_symtab_datum_init(&(*context)->datum);
1757	(*context)->user_str = NULL;
1758	(*context)->user = NULL;
1759	(*context)->role_str = NULL;
1760	(*context)->role = NULL;
1761	(*context)->type_str = NULL;
1762	(*context)->type = NULL;
1763	(*context)->range_str = NULL;
1764	(*context)->range = NULL;
1765}
1766
1767void cil_level_init(struct cil_level **level)
1768{
1769	*level = cil_malloc(sizeof(**level));
1770
1771	cil_symtab_datum_init(&(*level)->datum);
1772	(*level)->sens_str = NULL;
1773	(*level)->sens = NULL;
1774	(*level)->cats = NULL;
1775}
1776
1777void cil_levelrange_init(struct cil_levelrange **range)
1778{
1779	*range = cil_malloc(sizeof(**range));
1780
1781	cil_symtab_datum_init(&(*range)->datum);
1782	(*range)->low_str = NULL;
1783	(*range)->low = NULL;
1784	(*range)->high_str = NULL;
1785	(*range)->high = NULL;
1786}
1787
1788void cil_sens_init(struct cil_sens **sens)
1789{
1790	*sens = cil_malloc(sizeof(**sens));
1791
1792	cil_symtab_datum_init(&(*sens)->datum);
1793
1794	(*sens)->cats_list = NULL;
1795
1796	(*sens)->ordered = CIL_FALSE;
1797}
1798
1799void cil_block_init(struct cil_block **block)
1800{
1801	*block = cil_malloc(sizeof(**block));
1802
1803	cil_symtab_datum_init(&(*block)->datum);
1804
1805	cil_symtab_array_init((*block)->symtab, cil_sym_sizes[CIL_SYM_ARRAY_BLOCK]);
1806
1807	(*block)->is_abstract = CIL_FALSE;
1808
1809	(*block)->bi_nodes = NULL;
1810}
1811
1812void cil_blockinherit_init(struct cil_blockinherit **inherit)
1813{
1814	*inherit = cil_malloc(sizeof(**inherit));
1815	(*inherit)->block_str = NULL;
1816	(*inherit)->block = NULL;
1817}
1818
1819void cil_blockabstract_init(struct cil_blockabstract **abstract)
1820{
1821	*abstract = cil_malloc(sizeof(**abstract));
1822	(*abstract)->block_str = NULL;
1823}
1824
1825void cil_in_init(struct cil_in **in)
1826{
1827	*in = cil_malloc(sizeof(**in));
1828
1829	cil_symtab_array_init((*in)->symtab, cil_sym_sizes[CIL_SYM_ARRAY_IN]);
1830	(*in)->block_str = NULL;
1831}
1832
1833void cil_class_init(struct cil_class **class)
1834{
1835	*class = cil_malloc(sizeof(**class));
1836
1837	cil_symtab_datum_init(&(*class)->datum);
1838
1839	cil_symtab_init(&(*class)->perms, CIL_CLASS_SYM_SIZE);
1840
1841	(*class)->num_perms = 0;
1842	(*class)->common = NULL;
1843	(*class)->ordered = CIL_FALSE;
1844}
1845
1846void cil_classorder_init(struct cil_classorder **classorder)
1847{
1848	*classorder = cil_malloc(sizeof(**classorder));
1849
1850	(*classorder)->class_list_str = NULL;
1851}
1852
1853void cil_classcommon_init(struct cil_classcommon **classcommon)
1854{
1855	*classcommon = cil_malloc(sizeof(**classcommon));
1856
1857	(*classcommon)->class_str = NULL;
1858	(*classcommon)->common_str = NULL;
1859}
1860
1861void cil_sid_init(struct cil_sid **sid)
1862{
1863	*sid = cil_malloc(sizeof(**sid));
1864
1865	cil_symtab_datum_init(&(*sid)->datum);
1866
1867	(*sid)->ordered = CIL_FALSE;
1868	(*sid)->context = NULL;
1869}
1870
1871void cil_sidcontext_init(struct cil_sidcontext **sidcontext)
1872{
1873	*sidcontext = cil_malloc(sizeof(**sidcontext));
1874
1875	(*sidcontext)->sid_str = NULL;
1876	(*sidcontext)->context_str = NULL;
1877	(*sidcontext)->context = NULL;
1878}
1879
1880void cil_sidorder_init(struct cil_sidorder **sidorder)
1881{
1882	*sidorder = cil_malloc(sizeof(**sidorder));
1883
1884	(*sidorder)->sid_list_str = NULL;
1885}
1886
1887void cil_userrole_init(struct cil_userrole **userrole)
1888{
1889	*userrole = cil_malloc(sizeof(**userrole));
1890
1891	(*userrole)->user_str = NULL;
1892	(*userrole)->user = NULL;
1893	(*userrole)->role_str = NULL;
1894	(*userrole)->role = NULL;
1895}
1896
1897void cil_userprefix_init(struct cil_userprefix **userprefix)
1898{
1899	*userprefix = cil_malloc(sizeof(**userprefix));
1900
1901	(*userprefix)->user_str = NULL;
1902	(*userprefix)->user = NULL;
1903	(*userprefix)->prefix_str = NULL;
1904}
1905
1906void cil_selinuxuser_init(struct cil_selinuxuser **selinuxuser)
1907{
1908	*selinuxuser = cil_malloc(sizeof(**selinuxuser));
1909
1910	(*selinuxuser)->name_str = NULL;
1911	(*selinuxuser)->user_str = NULL;
1912	(*selinuxuser)->user = NULL;
1913	(*selinuxuser)->range_str = NULL;
1914	(*selinuxuser)->range = NULL;
1915}
1916
1917void cil_roletype_init(struct cil_roletype **roletype)
1918{
1919	*roletype = cil_malloc(sizeof(**roletype));
1920
1921	(*roletype)->role_str = NULL;
1922	(*roletype)->role = NULL;
1923	(*roletype)->type_str = NULL;
1924	(*roletype)->type = NULL;
1925}
1926
1927void cil_roleattribute_init(struct cil_roleattribute **attr)
1928{
1929	*attr = cil_malloc(sizeof(**attr));
1930
1931	cil_symtab_datum_init(&(*attr)->datum);
1932
1933	(*attr)->expr_list = NULL;
1934	(*attr)->roles = NULL;
1935}
1936
1937void cil_roleattributeset_init(struct cil_roleattributeset **attrset)
1938{
1939	*attrset = cil_malloc(sizeof(**attrset));
1940
1941	(*attrset)->attr_str = NULL;
1942	(*attrset)->str_expr = NULL;
1943	(*attrset)->datum_expr = NULL;
1944}
1945
1946void cil_typeattribute_init(struct cil_typeattribute **attr)
1947{
1948	*attr = cil_malloc(sizeof(**attr));
1949
1950	cil_symtab_datum_init(&(*attr)->datum);
1951
1952	(*attr)->expr_list = NULL;
1953	(*attr)->types = NULL;
1954	(*attr)->used = CIL_FALSE;
1955}
1956
1957void cil_typeattributeset_init(struct cil_typeattributeset **attrset)
1958{
1959	*attrset = cil_malloc(sizeof(**attrset));
1960
1961	(*attrset)->attr_str = NULL;
1962	(*attrset)->str_expr = NULL;
1963	(*attrset)->datum_expr = NULL;
1964}
1965
1966void cil_alias_init(struct cil_alias **alias)
1967{
1968	*alias = cil_malloc(sizeof(**alias));
1969
1970	(*alias)->actual = NULL;
1971
1972	cil_symtab_datum_init(&(*alias)->datum);
1973}
1974
1975void cil_aliasactual_init(struct cil_aliasactual **aliasactual)
1976{
1977	*aliasactual = cil_malloc(sizeof(**aliasactual));
1978
1979	(*aliasactual)->alias_str = NULL;
1980	(*aliasactual)->actual_str = NULL;
1981}
1982
1983void cil_typepermissive_init(struct cil_typepermissive **typeperm)
1984{
1985	*typeperm = cil_malloc(sizeof(**typeperm));
1986
1987	(*typeperm)->type_str = NULL;
1988	(*typeperm)->type = NULL;
1989}
1990
1991void cil_name_init(struct cil_name **name)
1992{
1993	*name = cil_malloc(sizeof(**name));
1994
1995	cil_symtab_datum_init(&(*name)->datum);
1996	(*name)->name_str = NULL;
1997}
1998
1999void cil_nametypetransition_init(struct cil_nametypetransition **nametypetrans)
2000{
2001	*nametypetrans = cil_malloc(sizeof(**nametypetrans));
2002
2003	(*nametypetrans)->src_str = NULL;
2004	(*nametypetrans)->src = NULL;
2005	(*nametypetrans)->tgt_str = NULL;
2006	(*nametypetrans)->tgt = NULL;
2007	(*nametypetrans)->obj_str = NULL;
2008	(*nametypetrans)->obj = NULL;
2009	(*nametypetrans)->name_str = NULL;
2010	(*nametypetrans)->name = NULL;
2011	(*nametypetrans)->result_str = NULL;
2012	(*nametypetrans)->result = NULL;
2013}
2014
2015void cil_rangetransition_init(struct cil_rangetransition **rangetrans)
2016{
2017        *rangetrans = cil_malloc(sizeof(**rangetrans));
2018
2019	(*rangetrans)->src_str = NULL;
2020	(*rangetrans)->src = NULL;
2021	(*rangetrans)->exec_str = NULL;
2022	(*rangetrans)->exec = NULL;
2023	(*rangetrans)->obj_str = NULL;
2024	(*rangetrans)->obj = NULL;
2025	(*rangetrans)->range_str = NULL;
2026	(*rangetrans)->range = NULL;
2027}
2028
2029void cil_bool_init(struct cil_bool **cilbool)
2030{
2031	*cilbool = cil_malloc(sizeof(**cilbool));
2032
2033	cil_symtab_datum_init(&(*cilbool)->datum);
2034	(*cilbool)->value = 0;
2035}
2036
2037void cil_tunable_init(struct cil_tunable **ciltun)
2038{
2039	*ciltun = cil_malloc(sizeof(**ciltun));
2040
2041	cil_symtab_datum_init(&(*ciltun)->datum);
2042	(*ciltun)->value = 0;
2043}
2044
2045void cil_condblock_init(struct cil_condblock **cb)
2046{
2047	*cb = cil_malloc(sizeof(**cb));
2048
2049	(*cb)->flavor = CIL_NONE;
2050	cil_symtab_array_init((*cb)->symtab, cil_sym_sizes[CIL_SYM_ARRAY_CONDBLOCK]);
2051}
2052
2053void cil_boolif_init(struct cil_booleanif **bif)
2054{
2055	*bif = cil_malloc(sizeof(**bif));
2056
2057	(*bif)->str_expr = NULL;
2058	(*bif)->datum_expr = NULL;
2059}
2060
2061void cil_tunif_init(struct cil_tunableif **tif)
2062{
2063	*tif = cil_malloc(sizeof(**tif));
2064
2065	(*tif)->str_expr = NULL;
2066	(*tif)->datum_expr = NULL;
2067}
2068
2069void cil_avrule_init(struct cil_avrule **avrule)
2070{
2071	*avrule = cil_malloc(sizeof(**avrule));
2072
2073	(*avrule)->rule_kind = CIL_NONE;
2074	(*avrule)->src_str = NULL;
2075	(*avrule)->src = NULL;
2076	(*avrule)->tgt_str = NULL;
2077	(*avrule)->tgt = NULL;
2078	(*avrule)->classperms = NULL;
2079}
2080
2081void cil_type_rule_init(struct cil_type_rule **type_rule)
2082{
2083	*type_rule = cil_malloc(sizeof(**type_rule));
2084
2085	(*type_rule)->rule_kind = CIL_NONE;
2086	(*type_rule)->src_str = NULL;
2087	(*type_rule)->src = NULL;
2088	(*type_rule)->tgt_str = NULL;
2089	(*type_rule)->tgt = NULL;
2090	(*type_rule)->obj_str = NULL;
2091	(*type_rule)->obj = NULL;
2092	(*type_rule)->result_str = NULL;
2093	(*type_rule)->result = NULL;
2094}
2095
2096void cil_roletransition_init(struct cil_roletransition **role_trans)
2097{
2098	*role_trans = cil_malloc(sizeof(**role_trans));
2099
2100	(*role_trans)->src_str = NULL;
2101	(*role_trans)->src = NULL;
2102	(*role_trans)->tgt_str = NULL;
2103	(*role_trans)->tgt = NULL;
2104	(*role_trans)->obj_str = NULL;
2105	(*role_trans)->obj = NULL;
2106	(*role_trans)->result_str = NULL;
2107	(*role_trans)->result = NULL;
2108}
2109
2110void cil_roleallow_init(struct cil_roleallow **roleallow)
2111{
2112	*roleallow = cil_malloc(sizeof(**roleallow));
2113
2114	(*roleallow)->src_str = NULL;
2115	(*roleallow)->src = NULL;
2116	(*roleallow)->tgt_str = NULL;
2117	(*roleallow)->tgt = NULL;
2118}
2119
2120void cil_catset_init(struct cil_catset **catset)
2121{
2122	*catset = cil_malloc(sizeof(**catset));
2123
2124	cil_symtab_datum_init(&(*catset)->datum);
2125	(*catset)->cats = NULL;
2126}
2127
2128void cil_senscat_init(struct cil_senscat **senscat)
2129{
2130	*senscat = cil_malloc(sizeof(**senscat));
2131
2132	(*senscat)->sens_str = NULL;
2133	(*senscat)->cats = NULL;
2134}
2135
2136void cil_cats_init(struct cil_cats **cats)
2137{
2138	*cats = cil_malloc(sizeof(**cats));
2139
2140	(*cats)->evaluated = CIL_FALSE;
2141	(*cats)->str_expr = NULL;
2142	(*cats)->datum_expr = NULL;
2143}
2144
2145void cil_filecon_init(struct cil_filecon **filecon)
2146{
2147	*filecon = cil_malloc(sizeof(**filecon));
2148
2149	(*filecon)->path_str = NULL;
2150	(*filecon)->type = 0;
2151	(*filecon)->context_str = NULL;
2152	(*filecon)->context = NULL;
2153}
2154
2155void cil_portcon_init(struct cil_portcon **portcon)
2156{
2157	*portcon = cil_malloc(sizeof(**portcon));
2158	(*portcon)->proto = 0;
2159	(*portcon)->port_low = 0;
2160	(*portcon)->port_high = 0;
2161	(*portcon)->context_str = NULL;
2162	(*portcon)->context = NULL;
2163}
2164
2165void cil_nodecon_init(struct cil_nodecon **nodecon)
2166{
2167	*nodecon = cil_malloc(sizeof(**nodecon));
2168
2169	(*nodecon)->addr_str = NULL;
2170	(*nodecon)->addr = NULL;
2171	(*nodecon)->mask_str = NULL;
2172	(*nodecon)->mask = NULL;
2173	(*nodecon)->context_str = NULL;
2174	(*nodecon)->context = NULL;
2175}
2176
2177void cil_genfscon_init(struct cil_genfscon **genfscon)
2178{
2179	*genfscon = cil_malloc(sizeof(**genfscon));
2180
2181	(*genfscon)->fs_str = NULL;
2182	(*genfscon)->path_str = NULL;
2183	(*genfscon)->context_str = NULL;
2184	(*genfscon)->context = NULL;
2185}
2186
2187void cil_pirqcon_init(struct cil_pirqcon **pirqcon)
2188{
2189	*pirqcon = cil_malloc(sizeof(**pirqcon));
2190
2191	(*pirqcon)->pirq = 0;
2192	(*pirqcon)->context_str = NULL;
2193	(*pirqcon)->context = NULL;
2194}
2195
2196void cil_iomemcon_init(struct cil_iomemcon **iomemcon)
2197{
2198	*iomemcon = cil_malloc(sizeof(**iomemcon));
2199
2200	(*iomemcon)->iomem_low = 0;
2201	(*iomemcon)->iomem_high = 0;
2202	(*iomemcon)->context_str = NULL;
2203	(*iomemcon)->context = NULL;
2204}
2205
2206void cil_ioportcon_init(struct cil_ioportcon **ioportcon)
2207{
2208	*ioportcon = cil_malloc(sizeof(**ioportcon));
2209
2210	(*ioportcon)->context_str = NULL;
2211	(*ioportcon)->context = NULL;
2212}
2213
2214void cil_pcidevicecon_init(struct cil_pcidevicecon **pcidevicecon)
2215{
2216	*pcidevicecon = cil_malloc(sizeof(**pcidevicecon));
2217
2218	(*pcidevicecon)->dev = 0;
2219	(*pcidevicecon)->context_str = NULL;
2220	(*pcidevicecon)->context = NULL;
2221}
2222
2223void cil_devicetreecon_init(struct cil_devicetreecon **dtcon)
2224{
2225	*dtcon = cil_malloc(sizeof(**dtcon));
2226
2227	(*dtcon)->path = NULL;
2228	(*dtcon)->context_str = NULL;
2229	(*dtcon)->context = NULL;
2230}
2231
2232void cil_fsuse_init(struct cil_fsuse **fsuse)
2233{
2234	*fsuse = cil_malloc(sizeof(**fsuse));
2235
2236	(*fsuse)->type = 0;
2237	(*fsuse)->fs_str = NULL;
2238	(*fsuse)->context_str = NULL;
2239	(*fsuse)->context = NULL;
2240}
2241
2242void cil_constrain_init(struct cil_constrain **constrain)
2243{
2244	*constrain = cil_malloc(sizeof(**constrain));
2245
2246	(*constrain)->classperms = NULL;
2247	(*constrain)->str_expr = NULL;
2248	(*constrain)->datum_expr = NULL;
2249}
2250
2251void cil_validatetrans_init(struct cil_validatetrans **validtrans)
2252{
2253	*validtrans = cil_malloc(sizeof(**validtrans));
2254
2255	(*validtrans)->class_str = NULL;
2256	(*validtrans)->class = NULL;
2257	(*validtrans)->str_expr = NULL;
2258	(*validtrans)->datum_expr = NULL;
2259}
2260
2261void cil_ipaddr_init(struct cil_ipaddr **ipaddr)
2262{
2263	*ipaddr = cil_malloc(sizeof(**ipaddr));
2264
2265	cil_symtab_datum_init(&(*ipaddr)->datum);
2266	memset(&(*ipaddr)->ip, 0, sizeof((*ipaddr)->ip));
2267}
2268
2269void cil_perm_init(struct cil_perm **perm)
2270{
2271	*perm = cil_malloc(sizeof(**perm));
2272
2273	cil_symtab_datum_init(&(*perm)->datum);
2274	(*perm)->value = 0;
2275	(*perm)->classperms = NULL;
2276}
2277
2278void cil_classpermission_init(struct cil_classpermission **cp)
2279{
2280	*cp = cil_malloc(sizeof(**cp));
2281
2282	cil_symtab_datum_init(&(*cp)->datum);
2283	(*cp)->classperms = NULL;
2284}
2285
2286void cil_classpermissionset_init(struct cil_classpermissionset **cps)
2287{
2288	*cps = cil_malloc(sizeof(**cps));
2289
2290	(*cps)->set_str = NULL;
2291	(*cps)->classperms = NULL;
2292}
2293
2294void cil_classperms_set_init(struct cil_classperms_set **cp_set)
2295{
2296	*cp_set = cil_malloc(sizeof(**cp_set));
2297	(*cp_set)->set_str = NULL;
2298	(*cp_set)->set = NULL;
2299}
2300
2301void cil_classperms_init(struct cil_classperms **cp)
2302{
2303	*cp = cil_malloc(sizeof(**cp));
2304	(*cp)->class_str = NULL;
2305	(*cp)->class = NULL;
2306	(*cp)->perm_strs = NULL;
2307	(*cp)->perms = NULL;
2308}
2309
2310void cil_classmapping_init(struct cil_classmapping **mapping)
2311{
2312	*mapping = cil_malloc(sizeof(**mapping));
2313
2314	(*mapping)->map_class_str = NULL;
2315	(*mapping)->map_perm_str = NULL;
2316	(*mapping)->classperms = NULL;
2317}
2318
2319void cil_user_init(struct cil_user **user)
2320{
2321	*user = cil_malloc(sizeof(**user));
2322
2323	cil_symtab_datum_init(&(*user)->datum);
2324	(*user)->bounds = NULL;
2325	(*user)->roles = NULL;
2326	(*user)->dftlevel = NULL;
2327	(*user)->range = NULL;
2328}
2329
2330void cil_userlevel_init(struct cil_userlevel **usrlvl)
2331{
2332	*usrlvl = cil_malloc(sizeof(**usrlvl));
2333
2334	(*usrlvl)->user_str = NULL;
2335	(*usrlvl)->level_str = NULL;
2336	(*usrlvl)->level = NULL;
2337}
2338
2339void cil_userrange_init(struct cil_userrange **userrange)
2340{
2341	*userrange = cil_malloc(sizeof(**userrange));
2342
2343	(*userrange)->user_str = NULL;
2344	(*userrange)->range_str = NULL;
2345	(*userrange)->range = NULL;
2346}
2347
2348void cil_role_init(struct cil_role **role)
2349{
2350	*role = cil_malloc(sizeof(**role));
2351
2352	cil_symtab_datum_init(&(*role)->datum);
2353	(*role)->bounds = NULL;
2354	(*role)->types = NULL;
2355	(*role)->value = 0;
2356}
2357
2358void cil_type_init(struct cil_type **type)
2359{
2360	*type = cil_malloc(sizeof(**type));
2361
2362	cil_symtab_datum_init(&(*type)->datum);
2363	(*type)->bounds = NULL;
2364	(*type)->value = 0;
2365}
2366
2367void cil_cat_init(struct cil_cat **cat)
2368{
2369	*cat = cil_malloc(sizeof(**cat));
2370
2371	cil_symtab_datum_init(&(*cat)->datum);
2372	(*cat)->ordered = CIL_FALSE;
2373	(*cat)->value = 0;
2374}
2375
2376void cil_catorder_init(struct cil_catorder **catorder)
2377{
2378	*catorder = cil_malloc(sizeof(**catorder));
2379
2380	(*catorder)->cat_list_str = NULL;
2381}
2382
2383void cil_sensorder_init(struct cil_sensorder **sensorder)
2384{
2385	*sensorder = cil_malloc(sizeof(**sensorder));
2386
2387	(*sensorder)->sens_list_str = NULL;
2388}
2389
2390void cil_args_init(struct cil_args **args)
2391{
2392	*args = cil_malloc(sizeof(**args));
2393	(*args)->arg_str = NULL;
2394	(*args)->arg = NULL;
2395	(*args)->param_str = NULL;
2396	(*args)->flavor = CIL_NONE;
2397}
2398
2399void cil_call_init(struct cil_call **call)
2400{
2401	*call = cil_malloc(sizeof(**call));
2402
2403	(*call)->macro_str = NULL;
2404	(*call)->macro = NULL;
2405	(*call)->args_tree = NULL;
2406	(*call)->args = NULL;
2407	(*call)->copied = 0;
2408}
2409
2410void cil_optional_init(struct cil_optional **optional)
2411{
2412	*optional = cil_malloc(sizeof(**optional));
2413	(*optional)->enabled = CIL_TRUE;
2414	cil_symtab_datum_init(&(*optional)->datum);
2415}
2416
2417void cil_param_init(struct cil_param **param)
2418{
2419	*param = cil_malloc(sizeof(**param));
2420
2421	(*param)->str = NULL;
2422	(*param)->flavor = CIL_NONE;
2423}
2424
2425void cil_macro_init(struct cil_macro **macro)
2426{
2427	*macro = cil_malloc(sizeof(**macro));
2428
2429	cil_symtab_datum_init(&(*macro)->datum);
2430	cil_symtab_array_init((*macro)->symtab, cil_sym_sizes[CIL_SYM_ARRAY_MACRO]);
2431	(*macro)->params = NULL;
2432}
2433
2434void cil_policycap_init(struct cil_policycap **policycap)
2435{
2436	*policycap = cil_malloc(sizeof(**policycap));
2437
2438	cil_symtab_datum_init(&(*policycap)->datum);
2439}
2440
2441void cil_bounds_init(struct cil_bounds **bounds)
2442{
2443	*bounds = cil_malloc(sizeof(**bounds));
2444
2445	(*bounds)->parent_str = NULL;
2446	(*bounds)->child_str = NULL;
2447}
2448
2449void cil_default_init(struct cil_default **def)
2450{
2451	*def = cil_malloc(sizeof(**def));
2452
2453	(*def)->flavor = CIL_NONE;
2454	(*def)->class_strs = NULL;
2455	(*def)->class_datums = NULL;
2456}
2457
2458void cil_defaultrange_init(struct cil_defaultrange **def)
2459{
2460	*def = cil_malloc(sizeof(**def));
2461
2462	(*def)->class_strs = NULL;
2463	(*def)->class_datums = NULL;
2464}
2465
2466void cil_handleunknown_init(struct cil_handleunknown **unk)
2467{
2468	*unk = cil_malloc(sizeof(**unk));
2469}
2470
2471void cil_mls_init(struct cil_mls **mls)
2472{
2473	*mls = cil_malloc(sizeof(**mls));
2474	(*mls)->value = 0;
2475}
2476