policy_parse.y revision 13cd4c8960688af11ad23b4c946149015c80d549
1
2/*
3 * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
4 */
5
6/*
7 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
8 *
9 *	Support for enhanced MLS infrastructure.
10 *
11 * Updated: David Caplan, <dac@tresys.com>
12 *
13 * 	Added conditional policy language extensions
14 *
15 * Updated: Joshua Brindle <jbrindle@tresys.com>
16 *	    Karl MacMillan <kmacmillan@mentalrootkit.com>
17 *          Jason Tang     <jtang@tresys.com>
18 *
19 *	Added support for binary policy modules
20 *
21 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
22 * Copyright (C) 2003 - 2008 Tresys Technology, LLC
23 * Copyright (C) 2007 Red Hat Inc.
24 *	This program is free software; you can redistribute it and/or modify
25 *  	it under the terms of the GNU General Public License as published by
26 *	the Free Software Foundation, version 2.
27 */
28
29/* FLASK */
30
31%{
32#include <sys/types.h>
33#include <assert.h>
34#include <stdarg.h>
35#include <stdint.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#include <sys/socket.h>
40#include <netinet/in.h>
41#include <arpa/inet.h>
42#include <stdlib.h>
43
44#include <sepol/policydb/expand.h>
45#include <sepol/policydb/policydb.h>
46#include <sepol/policydb/services.h>
47#include <sepol/policydb/conditional.h>
48#include <sepol/policydb/flask.h>
49#include <sepol/policydb/hierarchy.h>
50#include <sepol/policydb/polcaps.h>
51#include "queue.h"
52#include "checkpolicy.h"
53#include "module_compiler.h"
54#include "policy_define.h"
55
56extern policydb_t *policydbp;
57extern unsigned int pass;
58
59extern char yytext[];
60extern int yylex(void);
61extern int yywarn(char *msg);
62extern int yyerror(char *msg);
63
64typedef int (* require_func_t)();
65
66%}
67
68%union {
69	unsigned int val;
70	uintptr_t valptr;
71	void *ptr;
72        require_func_t require_func;
73}
74
75%type <ptr> cond_expr cond_expr_prim cond_pol_list cond_else
76%type <ptr> cond_allow_def cond_auditallow_def cond_auditdeny_def cond_dontaudit_def
77%type <ptr> cond_transition_def cond_te_avtab_def cond_rule_def
78%type <ptr> role_def roles
79%type <valptr> cexpr cexpr_prim op role_mls_op
80%type <val> ipv4_addr_def number
81%type <require_func> require_decl_def
82
83%token PATH
84%token CLONE
85%token COMMON
86%token CLASS
87%token CONSTRAIN
88%token VALIDATETRANS
89%token INHERITS
90%token SID
91%token ROLE
92%token ROLES
93%token TYPEALIAS
94%token TYPEATTRIBUTE
95%token TYPE
96%token TYPES
97%token ALIAS
98%token ATTRIBUTE
99%token BOOL
100%token IF
101%token ELSE
102%token TYPE_TRANSITION
103%token TYPE_MEMBER
104%token TYPE_CHANGE
105%token ROLE_TRANSITION
106%token RANGE_TRANSITION
107%token SENSITIVITY
108%token DOMINANCE
109%token DOM DOMBY INCOMP
110%token CATEGORY
111%token LEVEL
112%token RANGE
113%token MLSCONSTRAIN
114%token MLSVALIDATETRANS
115%token USER
116%token NEVERALLOW
117%token ALLOW
118%token AUDITALLOW
119%token AUDITDENY
120%token DONTAUDIT
121%token SOURCE
122%token TARGET
123%token SAMEUSER
124%token FSCON PORTCON NETIFCON NODECON
125%token FSUSEXATTR FSUSETASK FSUSETRANS
126%token GENFSCON
127%token U1 U2 U3 R1 R2 R3 T1 T2 T3 L1 L2 H1 H2
128%token NOT AND OR XOR
129%token CTRUE CFALSE
130%token IDENTIFIER
131%token NUMBER
132%token EQUALS
133%token NOTEQUAL
134%token IPV4_ADDR
135%token IPV6_ADDR
136%token MODULE VERSION_IDENTIFIER REQUIRE OPTIONAL
137%token POLICYCAP
138%token PERMISSIVE
139
140%left OR
141%left XOR
142%left AND
143%right NOT
144%left EQUALS NOTEQUAL
145%%
146policy			: base_policy
147                        | module_policy
148                        ;
149base_policy             : { if (define_policy(pass, 0) == -1) return -1; }
150                          classes initial_sids access_vectors
151                          { if (pass == 1) { if (policydb_index_classes(policydbp)) return -1; }
152                            else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1; }}
153			  opt_mls te_rbac users opt_constraints
154                         { if (pass == 1) { if (policydb_index_bools(policydbp)) return -1;}
155			   else if (pass == 2) { if (policydb_index_others(NULL, policydbp, 0)) return -1;}}
156			  initial_sid_contexts opt_fs_contexts opt_fs_uses opt_genfs_contexts net_contexts
157			;
158classes			: class_def
159			| classes class_def
160			;
161class_def		: CLASS identifier
162			{if (define_class()) return -1;}
163			;
164initial_sids 		: initial_sid_def
165			| initial_sids initial_sid_def
166			;
167initial_sid_def		: SID identifier
168                        {if (define_initial_sid()) return -1;}
169			;
170access_vectors		: opt_common_perms av_perms
171			;
172opt_common_perms        : common_perms
173                        |
174                        ;
175common_perms		: common_perms_def
176			| common_perms common_perms_def
177			;
178common_perms_def	: COMMON identifier '{' identifier_list '}'
179			{if (define_common_perms()) return -1;}
180			;
181av_perms		: av_perms_def
182			| av_perms av_perms_def
183			;
184av_perms_def		: CLASS identifier '{' identifier_list '}'
185			{if (define_av_perms(FALSE)) return -1;}
186                        | CLASS identifier INHERITS identifier
187			{if (define_av_perms(TRUE)) return -1;}
188                        | CLASS identifier INHERITS identifier '{' identifier_list '}'
189			{if (define_av_perms(TRUE)) return -1;}
190			;
191opt_mls			: mls
192                        |
193			;
194mls			: sensitivities dominance opt_categories levels mlspolicy
195			;
196sensitivities	 	: sensitivity_def
197			| sensitivities sensitivity_def
198			;
199sensitivity_def		: SENSITIVITY identifier alias_def ';'
200			{if (define_sens()) return -1;}
201			| SENSITIVITY identifier ';'
202			{if (define_sens()) return -1;}
203	                ;
204alias_def		: ALIAS names
205			;
206dominance		: DOMINANCE identifier
207			{if (define_dominance()) return -1;}
208                        | DOMINANCE '{' identifier_list '}'
209			{if (define_dominance()) return -1;}
210			;
211opt_categories          : categories
212                        |
213                        ;
214categories 		: category_def
215			| categories category_def
216			;
217category_def		: CATEGORY identifier alias_def ';'
218			{if (define_category()) return -1;}
219			| CATEGORY identifier ';'
220			{if (define_category()) return -1;}
221			;
222levels	 		: level_def
223			| levels level_def
224			;
225level_def		: LEVEL identifier ':' id_comma_list ';'
226			{if (define_level()) return -1;}
227			| LEVEL identifier ';'
228			{if (define_level()) return -1;}
229			;
230mlspolicy		: mlspolicy_decl
231			| mlspolicy mlspolicy_decl
232			;
233mlspolicy_decl		: mlsconstraint_def
234			| mlsvalidatetrans_def
235			;
236mlsconstraint_def	: MLSCONSTRAIN names names cexpr ';'
237			{ if (define_constraint((constraint_expr_t*)$4)) return -1; }
238			;
239mlsvalidatetrans_def	: MLSVALIDATETRANS names cexpr ';'
240			{ if (define_validatetrans((constraint_expr_t*)$3)) return -1; }
241			;
242te_rbac			: te_rbac_decl
243			| te_rbac te_rbac_decl
244			;
245te_rbac_decl		: te_decl
246			| rbac_decl
247                        | cond_stmt_def
248			| optional_block
249			| policycap_def
250			| ';'
251                        ;
252rbac_decl		: role_type_def
253                        | role_dominance
254                        | role_trans_def
255 			| role_allow_def
256			;
257te_decl			: attribute_def
258                        | type_def
259                        | typealias_def
260                        | typeattribute_def
261                        | bool_def
262                        | transition_def
263                        | range_trans_def
264                        | te_avtab_def
265			| permissive_def
266			;
267attribute_def           : ATTRIBUTE identifier ';'
268                        { if (define_attrib()) return -1;}
269                        ;
270type_def		: TYPE identifier alias_def opt_attr_list ';'
271                        {if (define_type(1)) return -1;}
272	                | TYPE identifier opt_attr_list ';'
273                        {if (define_type(0)) return -1;}
274    			;
275typealias_def           : TYPEALIAS identifier alias_def ';'
276			{if (define_typealias()) return -1;}
277			;
278typeattribute_def	: TYPEATTRIBUTE identifier id_comma_list ';'
279			{if (define_typeattribute()) return -1;}
280			;
281opt_attr_list           : ',' id_comma_list
282			|
283			;
284bool_def                : BOOL identifier bool_val ';'
285                        {if (define_bool()) return -1;}
286                        ;
287bool_val                : CTRUE
288 			{ if (insert_id("T",0)) return -1; }
289                        | CFALSE
290			{ if (insert_id("F",0)) return -1; }
291                        ;
292cond_stmt_def           : IF cond_expr '{' cond_pol_list '}' cond_else
293                        { if (pass == 2) { if (define_conditional((cond_expr_t*)$2, (avrule_t*)$4, (avrule_t*)$6) < 0) return -1;  }}
294                        ;
295cond_else		: ELSE '{' cond_pol_list '}'
296			{ $$ = $3; }
297			| /* empty */
298			{ $$ = NULL; }
299cond_expr               : '(' cond_expr ')'
300			{ $$ = $2;}
301			| NOT cond_expr
302			{ $$ = define_cond_expr(COND_NOT, $2, 0);
303			  if ($$ == 0) return -1; }
304			| cond_expr AND cond_expr
305			{ $$ = define_cond_expr(COND_AND, $1, $3);
306			  if ($$ == 0) return  -1; }
307			| cond_expr OR cond_expr
308			{ $$ = define_cond_expr(COND_OR, $1, $3);
309			  if ($$ == 0) return   -1; }
310			| cond_expr XOR cond_expr
311			{ $$ = define_cond_expr(COND_XOR, $1, $3);
312			  if ($$ == 0) return  -1; }
313			| cond_expr EQUALS cond_expr
314			{ $$ = define_cond_expr(COND_EQ, $1, $3);
315			  if ($$ == 0) return  -1; }
316			| cond_expr NOTEQUAL cond_expr
317			{ $$ = define_cond_expr(COND_NEQ, $1, $3);
318			  if ($$ == 0) return  -1; }
319			| cond_expr_prim
320			{ $$ = $1; }
321			;
322cond_expr_prim          : identifier
323                        { $$ = define_cond_expr(COND_BOOL,0, 0);
324			  if ($$ == COND_ERR) return   -1; }
325                        ;
326cond_pol_list           : cond_pol_list cond_rule_def
327                        { $$ = define_cond_pol_list((avrule_t *)$1, (avrule_t *)$2); }
328			| /* empty */
329			{ $$ = NULL; }
330			;
331cond_rule_def           : cond_transition_def
332                        { $$ = $1; }
333                        | cond_te_avtab_def
334                        { $$ = $1; }
335			| require_block
336			{ $$ = NULL; }
337                        ;
338cond_transition_def	: TYPE_TRANSITION names names ':' names identifier ';'
339                        { $$ = define_cond_compute_type(AVRULE_TRANSITION) ;
340                          if ($$ == COND_ERR) return -1;}
341                        | TYPE_MEMBER names names ':' names identifier ';'
342                        { $$ = define_cond_compute_type(AVRULE_MEMBER) ;
343                          if ($$ ==  COND_ERR) return -1;}
344                        | TYPE_CHANGE names names ':' names identifier ';'
345                        { $$ = define_cond_compute_type(AVRULE_CHANGE) ;
346                          if ($$ == COND_ERR) return -1;}
347    			;
348cond_te_avtab_def	: cond_allow_def
349                          { $$ = $1; }
350			| cond_auditallow_def
351			  { $$ = $1; }
352			| cond_auditdeny_def
353			  { $$ = $1; }
354			| cond_dontaudit_def
355			  { $$ = $1; }
356			;
357cond_allow_def		: ALLOW names names ':' names names  ';'
358			{ $$ = define_cond_te_avtab(AVRULE_ALLOWED) ;
359                          if ($$ == COND_ERR) return -1; }
360		        ;
361cond_auditallow_def	: AUDITALLOW names names ':' names names ';'
362			{ $$ = define_cond_te_avtab(AVRULE_AUDITALLOW) ;
363                          if ($$ == COND_ERR) return -1; }
364		        ;
365cond_auditdeny_def	: AUDITDENY names names ':' names names ';'
366			{ $$ = define_cond_te_avtab(AVRULE_AUDITDENY) ;
367                          if ($$ == COND_ERR) return -1; }
368		        ;
369cond_dontaudit_def	: DONTAUDIT names names ':' names names ';'
370			{ $$ = define_cond_te_avtab(AVRULE_DONTAUDIT);
371                          if ($$ == COND_ERR) return -1; }
372		        ;
373transition_def		: TYPE_TRANSITION names names ':' names identifier ';'
374                        {if (define_compute_type(AVRULE_TRANSITION)) return -1;}
375                        | TYPE_MEMBER names names ':' names identifier ';'
376                        {if (define_compute_type(AVRULE_MEMBER)) return -1;}
377                        | TYPE_CHANGE names names ':' names identifier ';'
378                        {if (define_compute_type(AVRULE_CHANGE)) return -1;}
379    			;
380range_trans_def		: RANGE_TRANSITION names names mls_range_def ';'
381			{ if (define_range_trans(0)) return -1; }
382			| RANGE_TRANSITION names names ':' names mls_range_def ';'
383			{ if (define_range_trans(1)) return -1; }
384			;
385te_avtab_def		: allow_def
386			| auditallow_def
387			| auditdeny_def
388			| dontaudit_def
389			| neverallow_def
390			;
391allow_def		: ALLOW names names ':' names names  ';'
392			{if (define_te_avtab(AVRULE_ALLOWED)) return -1; }
393		        ;
394auditallow_def		: AUDITALLOW names names ':' names names ';'
395			{if (define_te_avtab(AVRULE_AUDITALLOW)) return -1; }
396		        ;
397auditdeny_def		: AUDITDENY names names ':' names names ';'
398			{if (define_te_avtab(AVRULE_AUDITDENY)) return -1; }
399		        ;
400dontaudit_def		: DONTAUDIT names names ':' names names ';'
401			{if (define_te_avtab(AVRULE_DONTAUDIT)) return -1; }
402		        ;
403neverallow_def		: NEVERALLOW names names ':' names names  ';'
404			{if (define_te_avtab(AVRULE_NEVERALLOW)) return -1; }
405		        ;
406role_type_def		: ROLE identifier TYPES names ';'
407			{if (define_role_types()) return -1;}
408 			| ROLE identifier';'
409 			{if (define_role_types()) return -1;}
410                        ;
411role_dominance		: DOMINANCE '{' roles '}'
412			;
413role_trans_def		: ROLE_TRANSITION names names identifier ';'
414			{if (define_role_trans()) return -1; }
415			;
416role_allow_def		: ALLOW names names ';'
417			{if (define_role_allow()) return -1; }
418			;
419roles			: role_def
420			{ $$ = $1; }
421			| roles role_def
422			{ $$ = merge_roles_dom((role_datum_t*)$1, (role_datum_t*)$2); if ($$ == 0) return -1;}
423			;
424role_def		: ROLE identifier_push ';'
425                        {$$ = define_role_dom(NULL); if ($$ == 0) return -1;}
426			| ROLE identifier_push '{' roles '}'
427                        {$$ = define_role_dom((role_datum_t*)$4); if ($$ == 0) return -1;}
428			;
429opt_constraints         : constraints
430                        |
431                        ;
432constraints		: constraint_decl
433			| constraints constraint_decl
434			;
435constraint_decl		: constraint_def
436			| validatetrans_def
437			;
438constraint_def		: CONSTRAIN names names cexpr ';'
439			{ if (define_constraint((constraint_expr_t*)$4)) return -1; }
440			;
441validatetrans_def	: VALIDATETRANS names cexpr ';'
442			{ if (define_validatetrans((constraint_expr_t*)$3)) return -1; }
443			;
444cexpr			: '(' cexpr ')'
445			{ $$ = $2; }
446			| NOT cexpr
447			{ $$ = define_cexpr(CEXPR_NOT, $2, 0);
448			  if ($$ == 0) return -1; }
449			| cexpr AND cexpr
450			{ $$ = define_cexpr(CEXPR_AND, $1, $3);
451			  if ($$ == 0) return -1; }
452			| cexpr OR cexpr
453			{ $$ = define_cexpr(CEXPR_OR, $1, $3);
454			  if ($$ == 0) return -1; }
455			| cexpr_prim
456			{ $$ = $1; }
457			;
458cexpr_prim		: U1 op U2
459			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, $2);
460			  if ($$ == 0) return -1; }
461			| R1 role_mls_op R2
462			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
463			  if ($$ == 0) return -1; }
464			| T1 op T2
465			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_TYPE, $2);
466			  if ($$ == 0) return -1; }
467			| U1 op { if (insert_separator(1)) return -1; } names_push
468			{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_USER, $2);
469			  if ($$ == 0) return -1; }
470			| U2 op { if (insert_separator(1)) return -1; } names_push
471			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_USER | CEXPR_TARGET), $2);
472			  if ($$ == 0) return -1; }
473			| U3 op { if (insert_separator(1)) return -1; } names_push
474			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_USER | CEXPR_XTARGET), $2);
475			  if ($$ == 0) return -1; }
476			| R1 op { if (insert_separator(1)) return -1; } names_push
477			{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, $2);
478			  if ($$ == 0) return -1; }
479			| R2 op { if (insert_separator(1)) return -1; } names_push
480			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), $2);
481			  if ($$ == 0) return -1; }
482			| R3 op { if (insert_separator(1)) return -1; } names_push
483			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_XTARGET), $2);
484			  if ($$ == 0) return -1; }
485			| T1 op { if (insert_separator(1)) return -1; } names_push
486			{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, $2);
487			  if ($$ == 0) return -1; }
488			| T2 op { if (insert_separator(1)) return -1; } names_push
489			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), $2);
490			  if ($$ == 0) return -1; }
491			| T3 op { if (insert_separator(1)) return -1; } names_push
492			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_XTARGET), $2);
493			  if ($$ == 0) return -1; }
494			| SAMEUSER
495			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, CEXPR_EQ);
496			  if ($$ == 0) return -1; }
497			| SOURCE ROLE { if (insert_separator(1)) return -1; } names_push
498			{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, CEXPR_EQ);
499			  if ($$ == 0) return -1; }
500			| TARGET ROLE { if (insert_separator(1)) return -1; } names_push
501			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), CEXPR_EQ);
502			  if ($$ == 0) return -1; }
503			| ROLE role_mls_op
504			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
505			  if ($$ == 0) return -1; }
506			| SOURCE TYPE { if (insert_separator(1)) return -1; } names_push
507			{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, CEXPR_EQ);
508			  if ($$ == 0) return -1; }
509			| TARGET TYPE { if (insert_separator(1)) return -1; } names_push
510			{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), CEXPR_EQ);
511			  if ($$ == 0) return -1; }
512			| L1 role_mls_op L2
513			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_L1L2, $2);
514			  if ($$ == 0) return -1; }
515			| L1 role_mls_op H2
516			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_L1H2, $2);
517			  if ($$ == 0) return -1; }
518			| H1 role_mls_op L2
519			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_H1L2, $2);
520			  if ($$ == 0) return -1; }
521			| H1 role_mls_op H2
522			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_H1H2, $2);
523			  if ($$ == 0) return -1; }
524			| L1 role_mls_op H1
525			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_L1H1, $2);
526			  if ($$ == 0) return -1; }
527			| L2 role_mls_op H2
528			{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_L2H2, $2);
529			  if ($$ == 0) return -1; }
530			;
531op			: EQUALS
532			{ $$ = CEXPR_EQ; }
533			| NOTEQUAL
534			{ $$ = CEXPR_NEQ; }
535			;
536role_mls_op		: op
537			{ $$ = $1; }
538			| DOM
539			{ $$ = CEXPR_DOM; }
540			| DOMBY
541			{ $$ = CEXPR_DOMBY; }
542			| INCOMP
543			{ $$ = CEXPR_INCOMP; }
544			;
545users			: user_def
546			| users user_def
547			;
548user_def		: USER identifier ROLES names opt_mls_user ';'
549	                {if (define_user()) return -1;}
550			;
551opt_mls_user		: LEVEL mls_level_def RANGE mls_range_def
552			|
553			;
554initial_sid_contexts	: initial_sid_context_def
555			| initial_sid_contexts initial_sid_context_def
556			;
557initial_sid_context_def	: SID identifier security_context_def
558			{if (define_initial_sid_context()) return -1;}
559			;
560opt_fs_contexts         : fs_contexts
561                        |
562                        ;
563fs_contexts		: fs_context_def
564			| fs_contexts fs_context_def
565			;
566fs_context_def		: FSCON number number security_context_def security_context_def
567			{if (define_fs_context($2,$3)) return -1;}
568			;
569net_contexts		: opt_port_contexts opt_netif_contexts opt_node_contexts
570			;
571opt_port_contexts       : port_contexts
572                        |
573                        ;
574port_contexts		: port_context_def
575			| port_contexts port_context_def
576			;
577port_context_def	: PORTCON identifier number security_context_def
578			{if (define_port_context($3,$3)) return -1;}
579			| PORTCON identifier number '-' number security_context_def
580			{if (define_port_context($3,$5)) return -1;}
581			;
582opt_netif_contexts      : netif_contexts
583                        |
584                        ;
585netif_contexts		: netif_context_def
586			| netif_contexts netif_context_def
587			;
588netif_context_def	: NETIFCON identifier security_context_def security_context_def
589			{if (define_netif_context()) return -1;}
590			;
591opt_node_contexts       : node_contexts
592                        |
593                        ;
594node_contexts		: node_context_def
595			| node_contexts node_context_def
596			;
597node_context_def	: NODECON ipv4_addr_def ipv4_addr_def security_context_def
598			{if (define_ipv4_node_context()) return -1;}
599			| NODECON ipv6_addr ipv6_addr security_context_def
600			{if (define_ipv6_node_context()) return -1;}
601			;
602opt_fs_uses             : fs_uses
603                        |
604                        ;
605fs_uses                 : fs_use_def
606                        | fs_uses fs_use_def
607                        ;
608fs_use_def              : FSUSEXATTR identifier security_context_def ';'
609                        {if (define_fs_use(SECURITY_FS_USE_XATTR)) return -1;}
610                        | FSUSETASK identifier security_context_def ';'
611                        {if (define_fs_use(SECURITY_FS_USE_TASK)) return -1;}
612                        | FSUSETRANS identifier security_context_def ';'
613                        {if (define_fs_use(SECURITY_FS_USE_TRANS)) return -1;}
614                        ;
615opt_genfs_contexts      : genfs_contexts
616                        |
617                        ;
618genfs_contexts          : genfs_context_def
619                        | genfs_contexts genfs_context_def
620                        ;
621genfs_context_def	: GENFSCON identifier path '-' identifier security_context_def
622			{if (define_genfs_context(1)) return -1;}
623			| GENFSCON identifier path '-' '-' {insert_id("-", 0);} security_context_def
624			{if (define_genfs_context(1)) return -1;}
625                        | GENFSCON identifier path security_context_def
626			{if (define_genfs_context(0)) return -1;}
627			;
628ipv4_addr_def		: IPV4_ADDR
629			{ if (insert_id(yytext,0)) return -1; }
630			;
631security_context_def	: identifier ':' identifier ':' identifier opt_mls_range_def
632	                ;
633opt_mls_range_def	: ':' mls_range_def
634			|
635			;
636mls_range_def		: mls_level_def '-' mls_level_def
637			{if (insert_separator(0)) return -1;}
638	                | mls_level_def
639			{if (insert_separator(0)) return -1;}
640	                ;
641mls_level_def		: identifier ':' id_comma_list
642			{if (insert_separator(0)) return -1;}
643	                | identifier
644			{if (insert_separator(0)) return -1;}
645	                ;
646id_comma_list           : identifier
647			| id_comma_list ',' identifier
648			;
649tilde			: '~'
650			;
651asterisk		: '*'
652			;
653names           	: identifier
654			{ if (insert_separator(0)) return -1; }
655			| nested_id_set
656			{ if (insert_separator(0)) return -1; }
657			| asterisk
658                        { if (insert_id("*", 0)) return -1;
659			  if (insert_separator(0)) return -1; }
660			| tilde identifier
661                        { if (insert_id("~", 0)) return -1;
662			  if (insert_separator(0)) return -1; }
663			| tilde nested_id_set
664	 		{ if (insert_id("~", 0)) return -1;
665			  if (insert_separator(0)) return -1; }
666                        | identifier '-' { if (insert_id("-", 0)) return -1; } identifier
667			{ if (insert_separator(0)) return -1; }
668			;
669tilde_push              : tilde
670                        { if (insert_id("~", 1)) return -1; }
671			;
672asterisk_push           : asterisk
673                        { if (insert_id("*", 1)) return -1; }
674			;
675names_push		: identifier_push
676			| '{' identifier_list_push '}'
677			| asterisk_push
678			| tilde_push identifier_push
679			| tilde_push '{' identifier_list_push '}'
680			;
681identifier_list_push	: identifier_push
682			| identifier_list_push identifier_push
683			;
684identifier_push		: IDENTIFIER
685			{ if (insert_id(yytext, 1)) return -1; }
686			;
687identifier_list		: identifier
688			| identifier_list identifier
689			;
690nested_id_set           : '{' nested_id_list '}'
691                        ;
692nested_id_list          : nested_id_element | nested_id_list nested_id_element
693                        ;
694nested_id_element       : identifier | '-' { if (insert_id("-", 0)) return -1; } identifier | nested_id_set
695                        ;
696identifier		: IDENTIFIER
697			{ if (insert_id(yytext,0)) return -1; }
698			;
699path     		: PATH
700			{ if (insert_id(yytext,0)) return -1; }
701			;
702number			: NUMBER
703			{ $$ = strtoul(yytext,NULL,0); }
704			;
705ipv6_addr		: IPV6_ADDR
706			{ if (insert_id(yytext,0)) return -1; }
707			;
708policycap_def		: POLICYCAP identifier ';'
709			{if (define_polcap()) return -1;}
710			;
711permissive_def		: PERMISSIVE identifier ';'
712			{if (define_permissive()) return -1;}
713
714/*********** module grammar below ***********/
715
716module_policy           : module_def avrules_block
717                        { if (end_avrule_block(pass) == -1) return -1;
718                          if (policydb_index_others(NULL, policydbp, 0)) return -1;
719                        }
720                        ;
721module_def              : MODULE identifier version_identifier ';'
722                        { if (define_policy(pass, 1) == -1) return -1; }
723                        ;
724version_identifier      : VERSION_IDENTIFIER
725                        { if (insert_id(yytext,0)) return -1; }
726                        | ipv4_addr_def /* version can look like ipv4 address */
727                        ;
728avrules_block           : avrule_decls avrule_user_defs
729                        ;
730avrule_decls            : avrule_decls avrule_decl
731                        | avrule_decl
732                        ;
733avrule_decl             : rbac_decl
734                        | te_decl
735                        | cond_stmt_def
736                        | require_block
737                        | optional_block
738                        | ';'
739                        ;
740require_block           : REQUIRE '{' require_list '}'
741                        ;
742require_list            : require_list require_decl
743                        | require_decl
744                        ;
745require_decl            : require_class ';'
746                        | require_decl_def require_id_list ';'
747                        ;
748require_class           : CLASS identifier names
749                        { if (require_class(pass)) return -1; }
750                        ;
751require_decl_def        : ROLE        { $$ = require_role; }
752                        | TYPE        { $$ = require_type; }
753                        | ATTRIBUTE   { $$ = require_attribute; }
754                        | USER        { $$ = require_user; }
755                        | BOOL        { $$ = require_bool; }
756                        | SENSITIVITY { $$ = require_sens; }
757                        | CATEGORY    { $$ = require_cat; }
758                        ;
759require_id_list         : identifier
760                        { if ($<require_func>0 (pass)) return -1; }
761                        | require_id_list ',' identifier
762                        { if ($<require_func>0 (pass)) return -1; }
763                        ;
764optional_block          : optional_decl '{' avrules_block '}'
765                        { if (end_avrule_block(pass) == -1) return -1; }
766                          optional_else
767                        { if (end_optional(pass) == -1) return -1; }
768                        ;
769optional_else           : else_decl '{' avrules_block '}'
770                        { if (end_avrule_block(pass) == -1) return -1; }
771                        | /* empty */
772                        ;
773optional_decl           : OPTIONAL
774                        { if (begin_optional(pass) == -1) return -1; }
775                        ;
776else_decl               : ELSE
777                        { if (begin_optional_else(pass) == -1) return -1; }
778                        ;
779avrule_user_defs        : user_def avrule_user_defs
780                        | /* empty */
781                        ;
782