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