~ubuntu-branches/ubuntu/gutsy/checkpolicy/gutsy

« back to all changes in this revision

Viewing changes to policy_parse.y

  • Committer: Bazaar Package Importer
  • Author(s): Russell Coker
  • Date: 2004-05-20 04:32:00 UTC
  • Revision ID: james.westby@ubuntu.com-20040520043200-w4lzkx37dmmc3wt9
Tags: upstream-1.10
ImportĀ upstreamĀ versionĀ 1.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 
 
4
 */
 
5
 
 
6
/* Updated: David Caplan, <dac@tresys.com>
 
7
 *
 
8
 *      Added conditional policy language extensions
 
9
 *
 
10
 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
 
11
 *      This program is free software; you can redistribute it and/or modify
 
12
 *      it under the terms of the GNU General Public License as published by
 
13
 *      the Free Software Foundation, version 2.
 
14
 */
 
15
 
 
16
/* FLASK */
 
17
 
 
18
%{
 
19
#include "policydb.h"
 
20
#include "services.h"
 
21
#include "queue.h"
 
22
#include "checkpolicy.h"
 
23
#include "conditional.h"
 
24
#include <stdint.h>
 
25
 
 
26
#define TRUE 1
 
27
#define FALSE 0
 
28
 
 
29
policydb_t *policydbp;
 
30
queue_t id_queue = 0;
 
31
unsigned int pass;
 
32
char *curfile = 0;
 
33
unsigned int curline; 
 
34
 
 
35
extern unsigned long policydb_lineno;
 
36
 
 
37
extern char yytext[];
 
38
extern int yywarn(char *msg);
 
39
extern int yyerror(char *msg);
 
40
 
 
41
static char errormsg[255];
 
42
 
 
43
static int insert_separator(int push);
 
44
static int insert_id(char *id,int push);
 
45
static int define_class(void);
 
46
static int define_initial_sid(void);
 
47
static int define_common_perms(void);
 
48
static int define_av_perms(int inherits);
 
49
static int define_sens(void);
 
50
static int define_dominance(void);
 
51
static int define_category(void);
 
52
static int define_level(void);
 
53
static int define_common_base(void);
 
54
static int define_av_base(void);
 
55
static int define_attrib(void);
 
56
static int define_typealias(void);
 
57
static int define_type(int alias);
 
58
static int define_compute_type(int which);
 
59
static int define_te_avtab(int which);
 
60
static int define_role_types(void);
 
61
static role_datum_t *merge_roles_dom(role_datum_t *r1,role_datum_t *r2);
 
62
static role_datum_t *define_role_dom(role_datum_t *r);
 
63
static int define_role_trans(void);
 
64
static int define_role_allow(void);
 
65
static int define_constraint(constraint_expr_t *expr);
 
66
static int define_bool();
 
67
static int define_conditional(cond_expr_t *expr,cond_av_list_t *t_list, cond_av_list_t *f_list );
 
68
static cond_expr_t *define_cond_expr(__u32 expr_type, void *arg1, void* arg2);
 
69
static cond_av_list_t *define_cond_pol_list(cond_av_list_t *avlist, cond_av_list_t *stmt);
 
70
static cond_av_list_t *define_cond_compute_type(int which);
 
71
static cond_av_list_t *define_cond_te_avtab(int which);
 
72
static cond_av_list_t *cond_list_append(cond_av_list_t *sl, avtab_key_t *key, avtab_datum_t *datum);
 
73
static void cond_reduce_insert_list(cond_av_list_t *new, cond_av_list_t **active, cond_av_list_t **inactive, int state ); 
 
74
static uintptr_t define_cexpr(__u32 expr_type, uintptr_t arg1, uintptr_t arg2);
 
75
static int define_user(void);
 
76
static int parse_security_context(context_struct_t *c);
 
77
static int define_initial_sid_context(void);
 
78
static int define_fs_use(int behavior);
 
79
static int define_genfs_context(int has_type);
 
80
static int define_fs_context(unsigned int major, unsigned int minor);
 
81
static int define_port_context(unsigned int low, unsigned int high);
 
82
static int define_netif_context(void);
 
83
static int define_ipv4_node_context(unsigned int addr, unsigned int mask);
 
84
static int define_ipv6_node_context(void);
 
85
%}
 
86
 
 
87
%union {
 
88
        unsigned int val;
 
89
        uintptr_t valptr;
 
90
        void *ptr;
 
91
}
 
92
 
 
93
%type <ptr> cond_expr cond_expr_prim cond_pol_list
 
94
%type <ptr> cond_allow_def cond_auditallow_def cond_auditdeny_def cond_dontaudit_def
 
95
%type <ptr> cond_transition_def cond_te_avtab_def cond_rule_def
 
96
%type <ptr> role_def roles
 
97
%type <valptr> cexpr cexpr_prim op roleop
 
98
%type <val> ipv4_addr_def number
 
99
 
 
100
%token PATH
 
101
%token CLONE
 
102
%token COMMON
 
103
%token CLASS
 
104
%token CONSTRAIN
 
105
%token INHERITS
 
106
%token SID
 
107
%token ROLE
 
108
%token ROLES
 
109
%token TYPEALIAS
 
110
%token TYPE
 
111
%token TYPES
 
112
%token ALIAS
 
113
%token ATTRIBUTE
 
114
%token BOOL
 
115
%token IF
 
116
%token ELSE
 
117
%token TYPE_TRANSITION
 
118
%token TYPE_MEMBER
 
119
%token TYPE_CHANGE
 
120
%token ROLE_TRANSITION
 
121
%token SENSITIVITY
 
122
%token DOMINANCE
 
123
%token DOM DOMBY INCOMP
 
124
%token CATEGORY
 
125
%token LEVEL
 
126
%token RANGES
 
127
%token USER
 
128
%token NEVERALLOW
 
129
%token ALLOW
 
130
%token AUDITALLOW
 
131
%token AUDITDENY
 
132
%token DONTAUDIT
 
133
%token SOURCE
 
134
%token TARGET
 
135
%token SAMEUSER
 
136
%token FSCON PORTCON NETIFCON NODECON 
 
137
%token FSUSEXATTR FSUSETASK FSUSETRANS
 
138
%token GENFSCON
 
139
%token U1 U2 R1 R2 T1 T2
 
140
%token NOT AND OR XOR
 
141
%token CTRUE CFALSE
 
142
%token IDENTIFIER
 
143
%token USER_IDENTIFIER
 
144
%token NUMBER
 
145
%token EQUALS
 
146
%token NOTEQUAL
 
147
%token IPV6_ADDR
 
148
 
 
149
%left OR
 
150
%left XOR
 
151
%left AND
 
152
%right NOT
 
153
%left EQUALS NOTEQUAL
 
154
%%
 
155
policy                  : classes initial_sids access_vectors
 
156
                          { if (pass == 1) { if (policydb_index_classes(policydbp)) return -1; } }
 
157
                          opt_mls te_rbac users opt_constraints 
 
158
                         { if (pass == 1) { if (policydb_index_bools(policydbp)) return -1;}
 
159
                           if (pass == 2) { if (policydb_index_others(policydbp)) return -1;} } 
 
160
                          initial_sid_contexts opt_fs_contexts fs_uses opt_genfs_contexts net_contexts 
 
161
                        ;
 
162
classes                 : class_def 
 
163
                        | classes class_def
 
164
                        ;
 
165
class_def               : CLASS identifier
 
166
                        {if (define_class()) return -1;}
 
167
                        ;
 
168
initial_sids            : initial_sid_def 
 
169
                        | initial_sids initial_sid_def
 
170
                        ;
 
171
initial_sid_def         : SID identifier
 
172
                        {if (define_initial_sid()) return -1;}
 
173
                        ;
 
174
access_vectors          : opt_common_perms av_perms
 
175
                        ;
 
176
opt_common_perms        : common_perms
 
177
                        |
 
178
                        ;
 
179
common_perms            : common_perms_def
 
180
                        | common_perms common_perms_def
 
181
                        ;
 
182
common_perms_def        : COMMON identifier '{' identifier_list '}'
 
183
                        {if (define_common_perms()) return -1;}
 
184
                        ;
 
185
av_perms                : av_perms_def
 
186
                        | av_perms av_perms_def
 
187
                        ;
 
188
av_perms_def            : CLASS identifier '{' identifier_list '}'
 
189
                        {if (define_av_perms(FALSE)) return -1;}
 
190
                        | CLASS identifier INHERITS identifier 
 
191
                        {if (define_av_perms(TRUE)) return -1;}
 
192
                        | CLASS identifier INHERITS identifier '{' identifier_list '}'
 
193
                        {if (define_av_perms(TRUE)) return -1;}
 
194
                        ;
 
195
opt_mls                 : mls
 
196
                        | 
 
197
                        ;
 
198
mls                     : sensitivities dominance opt_categories levels base_perms
 
199
                        ;
 
200
sensitivities           : sensitivity_def 
 
201
                        | sensitivities sensitivity_def
 
202
                        ;
 
203
sensitivity_def         : SENSITIVITY identifier alias_def ';'
 
204
                        {if (define_sens()) return -1;}
 
205
                        | SENSITIVITY identifier ';'
 
206
                        {if (define_sens()) return -1;}
 
207
                        ;
 
208
alias_def               : ALIAS names
 
209
                        ;
 
210
dominance               : DOMINANCE identifier 
 
211
                        {if (define_dominance()) return -1;}
 
212
                        | DOMINANCE '{' identifier_list '}' 
 
213
                        {if (define_dominance()) return -1;}
 
214
                        ;
 
215
opt_categories          : categories
 
216
                        |
 
217
                        ;
 
218
categories              : category_def 
 
219
                        | categories category_def
 
220
                        ;
 
221
category_def            : CATEGORY identifier alias_def ';'
 
222
                        {if (define_category()) return -1;}
 
223
                        | CATEGORY identifier ';'
 
224
                        {if (define_category()) return -1;}
 
225
                        ;
 
226
levels                  : level_def 
 
227
                        | levels level_def
 
228
                        ;
 
229
level_def               : LEVEL identifier ':' id_comma_list ';'
 
230
                        {if (define_level()) return -1;}
 
231
                        | LEVEL identifier ';' 
 
232
                        {if (define_level()) return -1;}
 
233
                                                ;
 
234
base_perms              : opt_common_base av_base
 
235
                        ;
 
236
opt_common_base         : common_base
 
237
                        |
 
238
                        ;
 
239
common_base             : common_base_def
 
240
                        | common_base common_base_def
 
241
                        ;
 
242
common_base_def         : COMMON identifier '{' perm_base_list '}'
 
243
                        {if (define_common_base()) return -1;}
 
244
                        ;
 
245
av_base                 : av_base_def
 
246
                        | av_base av_base_def
 
247
                        ;
 
248
av_base_def             : CLASS identifier '{' perm_base_list '}'
 
249
                        {if (define_av_base()) return -1;}
 
250
                        | CLASS identifier
 
251
                        {if (define_av_base()) return -1;}
 
252
                        ;
 
253
perm_base_list          : perm_base
 
254
                        | perm_base_list perm_base
 
255
                        ;
 
256
perm_base               : identifier ':' identifier
 
257
                        {if (insert_separator(0)) return -1;}
 
258
                        | identifier ':' '{' identifier_list '}'
 
259
                        {if (insert_separator(0)) return -1;}
 
260
                        ;
 
261
te_rbac                 : te_rbac_decl
 
262
                        | te_rbac te_rbac_decl
 
263
                        ;
 
264
te_rbac_decl            : te_decl
 
265
                        | rbac_decl
 
266
                        | ';'
 
267
                        ;
 
268
rbac_decl               : role_type_def
 
269
                        | role_dominance
 
270
                        | role_trans_def
 
271
                        | role_allow_def
 
272
                        ;
 
273
te_decl                 : attribute_def
 
274
                        | type_def
 
275
                        | typealias_def
 
276
                        | bool_def
 
277
                        | transition_def
 
278
                        | te_avtab_def
 
279
                        | cond_stmt_def
 
280
                        ;
 
281
attribute_def           : ATTRIBUTE identifier ';'
 
282
                        { if (define_attrib()) return -1;}
 
283
                        ;
 
284
type_def                : TYPE identifier alias_def opt_attr_list ';'
 
285
                        {if (define_type(1)) return -1;}
 
286
                        | TYPE identifier opt_attr_list ';'
 
287
                        {if (define_type(0)) return -1;}
 
288
                        ;
 
289
typealias_def           : TYPEALIAS identifier alias_def
 
290
                        {if (define_typealias()) return -1;}
 
291
                        ;
 
292
opt_attr_list           : ',' id_comma_list
 
293
                        | 
 
294
                        ;
 
295
bool_def                : BOOL identifier bool_val ';'
 
296
                        {if (define_bool()) return -1;}
 
297
                        ;
 
298
bool_val                : CTRUE
 
299
                        { if (insert_id("T",0)) return -1; }
 
300
                        | CFALSE
 
301
                        { if (insert_id("F",0)) return -1; }
 
302
                        ;
 
303
cond_stmt_def           : IF cond_expr '{' cond_pol_list '}'
 
304
                        { if (pass == 2) { if (define_conditional((cond_expr_t*)$2, (cond_av_list_t*)$4,(cond_av_list_t*) 0) < 0) return -1;  }}
 
305
                        | IF cond_expr '{' cond_pol_list '}' ELSE '{' cond_pol_list '}'
 
306
                        { if (pass == 2) { if (define_conditional((cond_expr_t*)$2,(cond_av_list_t*)$4,(cond_av_list_t*)$8) < 0 ) return -1;  }}       
 
307
                        ;
 
308
cond_expr               : '(' cond_expr ')'
 
309
                        { $$ = $2;}
 
310
                        | NOT cond_expr
 
311
                        { $$ = define_cond_expr(COND_NOT, $2, 0);
 
312
                          if ($$ == 0) return -1; }
 
313
                        | cond_expr AND cond_expr
 
314
                        { $$ = define_cond_expr(COND_AND, $1, $3);
 
315
                          if ($$ == 0) return  -1; }
 
316
                        | cond_expr OR cond_expr
 
317
                        { $$ = define_cond_expr(COND_OR, $1, $3);
 
318
                          if ($$ == 0) return   -1; }
 
319
                        | cond_expr XOR cond_expr
 
320
                        { $$ = define_cond_expr(COND_XOR, $1, $3);
 
321
                          if ($$ == 0) return  -1; }
 
322
                        | cond_expr EQUALS cond_expr
 
323
                        { $$ = define_cond_expr(COND_EQ, $1, $3);
 
324
                          if ($$ == 0) return  -1; }
 
325
                        | cond_expr NOTEQUAL cond_expr
 
326
                        { $$ = define_cond_expr(COND_NEQ, $1, $3);
 
327
                          if ($$ == 0) return  -1; }
 
328
                        | cond_expr_prim
 
329
                        { $$ = $1; }
 
330
                        ;
 
331
cond_expr_prim          : identifier
 
332
                        { $$ = define_cond_expr(COND_BOOL,0, 0);
 
333
                          if ($$ == COND_ERR) return   -1; }
 
334
                        ;
 
335
cond_pol_list           : cond_rule_def
 
336
                        { $$ = define_cond_pol_list((cond_av_list_t *) 0, (cond_av_list_t *)$1);}
 
337
                        | cond_pol_list cond_rule_def 
 
338
                        { $$ = define_cond_pol_list((cond_av_list_t *)$1, (cond_av_list_t *)$2); }
 
339
                        ;
 
340
cond_rule_def           : cond_transition_def
 
341
                        { $$ = $1; }
 
342
                        | cond_te_avtab_def
 
343
                        { $$ = $1; }
 
344
                        ;
 
345
cond_transition_def     : TYPE_TRANSITION names names ':' names identifier ';'
 
346
                        { $$ = define_cond_compute_type(AVTAB_TRANSITION) ;
 
347
                          if ($$ == COND_ERR) return -1;}
 
348
                        | TYPE_MEMBER names names ':' names identifier ';'
 
349
                        { $$ = define_cond_compute_type(AVTAB_MEMBER) ;
 
350
                          if ($$ ==  COND_ERR) return -1;}
 
351
                        | TYPE_CHANGE names names ':' names identifier ';'
 
352
                        { $$ = define_cond_compute_type(AVTAB_CHANGE) ;
 
353
                          if ($$ == COND_ERR) return -1;}
 
354
                        ;
 
355
cond_te_avtab_def       : cond_allow_def
 
356
                          { $$ = $1; }
 
357
                        | cond_auditallow_def
 
358
                          { $$ = $1; }
 
359
                        | cond_auditdeny_def
 
360
                          { $$ = $1; }
 
361
                        | cond_dontaudit_def
 
362
                          { $$ = $1; }
 
363
                        ;
 
364
cond_allow_def          : ALLOW names names ':' names names  ';'
 
365
                        { $$ = define_cond_te_avtab(AVTAB_ALLOWED) ;
 
366
                          if ($$ == COND_ERR) return -1; }
 
367
                        ;
 
368
cond_auditallow_def     : AUDITALLOW names names ':' names names ';'
 
369
                        { $$ = define_cond_te_avtab(AVTAB_AUDITALLOW) ;
 
370
                          if ($$ == COND_ERR) return -1; }
 
371
                        ;
 
372
cond_auditdeny_def      : AUDITDENY names names ':' names names ';'
 
373
                        { $$ = define_cond_te_avtab(AVTAB_AUDITDENY) ;
 
374
                          if ($$ == COND_ERR) return -1; }
 
375
                        ;
 
376
cond_dontaudit_def      : DONTAUDIT names names ':' names names ';'
 
377
                        { $$ = define_cond_te_avtab(-AVTAB_AUDITDENY);
 
378
                          if ($$ == COND_ERR) return -1; }
 
379
                        ;
 
380
transition_def          : TYPE_TRANSITION names names ':' names identifier ';'
 
381
                        {if (define_compute_type(AVTAB_TRANSITION)) return -1;}
 
382
                        | TYPE_MEMBER names names ':' names identifier ';'
 
383
                        {if (define_compute_type(AVTAB_MEMBER)) return -1;}
 
384
                        | TYPE_CHANGE names names ':' names identifier ';'
 
385
                        {if (define_compute_type(AVTAB_CHANGE)) return -1;}
 
386
                        ;
 
387
te_avtab_def            : allow_def
 
388
                        | auditallow_def
 
389
                        | auditdeny_def
 
390
                        | dontaudit_def
 
391
                        | neverallow_def
 
392
                        ;
 
393
allow_def               : ALLOW names names ':' names names  ';'
 
394
                        {if (define_te_avtab(AVTAB_ALLOWED)) return -1; }
 
395
                        ;
 
396
auditallow_def          : AUDITALLOW names names ':' names names ';'
 
397
                        {if (define_te_avtab(AVTAB_AUDITALLOW)) return -1; }
 
398
                        ;
 
399
auditdeny_def           : AUDITDENY names names ':' names names ';'
 
400
                        {if (define_te_avtab(AVTAB_AUDITDENY)) return -1; }
 
401
                        ;
 
402
dontaudit_def           : DONTAUDIT names names ':' names names ';'
 
403
                        {if (define_te_avtab(-AVTAB_AUDITDENY)) return -1; }
 
404
                        ;
 
405
neverallow_def          : NEVERALLOW names names ':' names names  ';'
 
406
                        {if (define_te_avtab(-AVTAB_ALLOWED)) return -1; }
 
407
                        ;
 
408
role_type_def           : ROLE identifier TYPES names ';'
 
409
                        {if (define_role_types()) return -1;}
 
410
                        ;
 
411
role_dominance          : DOMINANCE '{' roles '}'
 
412
                        ;
 
413
role_trans_def          : ROLE_TRANSITION names names identifier ';'
 
414
                        {if (define_role_trans()) return -1; }
 
415
                        ;
 
416
role_allow_def          : ALLOW names names ';'
 
417
                        {if (define_role_allow()) return -1; }
 
418
                        ;
 
419
roles                   : 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
                        ;
 
424
role_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
                        ;
 
429
opt_constraints         : constraints
 
430
                        |
 
431
                        ;
 
432
constraints             : constraint_def
 
433
                        | constraints constraint_def
 
434
                        ;
 
435
constraint_def          : CONSTRAIN names names cexpr ';'
 
436
                        { if (define_constraint((constraint_expr_t*)$4)) return -1; }
 
437
                        ;
 
438
cexpr                   : '(' cexpr ')'
 
439
                        { $$ = $2; }
 
440
                        | NOT cexpr
 
441
                        { $$ = define_cexpr(CEXPR_NOT, $2, 0);
 
442
                          if ($$ == 0) return -1; }
 
443
                        | cexpr AND cexpr
 
444
                        { $$ = define_cexpr(CEXPR_AND, $1, $3);
 
445
                          if ($$ == 0) return -1; }
 
446
                        | cexpr OR cexpr
 
447
                        { $$ = define_cexpr(CEXPR_OR, $1, $3);
 
448
                          if ($$ == 0) return -1; }
 
449
                        | cexpr_prim
 
450
                        { $$ = $1; }
 
451
                        ;
 
452
cexpr_prim              : U1 op U2
 
453
                        { $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, $2);
 
454
                          if ($$ == 0) return -1; }
 
455
                        | R1 roleop R2
 
456
                        { $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
 
457
                          if ($$ == 0) return -1; }
 
458
                        | T1 op T2
 
459
                        { $$ = define_cexpr(CEXPR_ATTR, CEXPR_TYPE, $2);
 
460
                          if ($$ == 0) return -1; }
 
461
                        | U1 op { if (insert_separator(1)) return -1; } user_names_push
 
462
                        { $$ = define_cexpr(CEXPR_NAMES, CEXPR_USER, $2);
 
463
                          if ($$ == 0) return -1; }
 
464
                        | U2 op { if (insert_separator(1)) return -1; } user_names_push
 
465
                        { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_USER | CEXPR_TARGET), $2);
 
466
                          if ($$ == 0) return -1; }
 
467
                        | R1 op { if (insert_separator(1)) return -1; } names_push
 
468
                        { $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, $2);
 
469
                          if ($$ == 0) return -1; }
 
470
                        | R2 op { if (insert_separator(1)) return -1; } names_push
 
471
                        { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), $2);
 
472
                          if ($$ == 0) return -1; }
 
473
                        | T1 op { if (insert_separator(1)) return -1; } names_push
 
474
                        { $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, $2);
 
475
                          if ($$ == 0) return -1; }
 
476
                        | T2 op { if (insert_separator(1)) return -1; } names_push
 
477
                        { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), $2);
 
478
                          if ($$ == 0) return -1; }
 
479
                        | SAMEUSER
 
480
                        { $$ = define_cexpr(CEXPR_ATTR, CEXPR_USER, CEXPR_EQ);
 
481
                          if ($$ == 0) return -1; }
 
482
                        | SOURCE ROLE { if (insert_separator(1)) return -1; } names_push
 
483
                        { $$ = define_cexpr(CEXPR_NAMES, CEXPR_ROLE, CEXPR_EQ);
 
484
                          if ($$ == 0) return -1; }
 
485
                        | TARGET ROLE { if (insert_separator(1)) return -1; } names_push
 
486
                        { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_TARGET), CEXPR_EQ);
 
487
                          if ($$ == 0) return -1; }
 
488
                        | ROLE roleop
 
489
                        { $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
 
490
                          if ($$ == 0) return -1; }
 
491
                        | SOURCE TYPE { if (insert_separator(1)) return -1; } names_push
 
492
                        { $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, CEXPR_EQ);
 
493
                          if ($$ == 0) return -1; }
 
494
                        | TARGET TYPE { if (insert_separator(1)) return -1; } names_push
 
495
                        { $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), CEXPR_EQ);
 
496
                          if ($$ == 0) return -1; }
 
497
                        ;
 
498
op                      : EQUALS
 
499
                        { $$ = CEXPR_EQ; }
 
500
                        | NOTEQUAL
 
501
                        { $$ = CEXPR_NEQ; }
 
502
                        ;
 
503
roleop                  : op 
 
504
                        { $$ = $1; }
 
505
                        | DOM
 
506
                        { $$ = CEXPR_DOM; }
 
507
                        | DOMBY
 
508
                        { $$ = CEXPR_DOMBY; }
 
509
                        | INCOMP
 
510
                        { $$ = CEXPR_INCOMP; }
 
511
                        ;
 
512
users                   : user_def
 
513
                        | users user_def
 
514
                        ;
 
515
user_id                 : identifier
 
516
                        | user_identifier
 
517
                        ;
 
518
user_def                : USER user_id ROLES names opt_user_ranges ';'
 
519
                        {if (define_user()) return -1;}
 
520
                        ;
 
521
opt_user_ranges         : RANGES user_ranges 
 
522
                        |
 
523
                        ;
 
524
user_ranges             : mls_range_def
 
525
                        | '{' user_range_def_list '}' 
 
526
                        ;
 
527
user_range_def_list     : mls_range_def
 
528
                        | user_range_def_list mls_range_def
 
529
                        ;
 
530
initial_sid_contexts    : initial_sid_context_def
 
531
                        | initial_sid_contexts initial_sid_context_def
 
532
                        ;
 
533
initial_sid_context_def : SID identifier security_context_def
 
534
                        {if (define_initial_sid_context()) return -1;}
 
535
                        ;
 
536
opt_fs_contexts         : fs_contexts 
 
537
                        |
 
538
                        ;
 
539
fs_contexts             : fs_context_def
 
540
                        | fs_contexts fs_context_def
 
541
                        ;
 
542
fs_context_def          : FSCON number number security_context_def security_context_def
 
543
                        {if (define_fs_context($2,$3)) return -1;}
 
544
                        ;
 
545
net_contexts            : opt_port_contexts opt_netif_contexts opt_node_contexts 
 
546
                        ;
 
547
opt_port_contexts       : port_contexts
 
548
                        |
 
549
                        ;
 
550
port_contexts           : port_context_def
 
551
                        | port_contexts port_context_def
 
552
                        ;
 
553
port_context_def        : PORTCON identifier number security_context_def
 
554
                        {if (define_port_context($3,$3)) return -1;}
 
555
                        | PORTCON identifier number '-' number security_context_def
 
556
                        {if (define_port_context($3,$5)) return -1;}
 
557
                        ;
 
558
opt_netif_contexts      : netif_contexts 
 
559
                        |
 
560
                        ;
 
561
netif_contexts          : netif_context_def
 
562
                        | netif_contexts netif_context_def
 
563
                        ;
 
564
netif_context_def       : NETIFCON identifier security_context_def security_context_def
 
565
                        {if (define_netif_context()) return -1;} 
 
566
                        ;
 
567
opt_node_contexts       : node_contexts 
 
568
                        |
 
569
                        ;
 
570
node_contexts           : node_context_def
 
571
                        | node_contexts node_context_def
 
572
                        ;
 
573
node_context_def        : NODECON ipv4_addr_def ipv4_addr_def security_context_def
 
574
                        {if (define_ipv4_node_context($2,$3)) return -1;}
 
575
                        | NODECON ipv6_addr ipv6_addr security_context_def
 
576
                        {if (define_ipv6_node_context()) return -1;}
 
577
                        ;
 
578
fs_uses                 : fs_use_def
 
579
                        | fs_uses fs_use_def
 
580
                        ;
 
581
fs_use_def              : FSUSEXATTR identifier security_context_def ';'
 
582
                        {if (define_fs_use(SECURITY_FS_USE_XATTR)) return -1;}
 
583
                        | FSUSETASK identifier security_context_def ';'
 
584
                        {if (define_fs_use(SECURITY_FS_USE_TASK)) return -1;}
 
585
                        | FSUSETRANS identifier security_context_def ';'
 
586
                        {if (define_fs_use(SECURITY_FS_USE_TRANS)) return -1;}
 
587
                        ;
 
588
opt_genfs_contexts      : genfs_contexts
 
589
                        | 
 
590
                        ;
 
591
genfs_contexts          : genfs_context_def
 
592
                        | genfs_contexts genfs_context_def
 
593
                        ;
 
594
genfs_context_def       : GENFSCON identifier path '-' identifier security_context_def
 
595
                        {if (define_genfs_context(1)) return -1;}
 
596
                        | GENFSCON identifier path '-' '-' {insert_id("-", 0);} security_context_def
 
597
                        {if (define_genfs_context(1)) return -1;}
 
598
                        | GENFSCON identifier path security_context_def
 
599
                        {if (define_genfs_context(0)) return -1;}
 
600
                        ;
 
601
ipv4_addr_def           : number '.' number '.' number '.' number
 
602
                        { 
 
603
                          unsigned int addr;
 
604
                          unsigned char *p = ((unsigned char *)&addr);
 
605
 
 
606
                          p[0] = $1 & 0xff;                             
 
607
                          p[1] = $3 & 0xff;
 
608
                          p[2] = $5 & 0xff;
 
609
                          p[3] = $7 & 0xff;
 
610
                          $$ = addr;
 
611
                        }
 
612
                        ;
 
613
security_context_def    : user_id ':' identifier ':' identifier opt_mls_range_def
 
614
                        ;
 
615
opt_mls_range_def       : ':' mls_range_def
 
616
                        |       
 
617
                        ;
 
618
mls_range_def           : mls_level_def '-' mls_level_def
 
619
                        {if (insert_separator(0)) return -1;}
 
620
                        | mls_level_def
 
621
                        {if (insert_separator(0)) return -1;}
 
622
                        ;
 
623
mls_level_def           : identifier ':' id_comma_list
 
624
                        {if (insert_separator(0)) return -1;}
 
625
                        | identifier 
 
626
                        {if (insert_separator(0)) return -1;}
 
627
                        ;
 
628
id_comma_list           : identifier
 
629
                        | id_comma_list ',' identifier
 
630
                        ;
 
631
tilde                   : '~'
 
632
                        ;
 
633
asterisk                : '*'
 
634
                        ;
 
635
names                   : identifier
 
636
                        { if (insert_separator(0)) return -1; }
 
637
                        | nested_id_set
 
638
                        { if (insert_separator(0)) return -1; }
 
639
                        | asterisk
 
640
                        { if (insert_id("*", 0)) return -1; 
 
641
                          if (insert_separator(0)) return -1; }
 
642
                        | tilde identifier
 
643
                        { if (insert_id("~", 0)) return -1;
 
644
                          if (insert_separator(0)) return -1; }
 
645
                        | tilde nested_id_set
 
646
                        { if (insert_id("~", 0)) return -1; 
 
647
                          if (insert_separator(0)) return -1; }
 
648
                        | identifier '-' { if (insert_id("-", 0)) return -1; } identifier 
 
649
                        { if (insert_separator(0)) return -1; }
 
650
                        ;
 
651
tilde_push              : tilde
 
652
                        { if (insert_id("~", 1)) return -1; }
 
653
                        ;
 
654
asterisk_push           : asterisk
 
655
                        { if (insert_id("*", 1)) return -1; }
 
656
                        ;
 
657
names_push              : identifier_push
 
658
                        | '{' identifier_list_push '}'
 
659
                        | asterisk_push
 
660
                        | tilde_push identifier_push
 
661
                        | tilde_push '{' identifier_list_push '}'
 
662
                        ;
 
663
identifier_list_push    : identifier_push
 
664
                        | identifier_list_push identifier_push
 
665
                        ;
 
666
identifier_push         : IDENTIFIER
 
667
                        { if (insert_id(yytext, 1)) return -1; }
 
668
                        ;
 
669
identifier_list         : identifier
 
670
                        | identifier_list identifier
 
671
                        ;
 
672
nested_id_set           : '{' nested_id_list '}'
 
673
                        ;
 
674
nested_id_list          : nested_id_element | nested_id_list nested_id_element
 
675
                        ;
 
676
nested_id_element       : identifier | '-' { if (insert_id("-", 0)) return -1; } identifier | nested_id_set
 
677
                        ;
 
678
identifier              : IDENTIFIER
 
679
                        { if (insert_id(yytext,0)) return -1; }
 
680
                        ;
 
681
user_identifier         : USER_IDENTIFIER
 
682
                        { if (insert_id(yytext,0)) return -1; }
 
683
                        ;
 
684
user_identifier_push    : USER_IDENTIFIER
 
685
                        { if (insert_id(yytext, 1)) return -1; }
 
686
                        ;
 
687
user_identifier_list_push : user_identifier_push
 
688
                        | identifier_list_push user_identifier_push
 
689
                        | user_identifier_list_push identifier_push
 
690
                        | user_identifier_list_push user_identifier_push
 
691
                        ;
 
692
user_names_push         : names_push
 
693
                        | user_identifier_push
 
694
                        | '{' user_identifier_list_push '}'
 
695
                        | tilde_push user_identifier_push
 
696
                        | tilde_push '{' user_identifier_list_push '}'
 
697
                        ;
 
698
path                    : PATH
 
699
                        { if (insert_id(yytext,0)) return -1; }
 
700
                        ;
 
701
number                  : NUMBER 
 
702
                        { $$ = strtoul(yytext,NULL,0); }
 
703
                        ;
 
704
ipv6_addr               : IPV6_ADDR
 
705
                        { if (insert_id(yytext,0)) return -1; }
 
706
                        ;
 
707
%%
 
708
#define DEBUG 1
 
709
 
 
710
static int insert_separator(int push)
 
711
{
 
712
        int error;
 
713
 
 
714
        if (push)
 
715
                error = queue_push(id_queue, 0);
 
716
        else
 
717
                error = queue_insert(id_queue, 0);
 
718
 
 
719
        if (error) {
 
720
                yyerror("queue overflow");
 
721
                return -1;
 
722
        }
 
723
        return 0;
 
724
}
 
725
 
 
726
static int insert_id(char *id, int push)
 
727
{
 
728
        char *newid = 0;
 
729
        int error;
 
730
 
 
731
        newid = (char *) malloc(strlen(id) + 1);
 
732
        if (!newid) {
 
733
                yyerror("out of memory");
 
734
                return -1;
 
735
        }
 
736
        strcpy(newid, id);
 
737
        if (push)
 
738
                error = queue_push(id_queue, (queue_element_t) newid);
 
739
        else
 
740
                error = queue_insert(id_queue, (queue_element_t) newid);
 
741
 
 
742
        if (error) {
 
743
                yyerror("queue overflow");
 
744
                free(newid);
 
745
                return -1;
 
746
        }
 
747
        return 0;
 
748
}
 
749
 
 
750
 
 
751
static int define_class(void)
 
752
{
 
753
        char *id = 0;
 
754
        class_datum_t *datum = 0;
 
755
        int ret;
 
756
 
 
757
 
 
758
        if (pass == 2) {
 
759
                id = queue_remove(id_queue);
 
760
                free(id);
 
761
                return 0;
 
762
        }
 
763
 
 
764
        id = (char *) queue_remove(id_queue);
 
765
        if (!id) {
 
766
                yyerror("no class name for class definition?");
 
767
                return -1;
 
768
        }
 
769
        datum = (class_datum_t *) malloc(sizeof(class_datum_t));
 
770
        if (!datum) {
 
771
                yyerror("out of memory");
 
772
                goto bad;
 
773
        }
 
774
        memset(datum, 0, sizeof(class_datum_t));
 
775
        datum->value = ++policydbp->p_classes.nprim;
 
776
 
 
777
        ret = hashtab_insert(policydbp->p_classes.table,
 
778
                             (hashtab_key_t) id, (hashtab_datum_t) datum);
 
779
 
 
780
        if (ret == HASHTAB_PRESENT) {
 
781
                --policydbp->p_classes.nprim;
 
782
                yyerror("duplicate class definition");
 
783
                goto bad;
 
784
        }
 
785
        if (ret == HASHTAB_OVERFLOW) {
 
786
                yyerror("hash table overflow");
 
787
                goto bad;
 
788
        }
 
789
        return 0;
 
790
 
 
791
      bad:
 
792
        if (id)
 
793
                free(id);
 
794
        if (datum)
 
795
                free(datum);
 
796
        return -1;
 
797
}
 
798
 
 
799
static int define_initial_sid(void)
 
800
{
 
801
        char *id = 0;
 
802
        ocontext_t *newc = 0, *c, *head;
 
803
 
 
804
 
 
805
        if (pass == 2) {
 
806
                id = queue_remove(id_queue);
 
807
                free(id);
 
808
                return 0;
 
809
        }
 
810
 
 
811
        id = (char *) queue_remove(id_queue);
 
812
        if (!id) {
 
813
                yyerror("no sid name for SID definition?");
 
814
                return -1;
 
815
        }
 
816
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
 
817
        if (!newc) {
 
818
                yyerror("out of memory");
 
819
                goto bad;
 
820
        }
 
821
        memset(newc, 0, sizeof(ocontext_t));
 
822
        newc->u.name = id;
 
823
        context_init(&newc->context[0]);
 
824
        head = policydbp->ocontexts[OCON_ISID];
 
825
 
 
826
        for (c = head; c; c = c->next) {
 
827
                if (!strcmp(newc->u.name, c->u.name)) {
 
828
                        sprintf(errormsg, "duplicate initial SID %s", id);
 
829
                        yyerror(errormsg);
 
830
                        goto bad;
 
831
                }
 
832
        }
 
833
 
 
834
        if (head) {
 
835
                newc->sid[0] = head->sid[0] + 1;
 
836
        } else {
 
837
                newc->sid[0] = 1;
 
838
        }
 
839
        newc->next = head;
 
840
        policydbp->ocontexts[OCON_ISID] = newc;
 
841
 
 
842
        return 0;
 
843
 
 
844
      bad:
 
845
        if (id)
 
846
                free(id);
 
847
        if (newc)
 
848
                free(newc);
 
849
        return -1;
 
850
}
 
851
 
 
852
static int define_common_perms(void)
 
853
{
 
854
        char *id = 0, *perm = 0;
 
855
        common_datum_t *comdatum = 0;
 
856
        perm_datum_t *perdatum = 0;
 
857
        int ret;
 
858
 
 
859
 
 
860
        if (pass == 2) {
 
861
                while ((id = queue_remove(id_queue))) 
 
862
                        free(id);
 
863
                return 0;
 
864
        }
 
865
 
 
866
        id = (char *) queue_remove(id_queue);
 
867
        if (!id) {
 
868
                yyerror("no common name for common perm definition?");
 
869
                return -1;
 
870
        }
 
871
        comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
 
872
        if (!comdatum) {
 
873
                yyerror("out of memory");
 
874
                goto bad;
 
875
        }
 
876
        memset(comdatum, 0, sizeof(common_datum_t));
 
877
        comdatum->value = ++policydbp->p_commons.nprim;
 
878
        ret = hashtab_insert(policydbp->p_commons.table,
 
879
                         (hashtab_key_t) id, (hashtab_datum_t) comdatum);
 
880
 
 
881
        if (ret == HASHTAB_PRESENT) {
 
882
                yyerror("duplicate common definition");
 
883
                goto bad;
 
884
        }
 
885
        if (ret == HASHTAB_OVERFLOW) {
 
886
                yyerror("hash table overflow");
 
887
                goto bad;
 
888
        }
 
889
        if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
 
890
                yyerror("out of memory");
 
891
                goto bad;
 
892
        }
 
893
        while ((perm = queue_remove(id_queue))) {
 
894
                perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
 
895
                if (!perdatum) {
 
896
                        yyerror("out of memory");
 
897
                        goto bad_perm;
 
898
                }
 
899
                memset(perdatum, 0, sizeof(perm_datum_t));
 
900
                perdatum->value = ++comdatum->permissions.nprim;
 
901
 
 
902
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
903
                /*
 
904
                 * By default, we set all four base permissions on this
 
905
                 * permission. This means that if base_permissions is not
 
906
                 * explicitly defined for this permission, then this
 
907
                 * permission will only be granted in the equivalent case.
 
908
                 */
 
909
                perdatum->base_perms = MLS_BASE_READ | MLS_BASE_WRITE |
 
910
                    MLS_BASE_READBY | MLS_BASE_WRITEBY;
 
911
#endif
 
912
 
 
913
                if (perdatum->value >= (sizeof(access_vector_t) * 8)) {
 
914
                        yyerror("too many permissions to fit in an access vector");
 
915
                        goto bad_perm;
 
916
                }
 
917
                ret = hashtab_insert(comdatum->permissions.table,
 
918
                                     (hashtab_key_t) perm,
 
919
                                     (hashtab_datum_t) perdatum);
 
920
 
 
921
                if (ret == HASHTAB_PRESENT) {
 
922
                        sprintf(errormsg, "duplicate permission %s in common %s",
 
923
                                perm, id);
 
924
                        yyerror(errormsg);
 
925
                        goto bad_perm;
 
926
                }
 
927
                if (ret == HASHTAB_OVERFLOW) {
 
928
                        yyerror("hash table overflow");
 
929
                        goto bad_perm;
 
930
                }
 
931
        }
 
932
 
 
933
        return 0;
 
934
 
 
935
      bad:
 
936
        if (id)
 
937
                free(id);
 
938
        if (comdatum)
 
939
                free(comdatum);
 
940
        return -1;
 
941
 
 
942
      bad_perm:
 
943
        if (perm)
 
944
                free(perm);
 
945
        if (perdatum)
 
946
                free(perdatum);
 
947
        return -1;
 
948
}
 
949
 
 
950
 
 
951
static int define_av_perms(int inherits)
 
952
{
 
953
        char *id;
 
954
        class_datum_t *cladatum;
 
955
        common_datum_t *comdatum;
 
956
        perm_datum_t *perdatum = 0, *perdatum2 = 0;
 
957
        int ret;
 
958
 
 
959
 
 
960
        if (pass == 2) {
 
961
                while ((id = queue_remove(id_queue))) 
 
962
                        free(id);
 
963
                return 0;
 
964
        }
 
965
 
 
966
        id = (char *) queue_remove(id_queue);
 
967
        if (!id) {
 
968
                yyerror("no tclass name for av perm definition?");
 
969
                return -1;
 
970
        }
 
971
        cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
 
972
                                                    (hashtab_key_t) id);
 
973
        if (!cladatum) {
 
974
                sprintf(errormsg, "class %s is not defined", id);
 
975
                yyerror(errormsg);
 
976
                goto bad;
 
977
        }
 
978
        free(id);
 
979
 
 
980
        if (cladatum->comdatum || cladatum->permissions.nprim) {
 
981
                yyerror("duplicate access vector definition");
 
982
                return -1;
 
983
        }
 
984
        if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) {
 
985
                yyerror("out of memory");
 
986
                return -1;
 
987
        }
 
988
        if (inherits) {
 
989
                id = (char *) queue_remove(id_queue);
 
990
                if (!id) {
 
991
                        yyerror("no inherits name for access vector definition?");
 
992
                        return -1;
 
993
                }
 
994
                comdatum = (common_datum_t *) hashtab_search(policydbp->p_commons.table,
 
995
                                                     (hashtab_key_t) id);
 
996
 
 
997
                if (!comdatum) {
 
998
                        sprintf(errormsg, "common %s is not defined", id);
 
999
                        yyerror(errormsg);
 
1000
                        goto bad;
 
1001
                }
 
1002
                cladatum->comkey = id;
 
1003
                cladatum->comdatum = comdatum;
 
1004
 
 
1005
                /*
 
1006
                 * Class-specific permissions start with values 
 
1007
                 * after the last common permission.
 
1008
                 */
 
1009
                cladatum->permissions.nprim += comdatum->permissions.nprim;
 
1010
        }
 
1011
        while ((id = queue_remove(id_queue))) {
 
1012
                perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
 
1013
                if (!perdatum) {
 
1014
                        yyerror("out of memory");
 
1015
                        goto bad;
 
1016
                }
 
1017
                memset(perdatum, 0, sizeof(perm_datum_t));
 
1018
                perdatum->value = ++cladatum->permissions.nprim;
 
1019
 
 
1020
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
1021
                /*
 
1022
                 * By default, we set all four base permissions on this
 
1023
                 * permission. This means that if base_permissions is not
 
1024
                 * explicitly defined for this permission, then this
 
1025
                 * permission will only be granted in the equivalent case.
 
1026
                 */
 
1027
                perdatum->base_perms = MLS_BASE_READ | MLS_BASE_WRITE |
 
1028
                    MLS_BASE_READBY | MLS_BASE_WRITEBY;
 
1029
                /* actual value set in define_av_base */
 
1030
#endif
 
1031
 
 
1032
                if (perdatum->value >= (sizeof(access_vector_t) * 8)) {
 
1033
                        yyerror("too many permissions to fit in an access vector");
 
1034
                        goto bad;
 
1035
                }
 
1036
                if (inherits) {
 
1037
                        /*
 
1038
                         * Class-specific permissions and 
 
1039
                         * common permissions exist in the same
 
1040
                         * name space.
 
1041
                         */
 
1042
                        perdatum2 = (perm_datum_t *) hashtab_search(cladatum->comdatum->permissions.table,
 
1043
                                                     (hashtab_key_t) id);
 
1044
                        if (perdatum2) {
 
1045
                                sprintf(errormsg, "permission %s conflicts with an inherited permission", id);
 
1046
                                yyerror(errormsg);
 
1047
                                goto bad;
 
1048
                        }
 
1049
                }
 
1050
                ret = hashtab_insert(cladatum->permissions.table,
 
1051
                                     (hashtab_key_t) id,
 
1052
                                     (hashtab_datum_t) perdatum);
 
1053
 
 
1054
                if (ret == HASHTAB_PRESENT) {
 
1055
                        sprintf(errormsg, "duplicate permission %s", id);
 
1056
                        yyerror(errormsg);
 
1057
                        goto bad;
 
1058
                }
 
1059
                if (ret == HASHTAB_OVERFLOW) {
 
1060
                        yyerror("hash table overflow");
 
1061
                        goto bad;
 
1062
                }
 
1063
        }
 
1064
 
 
1065
        return 0;
 
1066
 
 
1067
      bad:
 
1068
        if (id)
 
1069
                free(id);
 
1070
        if (perdatum)
 
1071
                free(perdatum);
 
1072
        return -1;
 
1073
}
 
1074
 
 
1075
 
 
1076
static int define_sens(void)
 
1077
{
 
1078
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
1079
        char *id;
 
1080
        mls_level_t *level = 0;
 
1081
        level_datum_t *datum = 0, *aliasdatum = 0;
 
1082
        int ret;
 
1083
 
 
1084
 
 
1085
        if (pass == 2) {
 
1086
                while ((id = queue_remove(id_queue))) 
 
1087
                        free(id);
 
1088
                return 0;
 
1089
        }
 
1090
 
 
1091
        id = (char *) queue_remove(id_queue);
 
1092
        if (!id) {
 
1093
                yyerror("no sensitivity name for sensitivity definition?");
 
1094
                return -1;
 
1095
        }
 
1096
        level = (mls_level_t *) malloc(sizeof(mls_level_t));
 
1097
        if (!level) {
 
1098
                yyerror("out of memory");
 
1099
                goto bad;
 
1100
        }
 
1101
        memset(level, 0, sizeof(mls_level_t));
 
1102
        level->sens = 0;        /* actual value set in define_dominance */
 
1103
        ++policydbp->p_levels.nprim;
 
1104
        ebitmap_init(&level->cat);      /* actual value set in define_level */
 
1105
 
 
1106
        datum = (level_datum_t *) malloc(sizeof(level_datum_t));
 
1107
        if (!datum) {
 
1108
                yyerror("out of memory");
 
1109
                goto bad;
 
1110
        }
 
1111
        memset(datum, 0, sizeof(level_datum_t));
 
1112
        datum->isalias = FALSE;
 
1113
        datum->level = level;
 
1114
 
 
1115
        ret = hashtab_insert(policydbp->p_levels.table,
 
1116
                             (hashtab_key_t) id, (hashtab_datum_t) datum);
 
1117
 
 
1118
        if (ret == HASHTAB_PRESENT) {
 
1119
                --policydbp->p_levels.nprim;
 
1120
                sprintf(errormsg, "duplicate definition for sensitivity %s", id);
 
1121
                yyerror(errormsg);
 
1122
                goto bad;
 
1123
        }
 
1124
        if (ret == HASHTAB_OVERFLOW) {
 
1125
                yyerror("hash table overflow");
 
1126
                goto bad;
 
1127
        }
 
1128
 
 
1129
        while ((id = queue_remove(id_queue))) {
 
1130
                aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t));
 
1131
                if (!aliasdatum) {
 
1132
                        yyerror("out of memory");
 
1133
                        goto bad_alias;
 
1134
                }
 
1135
                memset(aliasdatum, 0, sizeof(level_datum_t));
 
1136
                aliasdatum->isalias = TRUE;
 
1137
                aliasdatum->level = level;
 
1138
 
 
1139
                ret = hashtab_insert(policydbp->p_levels.table,
 
1140
                       (hashtab_key_t) id, (hashtab_datum_t) aliasdatum);
 
1141
 
 
1142
                if (ret == HASHTAB_PRESENT) {
 
1143
                        sprintf(errormsg, "duplicate definition for level %s", id);
 
1144
                        yyerror(errormsg);
 
1145
                        goto bad_alias;
 
1146
                }
 
1147
                if (ret == HASHTAB_OVERFLOW) {
 
1148
                        yyerror("hash table overflow");
 
1149
                        goto bad_alias;
 
1150
                }
 
1151
        }
 
1152
 
 
1153
        return 0;
 
1154
 
 
1155
      bad:
 
1156
        if (id)
 
1157
                free(id);
 
1158
        if (level)
 
1159
                free(level);
 
1160
        if (datum)
 
1161
                free(datum);
 
1162
        return -1;
 
1163
 
 
1164
      bad_alias:
 
1165
        if (id)
 
1166
                free(id);
 
1167
        if (aliasdatum)
 
1168
                free(aliasdatum);
 
1169
        return -1;
 
1170
#else
 
1171
        yyerror("sensitivity definition in non-MLS configuration");
 
1172
        return -1;
 
1173
#endif
 
1174
}
 
1175
 
 
1176
static int define_dominance(void)
 
1177
{
 
1178
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
1179
        level_datum_t *datum;
 
1180
        int order;
 
1181
        char *id;
 
1182
 
 
1183
        if (pass == 2) {
 
1184
                while ((id = queue_remove(id_queue))) 
 
1185
                        free(id);
 
1186
                return 0;
 
1187
        }
 
1188
 
 
1189
        order = 0;
 
1190
        while ((id = (char *) queue_remove(id_queue))) {
 
1191
                datum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
 
1192
                                                     (hashtab_key_t) id);
 
1193
                if (!datum) {
 
1194
                        sprintf(errormsg, "unknown sensitivity %s used in dominance definition", id);
 
1195
                        yyerror(errormsg);
 
1196
                        free(id);
 
1197
                        continue;
 
1198
                }
 
1199
                if (datum->level->sens != 0) {
 
1200
                        sprintf(errormsg, "sensitivity %s occurs multiply in dominance definition", id);
 
1201
                        yyerror(errormsg);
 
1202
                        free(id);
 
1203
                        return -1;
 
1204
                }
 
1205
                datum->level->sens = ++order;
 
1206
 
 
1207
                /* no need to keep sensitivity name */
 
1208
                free(id);
 
1209
        }
 
1210
 
 
1211
        if (order != policydbp->p_levels.nprim) {
 
1212
                yyerror("all sensitivities must be specified in dominance definition");
 
1213
                return -1;
 
1214
        }
 
1215
        return 0;
 
1216
#else
 
1217
        yyerror("dominance definition in non-MLS configuration");
 
1218
        return -1;
 
1219
#endif
 
1220
}
 
1221
 
 
1222
static int define_category(void)
 
1223
{
 
1224
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
1225
        char *id;
 
1226
        cat_datum_t *datum = 0, *aliasdatum = 0;
 
1227
        int ret;
 
1228
 
 
1229
        if (pass == 2) {
 
1230
                while ((id = queue_remove(id_queue))) 
 
1231
                        free(id);
 
1232
                return 0;
 
1233
        }
 
1234
 
 
1235
        id = (char *) queue_remove(id_queue);
 
1236
        if (!id) {
 
1237
                yyerror("no category name for category definition?");
 
1238
                return -1;
 
1239
        }
 
1240
        datum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
 
1241
        if (!datum) {
 
1242
                yyerror("out of memory");
 
1243
                goto bad;
 
1244
        }
 
1245
        memset(datum, 0, sizeof(cat_datum_t));
 
1246
        datum->isalias = FALSE;
 
1247
        datum->value = ++policydbp->p_cats.nprim;
 
1248
 
 
1249
        ret = hashtab_insert(policydbp->p_cats.table,
 
1250
                             (hashtab_key_t) id, (hashtab_datum_t) datum);
 
1251
 
 
1252
        if (ret == HASHTAB_PRESENT) {
 
1253
                --policydbp->p_cats.nprim;
 
1254
                sprintf(errormsg, "duplicate definition for category %s", id);
 
1255
                yyerror(errormsg);
 
1256
                goto bad;
 
1257
        }
 
1258
        if (ret == HASHTAB_OVERFLOW) {
 
1259
                yyerror("hash table overflow");
 
1260
                goto bad;
 
1261
        }
 
1262
 
 
1263
        while ((id = queue_remove(id_queue))) {
 
1264
                aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
 
1265
                if (!aliasdatum) {
 
1266
                        yyerror("out of memory");
 
1267
                        goto bad_alias;
 
1268
                }
 
1269
                memset(aliasdatum, 0, sizeof(cat_datum_t));
 
1270
                aliasdatum->isalias = TRUE;
 
1271
                aliasdatum->value = datum->value;
 
1272
 
 
1273
                ret = hashtab_insert(policydbp->p_cats.table,
 
1274
                       (hashtab_key_t) id, (hashtab_datum_t) aliasdatum);
 
1275
 
 
1276
                if (ret == HASHTAB_PRESENT) {
 
1277
                        sprintf(errormsg, "duplicate definition for category %s", id);
 
1278
                        yyerror(errormsg);
 
1279
                        goto bad_alias;
 
1280
                }
 
1281
                if (ret == HASHTAB_OVERFLOW) {
 
1282
                        yyerror("hash table overflow");
 
1283
                        goto bad_alias;
 
1284
                }
 
1285
        }
 
1286
 
 
1287
        return 0;
 
1288
 
 
1289
      bad:
 
1290
        if (id)
 
1291
                free(id);
 
1292
        if (datum)
 
1293
                free(datum);
 
1294
        return -1;
 
1295
 
 
1296
      bad_alias:
 
1297
        if (id)
 
1298
                free(id);
 
1299
        if (aliasdatum)
 
1300
                free(aliasdatum);
 
1301
        return -1;
 
1302
#else
 
1303
        yyerror("category definition in non-MLS configuration");
 
1304
        return -1;
 
1305
#endif
 
1306
}
 
1307
 
 
1308
 
 
1309
static int define_level(void)
 
1310
{
 
1311
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
1312
        int n;
 
1313
        char *id, *levid;
 
1314
        level_datum_t *levdatum;
 
1315
        cat_datum_t *catdatum;
 
1316
 
 
1317
 
 
1318
        if (pass == 2) {
 
1319
                while ((id = queue_remove(id_queue))) 
 
1320
                        free(id);
 
1321
                return 0;
 
1322
        }
 
1323
 
 
1324
        id = (char *) queue_remove(id_queue);
 
1325
        if (!id) {
 
1326
                yyerror("no level name for level definition?");
 
1327
                return -1;
 
1328
        }
 
1329
        levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
 
1330
                                                    (hashtab_key_t) id);
 
1331
        if (!levdatum) {
 
1332
                sprintf(errormsg, "unknown sensitivity %s used in level definition", id);
 
1333
                yyerror(errormsg);
 
1334
                free(id);
 
1335
                return -1;
 
1336
        }
 
1337
        if (ebitmap_length(&levdatum->level->cat)) {
 
1338
                sprintf(errormsg, "sensitivity %s used in multiple level definitions", id);
 
1339
                yyerror(errormsg);
 
1340
                free(id);
 
1341
                return -1;
 
1342
        }
 
1343
        levid = id;
 
1344
        n = 1;
 
1345
        while ((id = queue_remove(id_queue))) {
 
1346
                catdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
 
1347
                                                     (hashtab_key_t) id);
 
1348
                if (!catdatum) {
 
1349
                        sprintf(errormsg, "unknown category %s used in level definition", id);
 
1350
                        yyerror(errormsg);
 
1351
                        free(id);
 
1352
                        continue;
 
1353
                }
 
1354
                if (ebitmap_set_bit(&levdatum->level->cat, catdatum->value - 1, TRUE)) {
 
1355
                        yyerror("out of memory");
 
1356
                        free(id);
 
1357
                        free(levid);
 
1358
                        return -1;
 
1359
                }
 
1360
                /* no need to keep category name */
 
1361
                free(id);
 
1362
 
 
1363
                n = n * 2;
 
1364
        }
 
1365
 
 
1366
        free(levid);
 
1367
 
 
1368
        policydbp->nlevels += n;
 
1369
 
 
1370
        return 0;
 
1371
#else
 
1372
        yyerror("level definition in non-MLS configuration");
 
1373
        return -1;
 
1374
#endif
 
1375
}
 
1376
 
 
1377
 
 
1378
static int define_common_base(void)
 
1379
{
 
1380
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
1381
        char *id, *perm, *base;
 
1382
        common_datum_t *comdatum;
 
1383
        perm_datum_t *perdatum;
 
1384
 
 
1385
 
 
1386
        if (pass == 2) {
 
1387
                id = queue_remove(id_queue); free(id);
 
1388
                while ((id = queue_remove(id_queue))) {
 
1389
                        free(id);
 
1390
                        while ((id = queue_remove(id_queue))) {
 
1391
                                free(id);
 
1392
                        }
 
1393
                }
 
1394
                return 0;
 
1395
        }
 
1396
 
 
1397
        id = (char *) queue_remove(id_queue);
 
1398
        if (!id) {
 
1399
                yyerror("no common name for common base definition?");
 
1400
                return -1;
 
1401
        }
 
1402
        comdatum = (common_datum_t *) hashtab_search(policydbp->p_commons.table,
 
1403
                                                     (hashtab_key_t) id);
 
1404
        if (!comdatum) {
 
1405
                sprintf(errormsg, "common %s is not defined", id);
 
1406
                yyerror(errormsg);
 
1407
                free(id);
 
1408
                return -1;
 
1409
        }
 
1410
        while ((perm = queue_remove(id_queue))) {
 
1411
                perdatum = (perm_datum_t *) hashtab_search(comdatum->permissions.table,
 
1412
                                                   (hashtab_key_t) perm);
 
1413
                if (!perdatum) {
 
1414
                        sprintf(errormsg, "permission %s is not defined for common %s", perm, id);
 
1415
                        yyerror(errormsg);
 
1416
                        free(id);
 
1417
                        free(perm);
 
1418
                        return -1;
 
1419
                }
 
1420
 
 
1421
                /*
 
1422
                 * An explicit definition of base_permissions for this
 
1423
                 * permission.  Reset the value to zero.
 
1424
                 */
 
1425
                perdatum->base_perms = 0;
 
1426
 
 
1427
                while ((base = queue_remove(id_queue))) {
 
1428
                        if (!strcmp(base, "read"))
 
1429
                                perdatum->base_perms |= MLS_BASE_READ;
 
1430
                        else if (!strcmp(base, "write"))
 
1431
                                perdatum->base_perms |= MLS_BASE_WRITE;
 
1432
                        else if (!strcmp(base, "readby"))
 
1433
                                perdatum->base_perms |= MLS_BASE_READBY;
 
1434
                        else if (!strcmp(base, "writeby"))
 
1435
                                perdatum->base_perms |= MLS_BASE_WRITEBY;
 
1436
                        else if (strcmp(base, "none")) {
 
1437
                                sprintf(errormsg, "base permission %s is not defined", base);
 
1438
                                yyerror(errormsg);
 
1439
                                free(base);
 
1440
                                return -1;
 
1441
                        }
 
1442
                        free(base);
 
1443
                }
 
1444
 
 
1445
                free(perm);
 
1446
        }
 
1447
 
 
1448
        free(id);
 
1449
 
 
1450
        return 0;
 
1451
#else
 
1452
        yyerror("MLS base permission definition in non-MLS configuration");
 
1453
        return -1;
 
1454
#endif
 
1455
}
 
1456
 
 
1457
 
 
1458
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
1459
static int common_base_set(hashtab_key_t key, hashtab_datum_t datum, void *p)
 
1460
{
 
1461
        perm_datum_t *perdatum;
 
1462
        class_datum_t *cladatum;
 
1463
 
 
1464
        perdatum = (perm_datum_t *) datum;
 
1465
        cladatum = (class_datum_t *) p;
 
1466
 
 
1467
        if (perdatum->base_perms & MLS_BASE_READ)
 
1468
                cladatum->mlsperms.read |= (1 << (perdatum->value - 1));
 
1469
 
 
1470
        if (perdatum->base_perms & MLS_BASE_WRITE)
 
1471
                cladatum->mlsperms.write |= (1 << (perdatum->value - 1));
 
1472
 
 
1473
        if (perdatum->base_perms & MLS_BASE_READBY)
 
1474
                cladatum->mlsperms.readby |= (1 << (perdatum->value - 1));
 
1475
 
 
1476
        if (perdatum->base_perms & MLS_BASE_WRITEBY)
 
1477
                cladatum->mlsperms.writeby |= (1 << (perdatum->value - 1));
 
1478
 
 
1479
        return 0;
 
1480
}
 
1481
#endif
 
1482
 
 
1483
static int define_av_base(void)
 
1484
{
 
1485
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
1486
        char *id, *base;
 
1487
        class_datum_t *cladatum;
 
1488
        perm_datum_t *perdatum;
 
1489
 
 
1490
        if (pass == 2) {
 
1491
                id = queue_remove(id_queue); free(id);
 
1492
                while ((id = queue_remove(id_queue))) {
 
1493
                        free(id);
 
1494
                        while ((id = queue_remove(id_queue))) {
 
1495
                                free(id);
 
1496
                        }
 
1497
                }
 
1498
                return 0;
 
1499
        }
 
1500
 
 
1501
        id = (char *) queue_remove(id_queue);
 
1502
        if (!id) {
 
1503
                yyerror("no tclass name for av base definition?");
 
1504
                return -1;
 
1505
        }
 
1506
        cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
 
1507
                                                    (hashtab_key_t) id);
 
1508
        if (!cladatum) {
 
1509
                sprintf(errormsg, "class %s is not defined", id);
 
1510
                yyerror(errormsg);
 
1511
                free(id);
 
1512
                return -1;
 
1513
        }
 
1514
        free(id);
 
1515
 
 
1516
        /*
 
1517
         * Determine which common permissions should be included in each MLS
 
1518
         * vector for this access vector definition.
 
1519
         */
 
1520
        if (cladatum->comdatum)
 
1521
                hashtab_map(cladatum->comdatum->permissions.table, common_base_set, cladatum);
 
1522
 
 
1523
        while ((id = queue_remove(id_queue))) {
 
1524
                perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table,
 
1525
                                                     (hashtab_key_t) id);
 
1526
                if (!perdatum) {
 
1527
                        sprintf(errormsg, "permission %s is not defined", id);
 
1528
                        yyerror(errormsg);
 
1529
                        free(id);
 
1530
                        return -1;
 
1531
                }
 
1532
                /*
 
1533
                 * An explicit definition of base_permissions for this
 
1534
                 * permission.  Reset the value to zero.
 
1535
                 */
 
1536
                perdatum->base_perms = 0;
 
1537
 
 
1538
                while ((base = queue_remove(id_queue))) {
 
1539
                        if (!strcmp(base, "read")) {
 
1540
                                perdatum->base_perms |= MLS_BASE_READ;
 
1541
                                cladatum->mlsperms.read |= (1 << (perdatum->value - 1));
 
1542
                        } else if (!strcmp(base, "write")) {
 
1543
                                perdatum->base_perms |= MLS_BASE_WRITE;
 
1544
                                cladatum->mlsperms.write |= (1 << (perdatum->value - 1));
 
1545
                        } else if (!strcmp(base, "readby")) {
 
1546
                                perdatum->base_perms |= MLS_BASE_READBY;
 
1547
                                cladatum->mlsperms.readby |= (1 << (perdatum->value - 1));
 
1548
                        } else if (!strcmp(base, "writeby")) {
 
1549
                                perdatum->base_perms |= MLS_BASE_WRITEBY;
 
1550
                                cladatum->mlsperms.writeby |= (1 << (perdatum->value - 1));
 
1551
                        } else if (strcmp(base, "none")) {
 
1552
                                sprintf(errormsg, "base permission %s is not defined", base);
 
1553
                                yyerror(errormsg);
 
1554
                                free(base);
 
1555
                                continue;
 
1556
                        }
 
1557
                        free(base);
 
1558
                }
 
1559
 
 
1560
                free(id);
 
1561
        }
 
1562
 
 
1563
        return 0;
 
1564
#else
 
1565
        yyerror("MLS base permission definition in non-MLS configuration");
 
1566
        return -1;
 
1567
#endif
 
1568
}
 
1569
 
 
1570
static int define_attrib(void)
 
1571
{
 
1572
        char *id;
 
1573
        type_datum_t *attr;
 
1574
        int ret;
 
1575
 
 
1576
 
 
1577
        if (pass == 2) {
 
1578
                free(queue_remove(id_queue));
 
1579
                return 0;
 
1580
        }
 
1581
 
 
1582
        id = (char *) queue_remove(id_queue);
 
1583
        if (!id) {
 
1584
                return -1;
 
1585
        }
 
1586
 
 
1587
        attr = hashtab_search(policydbp->p_types.table, id);
 
1588
        if (attr) {
 
1589
                sprintf(errormsg, "duplicate declaration for attribute %s\n",
 
1590
                        id);
 
1591
                yyerror(errormsg);
 
1592
                return -1;
 
1593
        }
 
1594
 
 
1595
        attr = (type_datum_t *) malloc(sizeof(type_datum_t));
 
1596
        if (!attr) {
 
1597
                yyerror("out of memory");
 
1598
                return -1;
 
1599
        }
 
1600
        memset(attr, 0, sizeof(type_datum_t));
 
1601
        attr->isattr = TRUE;
 
1602
        ret = hashtab_insert(policydbp->p_types.table,
 
1603
                             id, (hashtab_datum_t) attr);
 
1604
        if (ret) {
 
1605
                yyerror("hash table overflow");
 
1606
                return -1;
 
1607
        }
 
1608
 
 
1609
        return 0;
 
1610
}
 
1611
 
 
1612
static int define_typealias(void)
 
1613
{
 
1614
        char *id;
 
1615
        type_datum_t *t, *aliasdatum;;
 
1616
        int ret;
 
1617
 
 
1618
 
 
1619
        if (pass == 2) {
 
1620
                while ((id = queue_remove(id_queue))) 
 
1621
                        free(id);
 
1622
                return 0;
 
1623
        }
 
1624
 
 
1625
        id = (char *) queue_remove(id_queue);
 
1626
        if (!id) {
 
1627
                yyerror("no type name for typealias definition?");
 
1628
                return -1;
 
1629
        }
 
1630
 
 
1631
        t = hashtab_search(policydbp->p_types.table, id);
 
1632
        if (!t || t->isattr) {
 
1633
                sprintf(errormsg, "unknown type %s", id);
 
1634
                yyerror(errormsg);
 
1635
                free(id);
 
1636
                return -1;
 
1637
        }
 
1638
 
 
1639
        while ((id = queue_remove(id_queue))) {
 
1640
                aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
 
1641
                if (!aliasdatum) {
 
1642
                        yyerror("out of memory");
 
1643
                        return -1;
 
1644
                }
 
1645
                memset(aliasdatum, 0, sizeof(type_datum_t));
 
1646
                aliasdatum->value = t->value;
 
1647
 
 
1648
                ret = hashtab_insert(policydbp->p_types.table,
 
1649
                                     (hashtab_key_t) id, (hashtab_datum_t) aliasdatum);
 
1650
 
 
1651
                if (ret == HASHTAB_PRESENT) {
 
1652
                        sprintf(errormsg, "name conflict for type alias %s", id);
 
1653
                        yyerror(errormsg);
 
1654
                        free(aliasdatum);
 
1655
                        free(id);
 
1656
                        return -1;
 
1657
                }
 
1658
                if (ret == HASHTAB_OVERFLOW) {
 
1659
                        yyerror("hash table overflow");
 
1660
                        free(aliasdatum);
 
1661
                        free(id);
 
1662
                        return -1;
 
1663
                }
 
1664
        }
 
1665
        return 0;
 
1666
}
 
1667
 
 
1668
static int define_type(int alias)
 
1669
{
 
1670
        char *id;
 
1671
        type_datum_t *datum, *aliasdatum, *attr;
 
1672
        int ret, newattr = 0;
 
1673
 
 
1674
 
 
1675
        if (pass == 2) {
 
1676
                while ((id = queue_remove(id_queue))) 
 
1677
                        free(id);
 
1678
                if (alias) {
 
1679
                        while ((id = queue_remove(id_queue))) 
 
1680
                                free(id);
 
1681
                }
 
1682
                return 0;
 
1683
        }
 
1684
 
 
1685
        id = (char *) queue_remove(id_queue);
 
1686
        if (!id) {
 
1687
                yyerror("no type name for type definition?");
 
1688
                return -1;
 
1689
        }
 
1690
 
 
1691
        datum = (type_datum_t *) malloc(sizeof(type_datum_t));
 
1692
        if (!datum) {
 
1693
                yyerror("out of memory");
 
1694
                free(id);
 
1695
                return -1;
 
1696
        }
 
1697
        memset(datum, 0, sizeof(type_datum_t));
 
1698
        datum->primary = TRUE;
 
1699
        datum->value = ++policydbp->p_types.nprim;
 
1700
 
 
1701
        ret = hashtab_insert(policydbp->p_types.table,
 
1702
                             (hashtab_key_t) id, (hashtab_datum_t) datum);
 
1703
 
 
1704
        if (ret == HASHTAB_PRESENT) {
 
1705
                --policydbp->p_types.nprim;
 
1706
                free(datum);
 
1707
                sprintf(errormsg, "name conflict for type %s", id);
 
1708
                yyerror(errormsg);
 
1709
                free(id);
 
1710
                return -1;
 
1711
        }
 
1712
        if (ret == HASHTAB_OVERFLOW) {
 
1713
                yyerror("hash table overflow");
 
1714
                free(datum);
 
1715
                free(id);
 
1716
                return -1;
 
1717
        }
 
1718
 
 
1719
        if (alias) { 
 
1720
                while ((id = queue_remove(id_queue))) {
 
1721
                        aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
 
1722
                        if (!aliasdatum) {
 
1723
                                yyerror("out of memory");
 
1724
                                return -1;
 
1725
                        }
 
1726
                        memset(aliasdatum, 0, sizeof(type_datum_t));
 
1727
                        aliasdatum->value = datum->value;
 
1728
 
 
1729
                        ret = hashtab_insert(policydbp->p_types.table,
 
1730
                                             (hashtab_key_t) id, (hashtab_datum_t) aliasdatum);
 
1731
 
 
1732
                        if (ret == HASHTAB_PRESENT) {
 
1733
                                sprintf(errormsg, "name conflict for type alias %s", id);
 
1734
                                yyerror(errormsg);
 
1735
                                free(aliasdatum);
 
1736
                                free(id);
 
1737
                                return -1;
 
1738
                        }
 
1739
                        if (ret == HASHTAB_OVERFLOW) {
 
1740
                                yyerror("hash table overflow");
 
1741
                                free(aliasdatum);
 
1742
                                free(id);
 
1743
                                return -1;
 
1744
                        }
 
1745
                }
 
1746
        }
 
1747
 
 
1748
        while ((id = queue_remove(id_queue))) {
 
1749
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
1750
                if (!strcmp(id, "mlstrustedreader")) {
 
1751
                        if (ebitmap_set_bit(&policydbp->trustedreaders, datum->value - 1, TRUE)) {
 
1752
                                yyerror("out of memory");
 
1753
                                free(id);
 
1754
                                return -1;
 
1755
                        }
 
1756
                } else if (!strcmp(id, "mlstrustedwriter")) {
 
1757
                        if (ebitmap_set_bit(&policydbp->trustedwriters, datum->value - 1, TRUE)) {
 
1758
                                yyerror("out of memory");
 
1759
                                free(id);
 
1760
                                return -1;
 
1761
                        }
 
1762
                } else if (!strcmp(id, "mlstrustedobject")) {
 
1763
                        if (ebitmap_set_bit(&policydbp->trustedobjects, datum->value - 1, TRUE)) {
 
1764
                                yyerror("out of memory");
 
1765
                                free(id);
 
1766
                                return -1;
 
1767
                        }
 
1768
                }
 
1769
#endif
 
1770
                attr = hashtab_search(policydbp->p_types.table, id);
 
1771
                if (!attr) {
 
1772
                        sprintf(errormsg, "attribute %s is not declared", id);
 
1773
#if 1
 
1774
                        /* treat it as a fatal error */
 
1775
                        yyerror(errormsg);
 
1776
                        return -1;
 
1777
#else
 
1778
                        /* Warn but automatically define the attribute.
 
1779
                           Useful for quickly finding all those attributes you
 
1780
                           forgot to declare. */
 
1781
                        yywarn(errormsg);
 
1782
                        attr = (type_datum_t *) malloc(sizeof(type_datum_t));
 
1783
                        if (!attr) {
 
1784
                                yyerror("out of memory");
 
1785
                                return -1;
 
1786
                        }
 
1787
                        memset(attr, 0, sizeof(type_datum_t));
 
1788
                        attr->isattr = TRUE;
 
1789
                        ret = hashtab_insert(policydbp->p_types.table,
 
1790
                                             id, (hashtab_datum_t) attr);
 
1791
                        if (ret) {
 
1792
                                yyerror("hash table overflow");
 
1793
                                return -1;
 
1794
                        }
 
1795
                        newattr = 1;
 
1796
#endif
 
1797
                } else {
 
1798
                        newattr = 0;
 
1799
                }
 
1800
 
 
1801
                if (!attr->isattr) {
 
1802
                        sprintf(errormsg, "%s is a type, not an attribute", id);
 
1803
                        yyerror(errormsg);
 
1804
                        return -1;
 
1805
                }
 
1806
 
 
1807
                if (!newattr)
 
1808
                        free(id);
 
1809
 
 
1810
                ebitmap_set_bit(&attr->types, datum->value - 1, TRUE);
 
1811
        }
 
1812
 
 
1813
        return 0;
 
1814
}
 
1815
 
 
1816
struct val_to_name {
 
1817
        unsigned int val;
 
1818
        char *name;
 
1819
};
 
1820
 
 
1821
static int type_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, void *p)
 
1822
{
 
1823
        type_datum_t *typdatum;
 
1824
        struct val_to_name *v = p;
 
1825
 
 
1826
        typdatum = (type_datum_t *) datum;
 
1827
 
 
1828
        if (v->val == typdatum->value) {
 
1829
                v->name = key;
 
1830
                return 1;
 
1831
        }
 
1832
 
 
1833
        return 0;
 
1834
}
 
1835
 
 
1836
static char *type_val_to_name(unsigned int val) 
 
1837
{
 
1838
        struct val_to_name v;
 
1839
        int rc;
 
1840
 
 
1841
        v.val = val;
 
1842
        rc = hashtab_map(policydbp->p_types.table, 
 
1843
                         type_val_to_name_helper, &v);
 
1844
        if (rc)
 
1845
                return v.name;
 
1846
        return NULL;
 
1847
}
 
1848
 
 
1849
 
 
1850
static int set_types(ebitmap_t *set,
 
1851
                     ebitmap_t *negset,
 
1852
                     char *id,
 
1853
                     int *add)
 
1854
{
 
1855
        type_datum_t *t;
 
1856
        unsigned int i;
 
1857
 
 
1858
        if (strcmp(id, "*") == 0) {
 
1859
                /* set all types not in negset */
 
1860
                for (i = 0; i < policydbp->p_types.nprim; i++) {
 
1861
                        if (!ebitmap_get_bit(negset, i))
 
1862
                                ebitmap_set_bit(set, i, TRUE);
 
1863
                }
 
1864
                free(id);
 
1865
                return 0;
 
1866
        }
 
1867
 
 
1868
        if (strcmp(id, "~") == 0) {
 
1869
                /* complement the set */
 
1870
                for (i = 0; i < policydbp->p_types.nprim; i++) {
 
1871
                        if (ebitmap_get_bit(set, i))
 
1872
                                ebitmap_set_bit(set, i, FALSE);
 
1873
                        else 
 
1874
                                ebitmap_set_bit(set, i, TRUE);
 
1875
                }
 
1876
                free(id);
 
1877
                return 0;
 
1878
        }
 
1879
 
 
1880
        if (strcmp(id, "-") == 0) {
 
1881
                *add = 0;
 
1882
                free(id);
 
1883
                return 0;
 
1884
        }       
 
1885
 
 
1886
        t = hashtab_search(policydbp->p_types.table, id);
 
1887
        if (!t) {
 
1888
                sprintf(errormsg, "unknown type %s", id);
 
1889
                yyerror(errormsg);
 
1890
                free(id);
 
1891
                return -1;
 
1892
        }
 
1893
 
 
1894
        if (t->isattr) {
 
1895
                /* set or clear all types with this attribute,
 
1896
                   but do not set anything explicitly cleared previously */
 
1897
                for (i = ebitmap_startbit(&t->types); i < ebitmap_length(&t->types); i++) {
 
1898
                        if (!ebitmap_get_bit(&t->types, i)) 
 
1899
                                continue;               
 
1900
                        if (!(*add)) {
 
1901
                                ebitmap_set_bit(set, i, FALSE);
 
1902
                                ebitmap_set_bit(negset, i, TRUE);
 
1903
                        } else if (!ebitmap_get_bit(negset, i)) {
 
1904
                                ebitmap_set_bit(set, i, TRUE);
 
1905
#if VERBOSE
 
1906
                        } else {
 
1907
                                char *name = type_val_to_name(i+1);
 
1908
                                sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
 
1909
                                yywarn(errormsg);
 
1910
#endif
 
1911
                        }
 
1912
                }
 
1913
        } else {
 
1914
                /* set or clear one type, but do not set anything
 
1915
                   explicitly cleared previously */     
 
1916
                if (!(*add)) {
 
1917
                        ebitmap_set_bit(set, t->value - 1, FALSE);
 
1918
                        ebitmap_set_bit(negset, t->value - 1, TRUE);
 
1919
                } else if (!ebitmap_get_bit(negset, t->value - 1)) {
 
1920
                        ebitmap_set_bit(set, t->value - 1, TRUE);
 
1921
#if VERBOSE
 
1922
                } else {
 
1923
                        sprintf(errormsg, "ignoring %s due to prior -%s", id, id);
 
1924
                        yywarn(errormsg);
 
1925
#endif
 
1926
                }
 
1927
        }
 
1928
 
 
1929
        free(id);
 
1930
        *add = 1;
 
1931
        return 0;
 
1932
}
 
1933
 
 
1934
 
 
1935
static int define_compute_type(int which)
 
1936
{
 
1937
        char *id;
 
1938
        avtab_key_t avkey;
 
1939
        avtab_datum_t avdatum, *avdatump;
 
1940
        type_datum_t *datum;
 
1941
        class_datum_t *cladatum;
 
1942
        ebitmap_t stypes, ttypes, tclasses, negset;
 
1943
        __u32 newtype = 0;
 
1944
        int ret, add = 1;
 
1945
        unsigned int i, j, k;
 
1946
 
 
1947
        if (pass == 1) {
 
1948
                while ((id = queue_remove(id_queue))) 
 
1949
                        free(id);
 
1950
                while ((id = queue_remove(id_queue))) 
 
1951
                        free(id);
 
1952
                while ((id = queue_remove(id_queue))) 
 
1953
                        free(id);
 
1954
                id = queue_remove(id_queue);
 
1955
                free(id);
 
1956
                return 0;
 
1957
        }
 
1958
 
 
1959
        ebitmap_init(&stypes);
 
1960
        ebitmap_init(&ttypes);
 
1961
        ebitmap_init(&tclasses);
 
1962
 
 
1963
        ebitmap_init(&negset);
 
1964
        while ((id = queue_remove(id_queue))) {
 
1965
                if (set_types(&stypes, &negset, id, &add))
 
1966
                        return -1;
 
1967
        }
 
1968
        ebitmap_destroy(&negset);
 
1969
 
 
1970
        ebitmap_init(&negset);
 
1971
        while ((id = queue_remove(id_queue))) {
 
1972
                if (set_types(&ttypes, &negset, id, &add))
 
1973
                        return -1;
 
1974
        }
 
1975
        ebitmap_destroy(&negset);
 
1976
 
 
1977
        while ((id = queue_remove(id_queue))) {
 
1978
                cladatum = hashtab_search(policydbp->p_classes.table, id);
 
1979
                if (!cladatum) {
 
1980
                        sprintf(errormsg, "unknown class %s", id);
 
1981
                        yyerror(errormsg);
 
1982
                        goto bad;
 
1983
                }
 
1984
                ebitmap_set_bit(&tclasses, cladatum->value - 1, TRUE);
 
1985
                free(id);
 
1986
        }
 
1987
 
 
1988
        id = (char *) queue_remove(id_queue);
 
1989
        if (!id) {
 
1990
                yyerror("no newtype?");
 
1991
                goto bad;
 
1992
        }
 
1993
        datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
 
1994
                                                (hashtab_key_t) id);
 
1995
        if (!datum || datum->isattr) {
 
1996
                sprintf(errormsg, "unknown type %s", id);
 
1997
                yyerror(errormsg);
 
1998
                goto bad;
 
1999
        }
 
2000
 
 
2001
        for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
 
2002
                if (!ebitmap_get_bit(&stypes, i)) 
 
2003
                        continue;
 
2004
                for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
 
2005
                        if (!ebitmap_get_bit(&ttypes, j)) 
 
2006
                                continue;
 
2007
                        for (k = ebitmap_startbit(&tclasses); k < ebitmap_length(&tclasses); k++) {
 
2008
                                if (!ebitmap_get_bit(&tclasses, k)) 
 
2009
                                        continue;
 
2010
                                avkey.source_type = i + 1;
 
2011
                                avkey.target_type = j + 1;
 
2012
                                avkey.target_class = k + 1;
 
2013
                                avdatump = avtab_search(&policydbp->te_avtab, &avkey, AVTAB_TYPE);
 
2014
                                if (avdatump) {
 
2015
                                        switch (which) {
 
2016
                                        case AVTAB_TRANSITION:
 
2017
                                                newtype = avtab_transition(avdatump);
 
2018
                                                break;
 
2019
                                        case AVTAB_MEMBER:
 
2020
                                                newtype = avtab_member(avdatump);
 
2021
                                                break;
 
2022
                                        case AVTAB_CHANGE:
 
2023
                                                newtype = avtab_change(avdatump);
 
2024
                                                break;
 
2025
                                        }
 
2026
                                        if ( (avdatump->specified & which) &&
 
2027
                                             (newtype != datum->value) ) {
 
2028
                                                sprintf(errormsg, "conflicting rule for (%s, %s:%s):  default was %s, is now %s", type_val_to_name(i+1), type_val_to_name(j+1), policydbp->p_class_val_to_name[k],
 
2029
                                                        type_val_to_name(newtype),
 
2030
                                                        type_val_to_name(datum->value));
 
2031
                                                yywarn(errormsg);
 
2032
                                        }
 
2033
                                        avdatump->specified |= which;
 
2034
                                        switch (which) {
 
2035
                                        case AVTAB_TRANSITION:
 
2036
                                                avtab_transition(avdatump) = datum->value;
 
2037
                                                break;
 
2038
                                        case AVTAB_MEMBER:
 
2039
                                                avtab_member(avdatump) = datum->value;
 
2040
                                                break;
 
2041
                                        case AVTAB_CHANGE:
 
2042
                                                avtab_change(avdatump) = datum->value;
 
2043
                                                break;
 
2044
                                        }
 
2045
                                } else {
 
2046
                                        memset(&avdatum, 0, sizeof avdatum);
 
2047
                                        avdatum.specified |= which;
 
2048
                                        switch (which) {
 
2049
                                        case AVTAB_TRANSITION:
 
2050
                                                avtab_transition(&avdatum) = datum->value;
 
2051
                                                break;
 
2052
                                        case AVTAB_MEMBER:
 
2053
                                                avtab_member(&avdatum) = datum->value;
 
2054
                                                break;
 
2055
                                        case AVTAB_CHANGE:
 
2056
                                                avtab_change(&avdatum) = datum->value;
 
2057
                                                break;
 
2058
                                        }
 
2059
                                        ret = avtab_insert(&policydbp->te_avtab, &avkey, &avdatum);
 
2060
                                        if (ret) {
 
2061
                                                yyerror("hash table overflow");
 
2062
                                                goto bad;
 
2063
                                        }
 
2064
                                }
 
2065
                        }
 
2066
                }
 
2067
        }
 
2068
 
 
2069
        return 0;
 
2070
 
 
2071
      bad:
 
2072
        return -1;
 
2073
}
 
2074
 
 
2075
static cond_av_list_t *define_cond_compute_type(int which)
 
2076
{
 
2077
        char *id;
 
2078
        cond_av_list_t *sub_list;
 
2079
        avtab_key_t avkey;
 
2080
        avtab_datum_t avdatum, *avdatump;
 
2081
        type_datum_t *datum;
 
2082
        class_datum_t *cladatum;
 
2083
        ebitmap_t stypes, ttypes, tclasses, negset;
 
2084
        __u32 newtype = 0;
 
2085
        int i, j, k, add = 1;
 
2086
 
 
2087
        if (pass == 1) {
 
2088
                while ((id = queue_remove(id_queue)))
 
2089
                        free(id);
 
2090
                while ((id = queue_remove(id_queue)))
 
2091
                        free(id);
 
2092
                while ((id = queue_remove(id_queue)))
 
2093
                        free(id);
 
2094
                id = queue_remove(id_queue);
 
2095
                free(id);
 
2096
                return (cond_av_list_t *)1; /* any non-NULL value */
 
2097
        }
 
2098
        
 
2099
        ebitmap_init(&stypes);
 
2100
        ebitmap_init(&ttypes);
 
2101
        ebitmap_init(&tclasses);
 
2102
 
 
2103
        ebitmap_init(&negset);
 
2104
        while ((id = queue_remove(id_queue))) {
 
2105
                if (set_types(&stypes, &negset, id, &add))
 
2106
                        return  COND_ERR;
 
2107
        }
 
2108
        ebitmap_destroy(&negset);
 
2109
 
 
2110
        ebitmap_init(&negset);
 
2111
        while ((id = queue_remove(id_queue))) {
 
2112
                if (set_types(&ttypes, &negset, id, &add))
 
2113
                        return COND_ERR;
 
2114
        }
 
2115
        ebitmap_destroy(&negset);
 
2116
 
 
2117
        while ((id = queue_remove(id_queue))) {
 
2118
                cladatum = hashtab_search(policydbp->p_classes.table, id);
 
2119
                if (!cladatum) {
 
2120
                        sprintf(errormsg, "unknown class %s", id);
 
2121
                        yyerror(errormsg);
 
2122
                        goto bad;
 
2123
                }
 
2124
                ebitmap_set_bit(&tclasses, cladatum->value - 1, TRUE);
 
2125
                free(id);
 
2126
        }
 
2127
 
 
2128
        id = (char *) queue_remove(id_queue);
 
2129
        if (!id) {
 
2130
                yyerror("no newtype?");
 
2131
                goto bad;
 
2132
        }
 
2133
        datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
 
2134
                                                (hashtab_key_t) id);
 
2135
        if (!datum || datum->isattr) {
 
2136
                sprintf(errormsg, "unknown type %s", id);
 
2137
                yyerror(errormsg);
 
2138
                goto bad;
 
2139
        }
 
2140
 
 
2141
        /* create sub_list to be passed back and appended to true or false list */
 
2142
        sub_list = (cond_av_list_t *) 0;
 
2143
 
 
2144
        for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
 
2145
                if (!ebitmap_get_bit(&stypes, i)) 
 
2146
                        continue;
 
2147
                for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
 
2148
                        if (!ebitmap_get_bit(&ttypes, j)) 
 
2149
                                continue;
 
2150
                        for (k = ebitmap_startbit(&tclasses); k < ebitmap_length(&tclasses); k++) {
 
2151
                                if (!ebitmap_get_bit(&tclasses, k)) 
 
2152
                                        continue;
 
2153
                                avkey.source_type = i + 1;
 
2154
                                avkey.target_type = j + 1;
 
2155
                                avkey.target_class = k + 1;
 
2156
                                avdatump = avtab_search(&policydbp->te_avtab, &avkey, AVTAB_TYPE);
 
2157
                                
 
2158
                                /* does rule exist in base policy? */
 
2159
                                if ((avdatump) && (avdatump->specified & which)) {
 
2160
                                        switch (which) {
 
2161
                                        case AVTAB_TRANSITION:
 
2162
                                                newtype = avtab_transition(avdatump);
 
2163
                                                break;
 
2164
                                        case AVTAB_MEMBER:
 
2165
                                                newtype = avtab_member(avdatump);
 
2166
                                                break;
 
2167
                                        case AVTAB_CHANGE:
 
2168
                                                newtype = avtab_change(avdatump);
 
2169
                                                break;
 
2170
                                        }
 
2171
                                        if ( (newtype != datum->value) ) {
 
2172
                                                sprintf(errormsg, "conflicting type rule for conditional "
 
2173
                                                        "(%s, %s:%s) in base: default is %s, conditional %s "
 
2174
                                                        "will be ignored", 
 
2175
                                                        type_val_to_name(i+1), 
 
2176
                                                        type_val_to_name(j+1), 
 
2177
                                                        policydbp->p_class_val_to_name[k],
 
2178
                                                        type_val_to_name(newtype),
 
2179
                                                        type_val_to_name(datum->value));
 
2180
                                                yywarn(errormsg);
 
2181
                                        } else {
 
2182
                                                sprintf(errormsg, "conditional type rule (%s, %s:%s): "
 
2183
                                                        "has same default, %s, as rule in base policy; "
 
2184
                                                        "conditional %s will be ignored", 
 
2185
                                                        type_val_to_name(i+1), 
 
2186
                                                        type_val_to_name(j+1), 
 
2187
                                                        policydbp->p_class_val_to_name[k],
 
2188
                                                        type_val_to_name(newtype),
 
2189
                                                        type_val_to_name(datum->value));
 
2190
                                                yywarn(errormsg);
 
2191
                                        }
 
2192
                                }
 
2193
                                /* rule does not exist in base policy */
 
2194
                                else {
 
2195
                                        
 
2196
                                        memset(&avdatum, 0, sizeof avdatum);
 
2197
                                        avdatum.specified |= which;
 
2198
                                        switch (which) {
 
2199
                                        case AVTAB_TRANSITION:
 
2200
                                                avtab_transition(&avdatum) = datum->value;
 
2201
                                                break;
 
2202
                                        case AVTAB_MEMBER:
 
2203
                                                avtab_member(&avdatum) = datum->value;
 
2204
                                                break;
 
2205
                                        case AVTAB_CHANGE:
 
2206
                                                avtab_change(&avdatum) = datum->value;
 
2207
                                                break;
 
2208
                                        }
 
2209
                                        /* add rule to sub list */
 
2210
                                        sub_list = cond_list_append(sub_list, &avkey, &avdatum);
 
2211
                                        if (sub_list == COND_ERR) {
 
2212
                                                yyerror("list overflow");
 
2213
                                                goto bad;
 
2214
                                        }
 
2215
                                }
 
2216
                        }
 
2217
                }
 
2218
        }
 
2219
        
 
2220
        return sub_list;
 
2221
 
 
2222
      bad:
 
2223
        return COND_ERR;
 
2224
}
 
2225
 
 
2226
static cond_av_list_t *cond_list_append(cond_av_list_t *sl, avtab_key_t *key, avtab_datum_t *datum) {
 
2227
 
 
2228
        cond_av_list_t  *n, *end;
 
2229
 
 
2230
        n = (cond_av_list_t *) malloc(sizeof(cond_av_list_t));
 
2231
        if (!n) {
 
2232
                  yyerror("out of memory");
 
2233
                  return COND_ERR;
 
2234
        }
 
2235
        memset(n, 0, sizeof(cond_av_list_t));
 
2236
        if (sl) {
 
2237
                for(end=sl; end->next != NULL; end = end->next);
 
2238
                end->next = n;
 
2239
        }
 
2240
        else sl = n;
 
2241
        n->next = NULL;
 
2242
        
 
2243
        /* construct new node */
 
2244
        n->node = (avtab_ptr_t) malloc(sizeof(struct avtab_node));
 
2245
        if (!n->node) {
 
2246
                yyerror("out of memory");
 
2247
                return COND_ERR;
 
2248
        }
 
2249
        memset(n->node, 0, sizeof(struct avtab_node));
 
2250
        n->node->key = *key;
 
2251
        n->node->datum = *datum;
 
2252
        /* the next two fields get filled in when we add to true/false list  */
 
2253
        n->node->next = (avtab_ptr_t) 0;
 
2254
        n->node->parse_context = (void *) 0;
 
2255
        
 
2256
        return(sl);
 
2257
}
 
2258
 
 
2259
 
 
2260
static int perm_name(hashtab_key_t key, hashtab_datum_t datum, void *data)
 
2261
{
 
2262
        struct val_to_name *v = data;
 
2263
        perm_datum_t *perdatum;
 
2264
 
 
2265
        perdatum = (perm_datum_t *) datum;
 
2266
 
 
2267
        if (v->val == perdatum->value) {
 
2268
                v->name = key;
 
2269
                return 1;
 
2270
        }
 
2271
 
 
2272
        return 0;
 
2273
}
 
2274
 
 
2275
 
 
2276
char *av_to_string(__u32 tclass, access_vector_t av)
 
2277
{
 
2278
        struct val_to_name v;
 
2279
        static char avbuf[1024];
 
2280
        class_datum_t *cladatum;
 
2281
        char *perm = NULL, *p;
 
2282
        unsigned int i;
 
2283
        int rc;
 
2284
 
 
2285
        cladatum = policydbp->class_val_to_struct[tclass-1];
 
2286
        p = avbuf;
 
2287
        for (i = 0; i < cladatum->permissions.nprim; i++) {
 
2288
                if (av & (1 << i)) {
 
2289
                        v.val = i+1;
 
2290
                        rc = hashtab_map(cladatum->permissions.table,
 
2291
                                         perm_name, &v);
 
2292
                        if (!rc && cladatum->comdatum) {
 
2293
                                rc = hashtab_map(
 
2294
                                        cladatum->comdatum->permissions.table,
 
2295
                                        perm_name, &v);
 
2296
                        }
 
2297
                        if (rc)
 
2298
                                perm = v.name;
 
2299
                        if (perm) {
 
2300
                                sprintf(p, " %s", perm);
 
2301
                                p += strlen(p);
 
2302
                        }
 
2303
                }
 
2304
        }
 
2305
 
 
2306
        return avbuf;
 
2307
}
 
2308
 
 
2309
static int define_bool()
 
2310
{
 
2311
        char *id, *name;
 
2312
        cond_bool_datum_t *datum;
 
2313
        int ret;
 
2314
 
 
2315
 
 
2316
        if (pass == 2) {
 
2317
                while ((id = queue_remove(id_queue)))
 
2318
                        free(id);
 
2319
                return 0;
 
2320
        }               
 
2321
 
 
2322
        id = (char *) queue_remove(id_queue);
 
2323
        if (!id) {
 
2324
                yyerror("no identifier for bool definition?");
 
2325
                return -1;
 
2326
        }
 
2327
        name = id;
 
2328
 
 
2329
        id = (char *) queue_remove(id_queue);
 
2330
        if (!id) {
 
2331
                yyerror("no default value for bool definition?");
 
2332
                free(name);
 
2333
                return -1;
 
2334
        }
 
2335
 
 
2336
        datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
 
2337
        if (!datum) {
 
2338
                yyerror("out of memory");
 
2339
                free(id);
 
2340
                free(name);
 
2341
                return -1;
 
2342
        }
 
2343
        memset(datum, 0, sizeof(cond_bool_datum_t));
 
2344
        datum->state = (int)(id[0] == 'T') ? 1 : 0;
 
2345
        datum->value = ++policydbp->p_bools.nprim;
 
2346
 
 
2347
        ret = hashtab_insert(policydbp->p_bools.table,
 
2348
                             (hashtab_key_t) name, (hashtab_datum_t) datum);
 
2349
 
 
2350
        if (ret == HASHTAB_PRESENT) {
 
2351
                --policydbp->p_bools.nprim;
 
2352
                free(datum);
 
2353
                sprintf(errormsg, "name conflict for bool %s", id);
 
2354
                yyerror(errormsg);
 
2355
                free(id);
 
2356
                free(name);
 
2357
                return -1;
 
2358
        }
 
2359
        if (ret == HASHTAB_OVERFLOW) {
 
2360
                yyerror("hash table overflow");
 
2361
                free(datum);
 
2362
                free(id);
 
2363
                free(name);
 
2364
                return -1;
 
2365
        }
 
2366
        return 0;
 
2367
}
 
2368
 
 
2369
static cond_av_list_t *define_cond_pol_list( cond_av_list_t *avlist, cond_av_list_t *sl )
 
2370
{
 
2371
        cond_av_list_t *end;
 
2372
 
 
2373
        if (pass == 1) {
 
2374
                /* return something so we get through pass 1 */
 
2375
                return (cond_av_list_t *)1;
 
2376
        }
 
2377
 
 
2378
        /* if we've started collecting sub lists, prepend to start of collection
 
2379
           because it's probably less iterations than appending. */
 
2380
        if (!sl) return avlist;
 
2381
        else if (!avlist) return sl;
 
2382
        else {
 
2383
                end = sl;
 
2384
                while (end->next) end = end->next;
 
2385
                end->next = avlist;
 
2386
        } 
 
2387
        return sl;
 
2388
}
 
2389
 
 
2390
static int te_avtab_helper(int which, unsigned int stype, unsigned int ttype, 
 
2391
                           ebitmap_t *tclasses, access_vector_t *avp)
 
2392
 
 
2393
{
 
2394
        avtab_key_t avkey;
 
2395
        avtab_datum_t avdatum, *avdatump;
 
2396
        int ret;
 
2397
        unsigned int k;
 
2398
 
 
2399
        if (which == -AVTAB_ALLOWED) {
 
2400
                yyerror("neverallow should not reach this function.");
 
2401
                return -1;
 
2402
        }
 
2403
 
 
2404
        for (k = ebitmap_startbit(tclasses); k < ebitmap_length(tclasses); k++) {
 
2405
                if (!ebitmap_get_bit(tclasses, k)) 
 
2406
                        continue;
 
2407
                avkey.source_type = stype + 1;
 
2408
                avkey.target_type = ttype + 1;
 
2409
                avkey.target_class = k + 1;
 
2410
                avdatump = avtab_search(&policydbp->te_avtab, &avkey, AVTAB_AV);
 
2411
                if (!avdatump) {
 
2412
                        memset(&avdatum, 0, sizeof avdatum);
 
2413
                        avdatum.specified = (which > 0) ? which : -which;
 
2414
                        ret = avtab_insert(&policydbp->te_avtab, &avkey, &avdatum);
 
2415
                        if (ret) {
 
2416
                                yyerror("hash table overflow");
 
2417
                                return -1;
 
2418
                        }
 
2419
                        avdatump = avtab_search(&policydbp->te_avtab, &avkey, AVTAB_AV);
 
2420
                        if (!avdatump) {
 
2421
                                yyerror("inserted entry vanished!");
 
2422
                                return -1;
 
2423
                        }
 
2424
                }
 
2425
 
 
2426
                avdatump->specified |= ((which > 0) ? which : -which);
 
2427
 
 
2428
                switch (which) {
 
2429
                case AVTAB_ALLOWED:
 
2430
                        avtab_allowed(avdatump) |= avp[k];
 
2431
                        break;
 
2432
                case AVTAB_AUDITALLOW:
 
2433
                        avtab_auditallow(avdatump) |= avp[k];
 
2434
                        break;
 
2435
                case AVTAB_AUDITDENY:
 
2436
                        avtab_auditdeny(avdatump) |= avp[k];
 
2437
                        break;
 
2438
                case -AVTAB_AUDITDENY:
 
2439
                        if (avtab_auditdeny(avdatump))
 
2440
                                avtab_auditdeny(avdatump) &= ~avp[k];
 
2441
                        else
 
2442
                                avtab_auditdeny(avdatump) = ~avp[k];
 
2443
                        break;
 
2444
                }
 
2445
        }
 
2446
 
 
2447
        return 0;
 
2448
}
 
2449
 
 
2450
static  cond_av_list_t *cond_te_avtab_helper(int which, int stype, int ttype, 
 
2451
                           ebitmap_t *tclasses, access_vector_t *avp )
 
2452
 
 
2453
{
 
2454
        cond_av_list_t *sl;
 
2455
        avtab_key_t avkey;
 
2456
        avtab_datum_t avdatum;
 
2457
        int  k;
 
2458
 
 
2459
        if (which == -AVTAB_ALLOWED) {
 
2460
                yyerror("neverallow should not reach this function.");
 
2461
                return COND_ERR;
 
2462
        }
 
2463
 
 
2464
        /* create sub_list to be passed back and appended to true or false list */
 
2465
        sl = (cond_av_list_t *) 0;
 
2466
 
 
2467
        for (k = ebitmap_startbit(tclasses); k < ebitmap_length(tclasses); k++) {
 
2468
                if (!ebitmap_get_bit(tclasses, k)) 
 
2469
                        continue;
 
2470
                /* build the key */
 
2471
                avkey.source_type = stype + 1;
 
2472
                avkey.target_type = ttype + 1;
 
2473
                avkey.target_class = k + 1;
 
2474
                
 
2475
                /* build the datum */
 
2476
                memset(&avdatum, 0, sizeof avdatum);
 
2477
                avdatum.specified = (which > 0) ? which : -which;
 
2478
 
 
2479
                switch (which) {
 
2480
                case AVTAB_ALLOWED:
 
2481
                        avtab_allowed(&avdatum) = avp[k];
 
2482
                        break;
 
2483
                case AVTAB_AUDITALLOW:
 
2484
                        avtab_auditallow(&avdatum) = avp[k];
 
2485
                        break;
 
2486
                case AVTAB_AUDITDENY:
 
2487
                        yyerror("AUDITDENY statements are not allowed in a conditional block; use DONTAUDIT");
 
2488
                        return COND_ERR;
 
2489
                case -AVTAB_AUDITDENY:
 
2490
                        avtab_auditdeny(&avdatum) = ~avp[k];
 
2491
                        break;
 
2492
                }
 
2493
 
 
2494
                /* add to temporary list */
 
2495
                sl = cond_list_append(sl, &avkey, &avdatum);
 
2496
 
 
2497
                if (sl == COND_ERR) {
 
2498
                        yyerror("list overflow");
 
2499
                        return COND_ERR;
 
2500
                }
 
2501
        }
 
2502
 
 
2503
        return sl;
 
2504
}
 
2505
 
 
2506
static cond_av_list_t *define_cond_te_avtab(int which)
 
2507
{
 
2508
        char *id;
 
2509
        cond_av_list_t *sub_list, *self_list, *n;
 
2510
        class_datum_t *cladatum;
 
2511
        perm_datum_t *perdatum;
 
2512
        ebitmap_t stypes, ttypes, tclasses, negset;
 
2513
        access_vector_t *avp;
 
2514
        int i, j, hiclass, self = 0, add = 1;
 
2515
 
 
2516
        if (pass == 1) {
 
2517
                while ((id = queue_remove(id_queue))) 
 
2518
                        free(id);
 
2519
                while ((id = queue_remove(id_queue))) 
 
2520
                        free(id);
 
2521
                while ((id = queue_remove(id_queue))) 
 
2522
                        free(id);
 
2523
                while ((id = queue_remove(id_queue))) 
 
2524
                        free(id);
 
2525
                return (cond_av_list_t *) 1; /* any non-NULL value */
 
2526
        }
 
2527
 
 
2528
        ebitmap_init(&stypes);
 
2529
        ebitmap_init(&ttypes);
 
2530
        ebitmap_init(&tclasses);
 
2531
 
 
2532
        ebitmap_init(&negset);
 
2533
        while ((id = queue_remove(id_queue))) {
 
2534
                if (set_types(&stypes, &negset, id, &add))
 
2535
                        return COND_ERR;
 
2536
        }
 
2537
        ebitmap_destroy(&negset);
 
2538
 
 
2539
        ebitmap_init(&negset);
 
2540
        while ((id = queue_remove(id_queue))) {
 
2541
                if (strcmp(id, "self") == 0) {
 
2542
                        self = 1;
 
2543
                        continue;
 
2544
                }
 
2545
                if (set_types(&ttypes, &negset, id, &add))
 
2546
                        return COND_ERR;
 
2547
        }
 
2548
        ebitmap_destroy(&negset);
 
2549
 
 
2550
        hiclass = 0;
 
2551
        while ((id = queue_remove(id_queue))) {
 
2552
                cladatum = hashtab_search(policydbp->p_classes.table, id);
 
2553
                if (!cladatum)  {
 
2554
                        sprintf(errormsg, "unknown class %s used in rule", id);
 
2555
                        yyerror(errormsg);
 
2556
                        goto bad;
 
2557
                }
 
2558
                ebitmap_set_bit(&tclasses, cladatum->value - 1, TRUE);  
 
2559
                if (cladatum->value > hiclass)
 
2560
                        hiclass = cladatum->value;
 
2561
                free(id);
 
2562
        }
 
2563
 
 
2564
        avp = malloc(hiclass * sizeof(access_vector_t));
 
2565
        if (!avp) {
 
2566
                yyerror("out of memory");
 
2567
                return COND_ERR;
 
2568
        }
 
2569
        for (i = 0; i < hiclass; i++)
 
2570
                avp[i] = 0;
 
2571
        while ((id = queue_remove(id_queue))) {
 
2572
                for (i = ebitmap_startbit(&tclasses); i < ebitmap_length(&tclasses); i++) {
 
2573
                        if (!ebitmap_get_bit(&tclasses, i)) 
 
2574
                                continue;
 
2575
                        cladatum = policydbp->class_val_to_struct[i];
 
2576
 
 
2577
                        if (strcmp(id, "*") == 0) {
 
2578
                                /* set all permissions in the class */
 
2579
                                avp[i] = ~0;
 
2580
                                continue;
 
2581
                        }
 
2582
 
 
2583
                        if (strcmp(id, "~") == 0) {
 
2584
                                /* complement the set */
 
2585
                                if (which == -AVTAB_AUDITDENY) 
 
2586
                                        yywarn("dontaudit rule with a ~?");
 
2587
                                avp[i] = ~avp[i];
 
2588
                                continue;
 
2589
                        }
 
2590
 
 
2591
                        perdatum = hashtab_search(cladatum->permissions.table,
 
2592
                                                  id);
 
2593
                        if (!perdatum) {
 
2594
                                if (cladatum->comdatum) {
 
2595
                                        perdatum = hashtab_search(cladatum->comdatum->permissions.table,
 
2596
                                                                  id);
 
2597
                                }
 
2598
                        }
 
2599
                        if (!perdatum) {
 
2600
                                sprintf(errormsg, "permission %s is not defined for class %s", id, policydbp->p_class_val_to_name[i]);
 
2601
                                yyerror(errormsg);
 
2602
                                continue;
 
2603
                        }
 
2604
 
 
2605
                        avp[i] |= (1 << (perdatum->value - 1));
 
2606
                }
 
2607
 
 
2608
                free(id);
 
2609
        }
 
2610
 
 
2611
        sub_list = (cond_av_list_t *) 0;
 
2612
        self_list = (cond_av_list_t *) 0;
 
2613
        for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
 
2614
                if (!ebitmap_get_bit(&stypes, i)) 
 
2615
                        continue;
 
2616
                if (self) {
 
2617
                        if ((self_list = cond_te_avtab_helper(which, i, i, &tclasses, avp )) == COND_ERR)
 
2618
                                return COND_ERR;
 
2619
                }
 
2620
                for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
 
2621
                        if (!ebitmap_get_bit(&ttypes, j)) 
 
2622
                                continue;
 
2623
                        if ((sub_list = cond_te_avtab_helper(which, i, j, &tclasses, avp)) == COND_ERR)
 
2624
                                return COND_ERR;
 
2625
                        /* add the self_list, if any, and the sub_list */
 
2626
                        if (self_list) {
 
2627
                                n = self_list;
 
2628
                                while (n->next != (cond_av_list_t *)0) n = n->next;
 
2629
                                n->next = sub_list;
 
2630
                        } else {
 
2631
                                self_list = sub_list;
 
2632
                        }
 
2633
                }
 
2634
        }
 
2635
 
 
2636
        ebitmap_destroy(&stypes);
 
2637
        ebitmap_destroy(&ttypes);
 
2638
        ebitmap_destroy(&tclasses);
 
2639
        free(avp);
 
2640
        
 
2641
        return self_list;
 
2642
 bad:
 
2643
        return COND_ERR;
 
2644
}
 
2645
 
 
2646
 
 
2647
static int define_te_avtab(int which)
 
2648
{
 
2649
        char *id;
 
2650
        class_datum_t *cladatum;
 
2651
        perm_datum_t *perdatum;
 
2652
        ebitmap_t stypes, ttypes, tclasses, negset;
 
2653
        access_vector_t *avp;
 
2654
        unsigned int i, j, hiclass;
 
2655
        int self = 0, add = 1;
 
2656
        te_assert_t *newassert;
 
2657
 
 
2658
        if (pass == 1) {
 
2659
                while ((id = queue_remove(id_queue))) 
 
2660
                        free(id);
 
2661
                while ((id = queue_remove(id_queue))) 
 
2662
                        free(id);
 
2663
                while ((id = queue_remove(id_queue))) 
 
2664
                        free(id);
 
2665
                while ((id = queue_remove(id_queue))) 
 
2666
                        free(id);
 
2667
                return 0;
 
2668
        }
 
2669
 
 
2670
        ebitmap_init(&stypes);
 
2671
        ebitmap_init(&ttypes);
 
2672
        ebitmap_init(&tclasses);
 
2673
 
 
2674
        ebitmap_init(&negset);
 
2675
        while ((id = queue_remove(id_queue))) {
 
2676
                if (set_types(&stypes, &negset, id, &add))
 
2677
                        return -1;
 
2678
        }
 
2679
        ebitmap_destroy(&negset);
 
2680
 
 
2681
        ebitmap_init(&negset);
 
2682
        while ((id = queue_remove(id_queue))) {
 
2683
                if (strcmp(id, "self") == 0) {
 
2684
                        self = 1;
 
2685
                        continue;
 
2686
                }
 
2687
                if (set_types(&ttypes, &negset, id, &add))
 
2688
                        return -1;
 
2689
        }
 
2690
        ebitmap_destroy(&negset);
 
2691
 
 
2692
        hiclass = 0;
 
2693
        while ((id = queue_remove(id_queue))) {
 
2694
                cladatum = hashtab_search(policydbp->p_classes.table, id);
 
2695
                if (!cladatum) {
 
2696
                        sprintf(errormsg, "unknown class %s used in rule", id);
 
2697
                        yyerror(errormsg);
 
2698
                        goto bad;
 
2699
                }
 
2700
                ebitmap_set_bit(&tclasses, cladatum->value - 1, TRUE);  
 
2701
                if (cladatum->value > hiclass)
 
2702
                        hiclass = cladatum->value;
 
2703
                free(id);
 
2704
        }
 
2705
 
 
2706
        avp = malloc(hiclass * sizeof(access_vector_t));
 
2707
        if (!avp) {
 
2708
                yyerror("out of memory");
 
2709
                return -1;
 
2710
        }
 
2711
        for (i = 0; i < hiclass; i++)
 
2712
                avp[i] = 0;
 
2713
 
 
2714
        while ((id = queue_remove(id_queue))) {
 
2715
                for (i = ebitmap_startbit(&tclasses); i < ebitmap_length(&tclasses); i++) {
 
2716
                        if (!ebitmap_get_bit(&tclasses, i)) 
 
2717
                                continue;
 
2718
                        cladatum = policydbp->class_val_to_struct[i];
 
2719
 
 
2720
                        if (strcmp(id, "*") == 0) {
 
2721
                                /* set all permissions in the class */
 
2722
                                avp[i] = ~0U;
 
2723
                                continue;
 
2724
                        }
 
2725
 
 
2726
                        if (strcmp(id, "~") == 0) {
 
2727
                                /* complement the set */
 
2728
                                if (which == -AVTAB_AUDITDENY) 
 
2729
                                        yywarn("dontaudit rule with a ~?");
 
2730
                                avp[i] = ~avp[i];
 
2731
                                continue;
 
2732
                        }
 
2733
 
 
2734
                        perdatum = hashtab_search(cladatum->permissions.table,
 
2735
                                                  id);
 
2736
                        if (!perdatum) {
 
2737
                                if (cladatum->comdatum) {
 
2738
                                        perdatum = hashtab_search(cladatum->comdatum->permissions.table,
 
2739
                                                                  id);
 
2740
                                }
 
2741
                        }
 
2742
                        if (!perdatum) {
 
2743
                                sprintf(errormsg, "permission %s is not defined for class %s", id, policydbp->p_class_val_to_name[i]);
 
2744
                                yyerror(errormsg);
 
2745
                                continue;
 
2746
                        }
 
2747
 
 
2748
                        avp[i] |= (1 << (perdatum->value - 1));
 
2749
                }
 
2750
 
 
2751
                free(id);
 
2752
        }
 
2753
 
 
2754
        if (which == -AVTAB_ALLOWED) {
 
2755
                newassert = malloc(sizeof(te_assert_t));
 
2756
                if (!newassert) {
 
2757
                        yyerror("out of memory");
 
2758
                        return -1;
 
2759
                }
 
2760
                memset(newassert, 0, sizeof(te_assert_t));
 
2761
                newassert->stypes = stypes;
 
2762
                newassert->ttypes = ttypes;
 
2763
                newassert->tclasses = tclasses;
 
2764
                newassert->self = self;
 
2765
                newassert->avp = avp;
 
2766
                newassert->line = policydb_lineno;
 
2767
                newassert->next = te_assertions;
 
2768
                te_assertions = newassert;
 
2769
                return 0;
 
2770
        }
 
2771
 
 
2772
        for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
 
2773
                if (!ebitmap_get_bit(&stypes, i)) 
 
2774
                        continue;
 
2775
                if (self) {
 
2776
                        if (te_avtab_helper(which, i, i, &tclasses, avp))
 
2777
                                return -1;
 
2778
                }
 
2779
                for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
 
2780
                        if (!ebitmap_get_bit(&ttypes, j)) 
 
2781
                                continue;
 
2782
                        if (te_avtab_helper(which, i, j, &tclasses, avp))
 
2783
                                return -1;
 
2784
                }
 
2785
        }
 
2786
 
 
2787
        ebitmap_destroy(&stypes);
 
2788
        ebitmap_destroy(&ttypes);
 
2789
        ebitmap_destroy(&tclasses);
 
2790
        free(avp);
 
2791
 
 
2792
        return 0;
 
2793
 bad:
 
2794
        return -1;
 
2795
}
 
2796
 
 
2797
 
 
2798
static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum, void *p)
 
2799
{
 
2800
        struct val_to_name *v = p;
 
2801
        role_datum_t *roldatum;
 
2802
 
 
2803
        roldatum = (role_datum_t *) datum;
 
2804
 
 
2805
        if (v->val == roldatum->value) {
 
2806
                v->name = key;
 
2807
                return 1;
 
2808
        }
 
2809
 
 
2810
        return 0;
 
2811
}
 
2812
 
 
2813
 
 
2814
static char *role_val_to_name(unsigned int val) 
 
2815
{
 
2816
        struct val_to_name v;
 
2817
        int rc;
 
2818
 
 
2819
        v.val = val;
 
2820
        rc = hashtab_map(policydbp->p_roles.table, 
 
2821
                         role_val_to_name_helper, &v);
 
2822
        if (rc)
 
2823
                return v.name;
 
2824
        return NULL;
 
2825
}
 
2826
 
 
2827
static int define_role_types(void)
 
2828
{
 
2829
        role_datum_t *role;
 
2830
        char *role_id, *id;
 
2831
        int ret, add = 1;
 
2832
        ebitmap_t negset;
 
2833
 
 
2834
        if (pass == 1) {
 
2835
                while ((id = queue_remove(id_queue))) 
 
2836
                        free(id);
 
2837
                return 0;
 
2838
        }
 
2839
 
 
2840
        role_id = queue_remove(id_queue);
 
2841
 
 
2842
        role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
 
2843
                                               role_id);
 
2844
        if (!role) {
 
2845
                role = (role_datum_t *) malloc(sizeof(role_datum_t));
 
2846
                if (!role) {
 
2847
                        yyerror("out of memory");
 
2848
                        free(role_id);
 
2849
                        return -1;
 
2850
                }
 
2851
                memset(role, 0, sizeof(role_datum_t));
 
2852
                role->value = ++policydbp->p_roles.nprim;
 
2853
                ebitmap_set_bit(&role->dominates, role->value-1, TRUE);
 
2854
                ret = hashtab_insert(policydbp->p_roles.table,
 
2855
                                     (hashtab_key_t) role_id, (hashtab_datum_t) role);
 
2856
 
 
2857
                if (ret) {
 
2858
                        yyerror("hash table overflow");
 
2859
                        free(role);
 
2860
                        free(role_id);
 
2861
                        return -1;
 
2862
                }
 
2863
        } else
 
2864
                free(role_id);
 
2865
 
 
2866
        ebitmap_init(&negset);
 
2867
        while ((id = queue_remove(id_queue))) {
 
2868
                if (set_types(&role->types, &negset, id, &add))
 
2869
                        return -1;
 
2870
        }
 
2871
        ebitmap_destroy(&negset);
 
2872
 
 
2873
        return 0;
 
2874
}
 
2875
 
 
2876
 
 
2877
static role_datum_t *
 
2878
 merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
 
2879
{
 
2880
        role_datum_t *new;
 
2881
 
 
2882
        if (pass == 1) {
 
2883
                return (role_datum_t *)1; /* any non-NULL value */
 
2884
        }
 
2885
 
 
2886
        new = malloc(sizeof(role_datum_t));
 
2887
        if (!new) {
 
2888
                yyerror("out of memory");
 
2889
                return NULL;
 
2890
        }
 
2891
        memset(new, 0, sizeof(role_datum_t));
 
2892
        new->value = 0;         /* temporary role */
 
2893
        if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
 
2894
                yyerror("out of memory");
 
2895
                return NULL;
 
2896
        }
 
2897
        if (ebitmap_or(&new->types, &r1->types, &r2->types)) {
 
2898
                yyerror("out of memory");
 
2899
                return NULL;
 
2900
        }
 
2901
        if (!r1->value) {
 
2902
                /* free intermediate result */
 
2903
                ebitmap_destroy(&r1->types);
 
2904
                ebitmap_destroy(&r1->dominates);
 
2905
                free(r1);
 
2906
        }
 
2907
        if (!r2->value) {
 
2908
                /* free intermediate result */
 
2909
                yyerror("right hand role is temporary?");
 
2910
                ebitmap_destroy(&r2->types);
 
2911
                ebitmap_destroy(&r2->dominates);
 
2912
                free(r2);
 
2913
        }
 
2914
        return new;
 
2915
}
 
2916
 
 
2917
 
 
2918
static role_datum_t *
 
2919
 define_role_dom(role_datum_t * r)
 
2920
{
 
2921
        role_datum_t *role;
 
2922
        char *role_id;
 
2923
        unsigned int i;
 
2924
        int ret;
 
2925
 
 
2926
        if (pass == 1) {
 
2927
                role_id = queue_remove(id_queue);
 
2928
                free(role_id);
 
2929
                return (role_datum_t *)1; /* any non-NULL value */
 
2930
        }
 
2931
 
 
2932
        role_id = queue_remove(id_queue);
 
2933
        role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
 
2934
                                               role_id);
 
2935
        if (!role) {
 
2936
                role = (role_datum_t *) malloc(sizeof(role_datum_t));
 
2937
                if (!role) {
 
2938
                        yyerror("out of memory");
 
2939
                        free(role_id);
 
2940
                        return NULL;
 
2941
                }
 
2942
                memset(role, 0, sizeof(role_datum_t));
 
2943
                role->value = ++policydbp->p_roles.nprim;
 
2944
                ebitmap_set_bit(&role->dominates, role->value-1, TRUE);
 
2945
                ret = hashtab_insert(policydbp->p_roles.table,
 
2946
                                     (hashtab_key_t) role_id, (hashtab_datum_t) role);
 
2947
 
 
2948
                if (ret) {
 
2949
                        yyerror("hash table overflow");
 
2950
                        free(role);
 
2951
                        free(role_id);
 
2952
                        return NULL;
 
2953
                }
 
2954
        }
 
2955
        if (r) {
 
2956
                for (i = ebitmap_startbit(&r->dominates); i < ebitmap_length(&r->dominates); i++) {
 
2957
                        if (ebitmap_get_bit(&r->dominates, i))
 
2958
                                ebitmap_set_bit(&role->dominates, i, TRUE);
 
2959
                }
 
2960
                for (i = ebitmap_startbit(&r->types); i < ebitmap_length(&r->types); i++)       {
 
2961
                        if (ebitmap_get_bit(&r->types, i))
 
2962
                                ebitmap_set_bit(&role->types, i, TRUE);
 
2963
                }
 
2964
                if (!r->value) {
 
2965
                        /* free intermediate result */
 
2966
                        ebitmap_destroy(&r->types);
 
2967
                        ebitmap_destroy(&r->dominates);
 
2968
                        free(r);
 
2969
                }
 
2970
        }
 
2971
        return role;
 
2972
}
 
2973
 
 
2974
 
 
2975
static int set_roles(ebitmap_t *set,
 
2976
                     char *id)
 
2977
{
 
2978
        role_datum_t *r;
 
2979
        unsigned int i;
 
2980
 
 
2981
        if (strcmp(id, "*") == 0) {
 
2982
                /* set all roles */
 
2983
                for (i = 0; i < policydbp->p_roles.nprim; i++) 
 
2984
                        ebitmap_set_bit(set, i, TRUE);
 
2985
                free(id);
 
2986
                return 0;
 
2987
        }
 
2988
 
 
2989
        if (strcmp(id, "~") == 0) {
 
2990
                /* complement the set */
 
2991
                for (i = 0; i < policydbp->p_roles.nprim; i++) {
 
2992
                        if (ebitmap_get_bit(set, i))
 
2993
                                ebitmap_set_bit(set, i, FALSE);
 
2994
                        else 
 
2995
                                ebitmap_set_bit(set, i, TRUE);
 
2996
                }
 
2997
                free(id);
 
2998
                return 0;
 
2999
        }
 
3000
 
 
3001
        r = hashtab_search(policydbp->p_roles.table, id);
 
3002
        if (!r) {
 
3003
                sprintf(errormsg, "unknown role %s", id);
 
3004
                yyerror(errormsg);
 
3005
                free(id);
 
3006
                return -1;
 
3007
        }
 
3008
 
 
3009
        /* set one role */
 
3010
        ebitmap_set_bit(set, r->value - 1, TRUE);
 
3011
        free(id);
 
3012
        return 0;
 
3013
}
 
3014
 
 
3015
 
 
3016
static int define_role_trans(void)
 
3017
{
 
3018
        char *id;
 
3019
        role_datum_t *role;
 
3020
        ebitmap_t roles, types, negset;
 
3021
        struct role_trans *tr = 0;
 
3022
        unsigned int i, j;
 
3023
        int add = 1;
 
3024
 
 
3025
        if (pass == 1) {
 
3026
                while ((id = queue_remove(id_queue))) 
 
3027
                        free(id);
 
3028
                while ((id = queue_remove(id_queue))) 
 
3029
                        free(id);
 
3030
                id = queue_remove(id_queue);
 
3031
                free(id);
 
3032
                return 0;
 
3033
        }
 
3034
 
 
3035
        ebitmap_init(&roles);
 
3036
        ebitmap_init(&types);
 
3037
 
 
3038
        while ((id = queue_remove(id_queue))) {
 
3039
                if (set_roles(&roles, id))
 
3040
                        return -1;
 
3041
        }
 
3042
 
 
3043
        ebitmap_init(&negset);
 
3044
        while ((id = queue_remove(id_queue))) {
 
3045
                if (set_types(&types, &negset, id, &add))
 
3046
                        return -1;
 
3047
        }
 
3048
        ebitmap_destroy(&negset);
 
3049
 
 
3050
        id = (char *) queue_remove(id_queue);
 
3051
        if (!id) {
 
3052
                yyerror("no new role in transition definition?");
 
3053
                goto bad;
 
3054
        }
 
3055
        role = hashtab_search(policydbp->p_roles.table, id);
 
3056
        if (!role) {
 
3057
                sprintf(errormsg, "unknown role %s used in transition definition", id);
 
3058
                yyerror(errormsg);
 
3059
                goto bad;
 
3060
        }
 
3061
 
 
3062
        for (i = ebitmap_startbit(&roles); i < ebitmap_length(&roles); i++) {
 
3063
                if (!ebitmap_get_bit(&roles, i)) 
 
3064
                        continue;
 
3065
                for (j = ebitmap_startbit(&types); j < ebitmap_length(&types); j++) {
 
3066
                        if (!ebitmap_get_bit(&types, j)) 
 
3067
                                continue;
 
3068
 
 
3069
                        for (tr = policydbp->role_tr; tr; tr = tr->next) {
 
3070
                                if (tr->role == (i+1) && tr->type == (j+1)) {
 
3071
                                        sprintf(errormsg, "duplicate role transition defined for (%s,%s)", 
 
3072
                                                role_val_to_name(i+1), type_val_to_name(j+1));
 
3073
                                        yyerror(errormsg);
 
3074
                                        goto bad;
 
3075
                                }
 
3076
                        }
 
3077
 
 
3078
                        tr = malloc(sizeof(struct role_trans));
 
3079
                        if (!tr) {
 
3080
                                yyerror("out of memory");
 
3081
                                return -1;
 
3082
                        }
 
3083
                        memset(tr, 0, sizeof(struct role_trans));
 
3084
                        tr->role = i+1;
 
3085
                        tr->type = j+1;
 
3086
                        tr->new_role = role->value;
 
3087
                        tr->next = policydbp->role_tr;
 
3088
                        policydbp->role_tr = tr;
 
3089
                }
 
3090
        }
 
3091
 
 
3092
        return 0;
 
3093
 
 
3094
 bad:
 
3095
        return -1;
 
3096
}
 
3097
 
 
3098
 
 
3099
static int define_role_allow(void)
 
3100
{
 
3101
        char *id;
 
3102
        ebitmap_t roles, new_roles;
 
3103
        struct role_allow *ra = 0;
 
3104
        unsigned int i, j;
 
3105
 
 
3106
        if (pass == 1) {
 
3107
                while ((id = queue_remove(id_queue))) 
 
3108
                        free(id);
 
3109
                while ((id = queue_remove(id_queue))) 
 
3110
                        free(id);
 
3111
                return 0;
 
3112
        }
 
3113
 
 
3114
        ebitmap_init(&roles);
 
3115
        ebitmap_init(&new_roles);
 
3116
 
 
3117
        while ((id = queue_remove(id_queue))) {
 
3118
                if (set_roles(&roles, id))
 
3119
                        return -1;
 
3120
        }
 
3121
 
 
3122
 
 
3123
        while ((id = queue_remove(id_queue))) {
 
3124
                if (set_roles(&new_roles, id))
 
3125
                        return -1;
 
3126
        }
 
3127
 
 
3128
        for (i = ebitmap_startbit(&roles); i < ebitmap_length(&roles); i++) {
 
3129
                if (!ebitmap_get_bit(&roles, i)) 
 
3130
                        continue;
 
3131
                for (j = ebitmap_startbit(&new_roles); j < ebitmap_length(&new_roles); j++) {
 
3132
                        if (!ebitmap_get_bit(&new_roles, j)) 
 
3133
                                continue;
 
3134
 
 
3135
                        for (ra = policydbp->role_allow; ra; ra = ra->next) {
 
3136
                                if (ra->role == (i+1) && ra->new_role == (j+1))
 
3137
                                        break;
 
3138
                        }
 
3139
 
 
3140
                        if (ra) 
 
3141
                                continue;
 
3142
 
 
3143
                        ra = malloc(sizeof(struct role_allow));
 
3144
                        if (!ra) {
 
3145
                                yyerror("out of memory");
 
3146
                                return -1;
 
3147
                        }
 
3148
                        memset(ra, 0, sizeof(struct role_allow));
 
3149
                        ra->role = i+1;
 
3150
                        ra->new_role = j+1;
 
3151
                        ra->next = policydbp->role_allow;
 
3152
                        policydbp->role_allow = ra;
 
3153
                }
 
3154
        }
 
3155
 
 
3156
        return 0;
 
3157
}
 
3158
 
 
3159
 
 
3160
static int define_constraint(constraint_expr_t * expr)
 
3161
{
 
3162
        struct constraint_node *node;
 
3163
        char *id;
 
3164
        class_datum_t *cladatum;
 
3165
        perm_datum_t *perdatum;
 
3166
        ebitmap_t classmap;
 
3167
        constraint_expr_t *e;
 
3168
        unsigned int i;
 
3169
        int depth;
 
3170
 
 
3171
        if (pass == 1) {
 
3172
                while ((id = queue_remove(id_queue))) 
 
3173
                        free(id);
 
3174
                while ((id = queue_remove(id_queue))) 
 
3175
                        free(id);
 
3176
                return 0;
 
3177
        }
 
3178
 
 
3179
        depth = -1;
 
3180
        for (e = expr; e; e = e->next) {
 
3181
                switch (e->expr_type) {
 
3182
                case CEXPR_NOT:
 
3183
                        if (depth < 0) {
 
3184
                                yyerror("illegal constraint expression");
 
3185
                                return -1;
 
3186
                        }
 
3187
                        break;
 
3188
                case CEXPR_AND:
 
3189
                case CEXPR_OR:
 
3190
                        if (depth < 1) {
 
3191
                                yyerror("illegal constraint expression");
 
3192
                                return -1;
 
3193
                        }
 
3194
                        depth--;
 
3195
                        break;
 
3196
                case CEXPR_ATTR:
 
3197
                case CEXPR_NAMES:
 
3198
                        if (depth == (CEXPR_MAXDEPTH-1)) {
 
3199
                                yyerror("constraint expression is too deep");
 
3200
                                return -1;
 
3201
                        }
 
3202
                        depth++;
 
3203
                        break;
 
3204
                default:
 
3205
                        yyerror("illegal constraint expression");
 
3206
                        return -1;
 
3207
                }
 
3208
        }
 
3209
        if (depth != 0) {
 
3210
                yyerror("illegal constraint expression");
 
3211
                return -1;
 
3212
        }
 
3213
 
 
3214
        ebitmap_init(&classmap);
 
3215
        while ((id = queue_remove(id_queue))) {
 
3216
                cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
 
3217
                                                     (hashtab_key_t) id);
 
3218
                if (!cladatum) {
 
3219
                        sprintf(errormsg, "class %s is not defined", id);
 
3220
                        ebitmap_destroy(&classmap);
 
3221
                        yyerror(errormsg);
 
3222
                        free(id);
 
3223
                        return -1;
 
3224
                }
 
3225
                if (ebitmap_set_bit(&classmap, cladatum->value - 1, TRUE)) {
 
3226
                        yyerror("out of memory");
 
3227
                        ebitmap_destroy(&classmap);
 
3228
                        free(id);
 
3229
                        return -1;
 
3230
                }
 
3231
                node = malloc(sizeof(struct constraint_node));
 
3232
                if (!node) {
 
3233
                        yyerror("out of memory");
 
3234
                        return -1;
 
3235
                }
 
3236
                memset(node, 0, sizeof(constraint_node_t));
 
3237
                node->expr = expr;
 
3238
                node->permissions = 0;
 
3239
 
 
3240
                node->next = cladatum->constraints;
 
3241
                cladatum->constraints = node;
 
3242
 
 
3243
                free(id);
 
3244
        }
 
3245
 
 
3246
        while ((id = queue_remove(id_queue))) {
 
3247
                for (i = ebitmap_startbit(&classmap); i < ebitmap_length(&classmap); i++) {
 
3248
                        if (ebitmap_get_bit(&classmap, i)) {
 
3249
                                cladatum = policydbp->class_val_to_struct[i];
 
3250
                                node = cladatum->constraints;
 
3251
 
 
3252
                                perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table,
 
3253
                                                     (hashtab_key_t) id);
 
3254
                                if (!perdatum) {
 
3255
                                        if (cladatum->comdatum) {
 
3256
                                                perdatum = (perm_datum_t *) hashtab_search(cladatum->comdatum->permissions.table,
 
3257
                                                     (hashtab_key_t) id);
 
3258
                                        }
 
3259
                                        if (!perdatum) {
 
3260
                                                sprintf(errormsg, "permission %s is not defined", id);
 
3261
                                                yyerror(errormsg);
 
3262
                                                free(id);
 
3263
                                                ebitmap_destroy(&classmap);
 
3264
                                                return -1;
 
3265
                                        }
 
3266
                                }
 
3267
                                node->permissions |= (1 << (perdatum->value - 1));
 
3268
                        }
 
3269
                }
 
3270
                free(id);
 
3271
        }
 
3272
 
 
3273
        ebitmap_destroy(&classmap);
 
3274
 
 
3275
        return 0;
 
3276
}
 
3277
 
 
3278
static uintptr_t
 
3279
 define_cexpr(__u32 expr_type, uintptr_t arg1, uintptr_t arg2)
 
3280
{
 
3281
        struct constraint_expr *expr, *e1 = NULL, *e2;
 
3282
        user_datum_t *user;
 
3283
        role_datum_t *role;
 
3284
        ebitmap_t negset;
 
3285
        char *id;
 
3286
        __u32 val;
 
3287
        int add = 1;
 
3288
 
 
3289
        if (pass == 1) {
 
3290
                if (expr_type == CEXPR_NAMES) {
 
3291
                        while ((id = queue_remove(id_queue))) 
 
3292
                                free(id);
 
3293
                }
 
3294
                return 1; /* any non-NULL value */
 
3295
        }
 
3296
 
 
3297
        expr = malloc(sizeof(struct constraint_expr));
 
3298
        if (!expr) {
 
3299
                yyerror("out of memory");
 
3300
                return 0;
 
3301
        }
 
3302
        memset(expr, 0, sizeof(constraint_expr_t));
 
3303
        expr->expr_type = expr_type;
 
3304
 
 
3305
        switch (expr_type) {
 
3306
        case CEXPR_NOT:
 
3307
                e1 = NULL;
 
3308
                e2 = (struct constraint_expr *) arg1;
 
3309
                while (e2) {
 
3310
                        e1 = e2;
 
3311
                        e2 = e2->next;
 
3312
                }
 
3313
                if (!e1 || e1->next) {
 
3314
                        yyerror("illegal constraint expression");
 
3315
                        free(expr);
 
3316
                        return 0;
 
3317
                }
 
3318
                e1->next = expr;
 
3319
                return arg1;
 
3320
        case CEXPR_AND:
 
3321
        case CEXPR_OR:
 
3322
                e1 = NULL;
 
3323
                e2 = (struct constraint_expr *) arg1;
 
3324
                while (e2) {
 
3325
                        e1 = e2;
 
3326
                        e2 = e2->next;
 
3327
                }
 
3328
                if (!e1 || e1->next) {
 
3329
                        yyerror("illegal constraint expression");
 
3330
                        free(expr);
 
3331
                        return 0;
 
3332
                }
 
3333
                e1->next = (struct constraint_expr *) arg2;
 
3334
 
 
3335
                e1 = NULL;
 
3336
                e2 = (struct constraint_expr *) arg2;
 
3337
                while (e2) {
 
3338
                        e1 = e2;
 
3339
                        e2 = e2->next;
 
3340
                }
 
3341
                if (!e1 || e1->next) {
 
3342
                        yyerror("illegal constraint expression");
 
3343
                        free(expr);
 
3344
                        return 0;
 
3345
                }
 
3346
                e1->next = expr;
 
3347
                return arg1;
 
3348
        case CEXPR_ATTR:
 
3349
                expr->attr = arg1;
 
3350
                expr->op = arg2;
 
3351
                return (uintptr_t)expr;
 
3352
        case CEXPR_NAMES:
 
3353
                expr->attr = arg1;
 
3354
                expr->op = arg2;
 
3355
                ebitmap_init(&negset);
 
3356
                while ((id = (char *) queue_remove(id_queue))) {
 
3357
                        if (expr->attr & CEXPR_USER) {
 
3358
                                user = (user_datum_t *) hashtab_search(policydbp->p_users.table,
 
3359
                                                                       (hashtab_key_t) id);
 
3360
                                if (!user) {
 
3361
                                        sprintf(errormsg, "unknown user %s", id);
 
3362
                                        yyerror(errormsg);
 
3363
                                        free(expr);
 
3364
                                        return 0;
 
3365
                                }
 
3366
                                val = user->value;
 
3367
                        } else if (expr->attr & CEXPR_ROLE) {
 
3368
                                role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
 
3369
                                                                       (hashtab_key_t) id);
 
3370
                                if (!role) {
 
3371
                                        sprintf(errormsg, "unknown role %s", id);
 
3372
                                        yyerror(errormsg);
 
3373
                                        free(expr);
 
3374
                                        return 0;
 
3375
                                }
 
3376
                                val = role->value;
 
3377
                        } else if (expr->attr & CEXPR_TYPE) {
 
3378
                                if (set_types(&expr->names, &negset, id, &add)) {
 
3379
                                        free(expr);
 
3380
                                        return 0;
 
3381
                                }
 
3382
                                continue;
 
3383
                        } else {
 
3384
                                yyerror("invalid constraint expression");
 
3385
                                free(expr);
 
3386
                                return 0;
 
3387
                        }
 
3388
                        if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
 
3389
                                yyerror("out of memory");
 
3390
                                ebitmap_destroy(&expr->names);
 
3391
                                free(expr);
 
3392
                                return 0;
 
3393
                        }
 
3394
                        free(id);
 
3395
                }
 
3396
                ebitmap_destroy(&negset);
 
3397
                return (uintptr_t)expr;
 
3398
        default:
 
3399
                yyerror("invalid constraint expression");
 
3400
                free(expr);
 
3401
                return 0;
 
3402
        }
 
3403
 
 
3404
        yyerror("invalid constraint expression");
 
3405
        free(expr);
 
3406
        return 0;
 
3407
}
 
3408
 
 
3409
static int define_conditional(cond_expr_t *expr, cond_av_list_t *t, cond_av_list_t *f )
 
3410
{
 
3411
        cond_expr_t *e;
 
3412
        cond_node_t *cn, tmp, *cn_new;
 
3413
        int depth;
 
3414
 
 
3415
 
 
3416
        /* expression cannot be NULL */
 
3417
        if ( !expr) {
 
3418
                yyerror("illegal conditional expression");
 
3419
                return -1;
 
3420
        }
 
3421
        /* Must have at least one rule in true list */
 
3422
        if (!t) {
 
3423
                yyerror("must have at least one rule in true list");
 
3424
                return -1;
 
3425
        }
 
3426
 
 
3427
 
 
3428
        /* verify expression */
 
3429
        depth = -1;
 
3430
        for (e = expr; e; e = e->next) {
 
3431
                switch (e->expr_type) {
 
3432
                case COND_NOT:
 
3433
                        if (depth < 0) {
 
3434
                                yyerror("illegal conditional expression; Bad NOT");
 
3435
                                return -1;
 
3436
                        }
 
3437
                        break;
 
3438
                case COND_AND:
 
3439
                case COND_OR:
 
3440
                case COND_XOR:
 
3441
                case COND_EQ:
 
3442
                case COND_NEQ:
 
3443
                        if (depth < 1) {
 
3444
                                yyerror("illegal conditional expression; Bad binary op");
 
3445
                                return -1;
 
3446
                        }
 
3447
                        depth--;
 
3448
                        break;
 
3449
                case COND_BOOL:
 
3450
                        if (depth == (COND_EXPR_MAXDEPTH-1)) {
 
3451
                                yyerror("conditional expression is like totally too deep");
 
3452
                                return -1;
 
3453
                        }
 
3454
                        depth++;
 
3455
                        break;
 
3456
                default:
 
3457
                        yyerror("illegal conditional expression");
 
3458
                        return -1;
 
3459
                }
 
3460
        }
 
3461
        if (depth != 0) {
 
3462
                yyerror("illegal conditional expression");
 
3463
                return -1;
 
3464
        }
 
3465
 
 
3466
        /*  use tmp conditional node to partially build new node */
 
3467
        cn = &tmp;
 
3468
        cn->expr = expr;
 
3469
        cn->true_list = t;
 
3470
        cn->false_list = f;
 
3471
      
 
3472
        /* normalize/precompute expression */
 
3473
        if (normalize_expr(policydbp, cn) < 0) {
 
3474
                yyerror("problem normalizing conditional expression");
 
3475
                return -1;
 
3476
        }
 
3477
 
 
3478
        /* get the existing conditional node, or a new one*/
 
3479
        cn_new = cond_node_search(policydbp, cn);
 
3480
        if(cn_new) {
 
3481
                cond_reduce_insert_list (cn->true_list, &cn_new->true_list, &cn_new->false_list, cn_new->cur_state);
 
3482
                cond_reduce_insert_list (cn->false_list, &cn_new->false_list, &cn_new->true_list, !cn_new->cur_state);
 
3483
        } else { 
 
3484
                yyerror("could not get a conditional node");
 
3485
                return -1;
 
3486
        }
 
3487
 
 
3488
 
 
3489
        return 0;
 
3490
}
 
3491
 
 
3492
 
 
3493
/*  Set the ENABLE bit and parse_context for each rule and check rules to see if they already exist.
 
3494
 * Insert rules into the conditional db when appropriate.
 
3495
 *  
 
3496
 * new - list of rules to potentially add/insert
 
3497
 * active - list to add rule to, and address to use as parse_context
 
3498
 * inactive - opposite rule list in same conditional
 
3499
 * state - whether rules in new are on or off by default.
 
3500
 *
 
3501
 * There are 4 possible conditions for a TYPE_* rule.  Allow rules are always inserted or
 
3502
 * OR'd with existing allow rules on the same side of the same conditional.
 
3503
 *
 
3504
 * 1) Not present anywhere -> add it
 
3505
 * 2) Already in cond, same side -> warn, replace default in prev rule, delete this rule
 
3506
 * 3) Just added to opp side -> search again (we may still add this rule)
 
3507
 * 4) In another conditional (either side) -> warn, delete this rule
 
3508
 */
 
3509
static void cond_reduce_insert_list(cond_av_list_t *new, cond_av_list_t **active, cond_av_list_t **inactive, int state)
 
3510
{
 
3511
        int add_rule = 1;
 
3512
        cond_av_list_t *c, *top;
 
3513
        avtab_ptr_t dup;
 
3514
        __u32 old_data = 0, new_data = 0;
 
3515
 
 
3516
        top = c = new; 
 
3517
        /* loop through all the rules in the list */
 
3518
        while(c) {
 
3519
 
 
3520
                /* is conditional rule a TYPE_* rule that's already in a conditional? */
 
3521
                /* [note that we checked to see if it's in the base when we parsed the rule] */
 
3522
                if ((c->node->datum.specified & AVTAB_TYPE) &&
 
3523
                    ((dup = avtab_search_node(&policydbp->te_cond_avtab, &c->node->key, c->node->datum.specified & AVTAB_TYPE)) != NULL) ){
 
3524
                        do {
 
3525
                                /* is the rule we found in the current rule list or the equivalent */
 
3526
                                if (dup->parse_context == active) {
 
3527
                                        /* change original default */
 
3528
                                        switch(c->node->datum.specified & AVTAB_TYPE) {
 
3529
                                        case AVTAB_TRANSITION:
 
3530
                                                old_data = avtab_transition(&dup->datum);
 
3531
                                                new_data = avtab_transition(&c->node->datum);
 
3532
                                                avtab_transition(&dup->datum) = new_data;
 
3533
                                                break;
 
3534
                                        case AVTAB_MEMBER:
 
3535
                                                old_data = avtab_member(&dup->datum);
 
3536
                                                new_data = avtab_member(&c->node->datum);
 
3537
                                                avtab_member(&dup->datum) = new_data;
 
3538
                                                break;
 
3539
                                        case AVTAB_CHANGE:
 
3540
                                                old_data = avtab_change(&dup->datum);
 
3541
                                                new_data = avtab_change(&c->node->datum);
 
3542
                                                avtab_change(&dup->datum) = new_data;
 
3543
                                                break;
 
3544
                                        }
 
3545
                                        sprintf(errormsg, "duplicate type rule on same side of conditional for (%s, %s:%s); overwrote original default %s with %s",
 
3546
                                                type_val_to_name(c->node->key.source_type), 
 
3547
                                                type_val_to_name(c->node->key.target_type), 
 
3548
                                                policydbp->p_class_val_to_name[c->node->key.target_class],
 
3549
                                                type_val_to_name(old_data),
 
3550
                                                type_val_to_name(new_data));                                    
 
3551
                                        yywarn(errormsg);
 
3552
                                        add_rule = 0;
 
3553
                                        break;
 
3554
                                }
 
3555
                                /* if the rule we found is in the opposite rule list that's OK*/
 
3556
                                if (dup->parse_context == inactive) {
 
3557
                                        continue;
 
3558
                                } else {
 
3559
                                        /* the rule we found must be in another conditional */
 
3560
                                        sprintf(errormsg, "discarding conflicting conditional type rule for (%s, %s:%s); may only be in one conditional",
 
3561
                                                type_val_to_name(c->node->key.source_type), 
 
3562
                                                type_val_to_name(c->node->key.target_type), 
 
3563
                                                policydbp->p_class_val_to_name[c->node->key.target_class]);
 
3564
                                        yywarn(errormsg);
 
3565
                                        add_rule = 0;
 
3566
                                        break;
 
3567
                                }
 
3568
                        } while ( (dup = avtab_search_node_next(dup, c->node->datum.specified & AVTAB_TYPE)) != NULL);
 
3569
 
 
3570
                } /* end dealing with TYPE_* rules */
 
3571
                else if ( (c->node->datum.specified & AVTAB_AV ) &&
 
3572
                     ((dup = avtab_search_node(&policydbp->te_cond_avtab, &c->node->key, c->node->datum.specified & AVTAB_AV)) != NULL) ){
 
3573
                        do {
 
3574
                                /* we only care if the same AV rule is on the same side of the same conditional */
 
3575
                                if (dup->parse_context == active) {
 
3576
                                        /* add to original */
 
3577
                                        switch(c->node->datum.specified & AVTAB_AV) {
 
3578
                                        case AVTAB_ALLOWED:
 
3579
                                                new_data = avtab_allowed(&c->node->datum);
 
3580
                                                avtab_allowed(&dup->datum) |= new_data;
 
3581
                                                break;
 
3582
                                        case AVTAB_AUDITALLOW:
 
3583
                                                new_data = avtab_auditallow(&c->node->datum);
 
3584
                                                avtab_auditallow(&dup->datum) |= new_data;
 
3585
                                                break;
 
3586
                                        case AVTAB_AUDITDENY:
 
3587
                                                new_data = avtab_auditdeny(&c->node->datum);
 
3588
                                                /* Since a '0' in an auditdeny mask represents a 
 
3589
                                                 * permission we do NOT want to audit (dontaudit), we use
 
3590
                                                 * the '&' operand to ensure that all '0's in the mask
 
3591
                                                 * are retained (much unlike the allow and auditallow cases).
 
3592
                                                 */
 
3593
                                                avtab_auditdeny(&dup->datum) &= new_data;
 
3594
                                                break;
 
3595
                                        }
 
3596
                                        add_rule = 0;
 
3597
                                        break;
 
3598
                                }
 
3599
                        } while ( (dup = avtab_search_node_next(dup, c->node->datum.specified & AVTAB_AV)) != NULL);
 
3600
                } /* end dealing with ALLOW rules */
 
3601
 
 
3602
                top = c->next;
 
3603
                /* Either insert the rule into the policy and active list, or discard the rule */
 
3604
                if (add_rule) {
 
3605
                        c->node = avtab_insert_with_parse_context(&policydbp->te_cond_avtab, 
 
3606
                                                                  &c->node->key,
 
3607
                                                                  &c->node->datum,
 
3608
                                                                  active);
 
3609
                        /* set whether the rule is enabled/disabled */
 
3610
                        if (state) {
 
3611
                                c->node->datum.specified |= AVTAB_ENABLED;
 
3612
                        } else {
 
3613
                                c->node->datum.specified &= ~AVTAB_ENABLED;
 
3614
                        }
 
3615
 
 
3616
                        /* prepend new rule to active list */
 
3617
                        c->next = *active; 
 
3618
                        *active = c; 
 
3619
                } else {
 
3620
                        /* discard rule */
 
3621
                        free(c->node);
 
3622
                        free(c);
 
3623
                        
 
3624
                        add_rule = 1;
 
3625
                }
 
3626
                /* next rule */
 
3627
                c = top;
 
3628
                
 
3629
        } /* while */
 
3630
}
 
3631
 
 
3632
static cond_expr_t *
 
3633
 define_cond_expr(__u32 expr_type, void* arg1, void* arg2)
 
3634
{
 
3635
        struct cond_expr *expr, *e1 = NULL, *e2;
 
3636
        cond_bool_datum_t *bool_var;
 
3637
        char *id;
 
3638
 
 
3639
        /* expressions are handled in the second pass */
 
3640
        if (pass == 1) {
 
3641
                if (expr_type == COND_BOOL) {
 
3642
                        while ((id = queue_remove(id_queue))) {
 
3643
                                free(id);
 
3644
                        }
 
3645
                }
 
3646
                return (cond_expr_t *)1; /* any non-NULL value */
 
3647
        }
 
3648
 
 
3649
        /* create a new expression struct */
 
3650
        expr = malloc(sizeof(struct cond_expr));
 
3651
        if (!expr) {
 
3652
                yyerror("out of memory");
 
3653
                return NULL;
 
3654
        }
 
3655
        memset(expr, 0, sizeof(cond_expr_t));
 
3656
        expr->expr_type = expr_type;
 
3657
 
 
3658
        /* create the type asked for */
 
3659
        switch (expr_type) {
 
3660
        case COND_NOT:
 
3661
                e1 = NULL;
 
3662
                e2 = (struct cond_expr *) arg1;
 
3663
                while (e2) {
 
3664
                        e1 = e2;
 
3665
                        e2 = e2->next;
 
3666
                }
 
3667
                if (!e1 || e1->next) {
 
3668
                        yyerror("illegal conditional NOT expression");
 
3669
                        free(expr);
 
3670
                        return NULL;
 
3671
                }
 
3672
                e1->next = expr;
 
3673
                return (struct cond_expr *) arg1;
 
3674
        case COND_AND:
 
3675
        case COND_OR:
 
3676
        case COND_XOR:
 
3677
        case COND_EQ:
 
3678
        case COND_NEQ:
 
3679
                e1 = NULL;
 
3680
                e2 = (struct cond_expr *) arg1;
 
3681
                while (e2) {
 
3682
                        e1 = e2;
 
3683
                        e2 = e2->next;
 
3684
                }
 
3685
                if (!e1 || e1->next) {
 
3686
                        yyerror("illegal left side of conditional binary op expression");
 
3687
                        free(expr);
 
3688
                        return NULL;
 
3689
                }
 
3690
                e1->next = (struct cond_expr *) arg2;
 
3691
 
 
3692
                e1 = NULL;
 
3693
                e2 = (struct cond_expr *) arg2;
 
3694
                while (e2) {
 
3695
                        e1 = e2;
 
3696
                        e2 = e2->next;
 
3697
                }
 
3698
                if (!e1 || e1->next) {
 
3699
                        yyerror("illegal right side of conditional binary op expression");
 
3700
                        free(expr);
 
3701
                        return NULL ;
 
3702
                }
 
3703
                e1->next = expr;
 
3704
                return (struct cond_expr *) arg1;
 
3705
        case COND_BOOL:
 
3706
                id = (char *) queue_remove(id_queue) ;
 
3707
                if (!id) {
 
3708
                        yyerror("bad conditional; expected boolean id");
 
3709
                        free(id);
 
3710
                        free(expr);
 
3711
                        return NULL;
 
3712
                }
 
3713
                bool_var = (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.table,
 
3714
                                                                (hashtab_key_t) id);
 
3715
                if (!bool_var) {
 
3716
                        sprintf(errormsg, "unknown boolean %s in conditional expression", id);
 
3717
                        yyerror(errormsg);
 
3718
                        free(expr);
 
3719
                        free(id);
 
3720
                        return NULL ;
 
3721
                }
 
3722
                expr->bool = bool_var->value;
 
3723
                free(id);
 
3724
                return expr;
 
3725
        default:
 
3726
                yyerror("illegal conditional expression");
 
3727
                return NULL;
 
3728
        }
 
3729
}
 
3730
 
 
3731
 
 
3732
static int set_user_roles(ebitmap_t *set,
 
3733
                          char *id)
 
3734
{
 
3735
        role_datum_t *r;
 
3736
        unsigned int i;
 
3737
 
 
3738
        if (strcmp(id, "*") == 0) {
 
3739
                /* set all roles */
 
3740
                for (i = 0; i < policydbp->p_roles.nprim; i++) 
 
3741
                        ebitmap_set_bit(set, i, TRUE);
 
3742
                free(id);
 
3743
                return 0;
 
3744
        }
 
3745
 
 
3746
        if (strcmp(id, "~") == 0) {
 
3747
                /* complement the set */
 
3748
                for (i = 0; i < policydbp->p_roles.nprim; i++) {
 
3749
                        if (ebitmap_get_bit(set, i))
 
3750
                                ebitmap_set_bit(set, i, FALSE);
 
3751
                        else 
 
3752
                                ebitmap_set_bit(set, i, TRUE);
 
3753
                }
 
3754
                free(id);
 
3755
                return 0;
 
3756
        }
 
3757
 
 
3758
        r = hashtab_search(policydbp->p_roles.table, id);
 
3759
        if (!r) {
 
3760
                sprintf(errormsg, "unknown role %s", id);
 
3761
                yyerror(errormsg);
 
3762
                free(id);
 
3763
                return -1;
 
3764
        }
 
3765
 
 
3766
        /* set the role and every role it dominates */
 
3767
        for (i = ebitmap_startbit(&r->dominates); i < ebitmap_length(&r->dominates); i++) {
 
3768
                if (ebitmap_get_bit(&r->dominates, i))
 
3769
                        ebitmap_set_bit(set, i, TRUE);
 
3770
        }
 
3771
        free(id);
 
3772
        return 0;
 
3773
}
 
3774
 
 
3775
 
 
3776
static int define_user(void)
 
3777
{
 
3778
        char *id;
 
3779
        user_datum_t *usrdatum;
 
3780
        int ret;
 
3781
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
3782
        mls_range_list_t *rnode;
 
3783
        level_datum_t *levdatum;
 
3784
        cat_datum_t *catdatum;
 
3785
        int relation, l;
 
3786
        char *levid;
 
3787
#endif
 
3788
 
 
3789
        if (pass == 1) {
 
3790
                while ((id = queue_remove(id_queue))) 
 
3791
                        free(id);
 
3792
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
3793
                while ((id = queue_remove(id_queue))) { 
 
3794
                        free(id);
 
3795
                        for (l = 0; l < 2; l++) {
 
3796
                                while ((id = queue_remove(id_queue))) { 
 
3797
                                        free(id);
 
3798
                                }
 
3799
                        }
 
3800
                }
 
3801
#endif
 
3802
                return 0;
 
3803
        }
 
3804
 
 
3805
        id = (char *) queue_remove(id_queue);
 
3806
        if (!id) {
 
3807
                yyerror("no user name for user definition?");
 
3808
                return -1;
 
3809
        }
 
3810
        usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
 
3811
                                                   (hashtab_key_t) id);
 
3812
        if (!usrdatum) {
 
3813
                usrdatum = (user_datum_t *) malloc(sizeof(user_datum_t));
 
3814
                if (!usrdatum) {
 
3815
                        yyerror("out of memory");
 
3816
                        free(id);
 
3817
                        return -1;
 
3818
                }
 
3819
                memset(usrdatum, 0, sizeof(user_datum_t));
 
3820
                usrdatum->value = ++policydbp->p_users.nprim;
 
3821
                ebitmap_init(&usrdatum->roles);
 
3822
                ret = hashtab_insert(policydbp->p_users.table,
 
3823
                                     (hashtab_key_t) id, (hashtab_datum_t) usrdatum);
 
3824
                if (ret) {
 
3825
                        yyerror("hash table overflow");
 
3826
                        free(usrdatum);
 
3827
                        free(id);
 
3828
                        return -1;
 
3829
                }
 
3830
        } else
 
3831
                free(id);
 
3832
 
 
3833
        while ((id = queue_remove(id_queue))) {
 
3834
                if (set_user_roles(&usrdatum->roles, id))
 
3835
                        continue;
 
3836
        }
 
3837
 
 
3838
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
3839
        id = queue_remove(id_queue);
 
3840
        if (!id) {
 
3841
                rnode = (mls_range_list_t *) malloc(sizeof(mls_range_list_t));
 
3842
                if (!rnode) {
 
3843
                        yyerror("out of memory");
 
3844
                        free(id);
 
3845
                        return -1;
 
3846
                }
 
3847
                memset(rnode, 0, sizeof(mls_range_list_t));
 
3848
                levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
 
3849
                                                            (hashtab_key_t) "unclassified");
 
3850
                if (!levdatum) {
 
3851
                        yyerror("no range for user");
 
3852
                        return -1;
 
3853
                }
 
3854
                rnode->range.level[0].sens = levdatum->level->sens;
 
3855
                rnode->range.level[1].sens = levdatum->level->sens;
 
3856
                rnode->next = usrdatum->ranges;
 
3857
                usrdatum->ranges = rnode;
 
3858
                goto skip_mls;
 
3859
        } 
 
3860
        do {
 
3861
                rnode = (mls_range_list_t *) malloc(sizeof(mls_range_list_t));
 
3862
                if (!rnode) {
 
3863
                        yyerror("out of memory");
 
3864
                        free(id);
 
3865
                        return -1;
 
3866
                }
 
3867
                memset(rnode, 0, sizeof(mls_range_list_t));
 
3868
 
 
3869
                for (l = 0; l < 2; l++) {
 
3870
                        levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
 
3871
                                                     (hashtab_key_t) id);
 
3872
                        if (!levdatum) {
 
3873
                                sprintf(errormsg, "unknown sensitivity %s used in user range definition", id);
 
3874
                                yyerror(errormsg);
 
3875
                                free(rnode);
 
3876
                                free(id);
 
3877
                                continue;
 
3878
                        }
 
3879
                        rnode->range.level[l].sens = levdatum->level->sens;
 
3880
                        ebitmap_init(&rnode->range.level[l].cat);
 
3881
 
 
3882
                        levid = id;
 
3883
 
 
3884
                        while ((id = queue_remove(id_queue))) {
 
3885
                                catdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
 
3886
                                                     (hashtab_key_t) id);
 
3887
                                if (!catdatum) {
 
3888
                                        sprintf(errormsg, "unknown category %s used in user range definition", id);
 
3889
                                        yyerror(errormsg);
 
3890
                                        free(id);
 
3891
                                        continue;
 
3892
                                }
 
3893
                                if (!(ebitmap_get_bit(&levdatum->level->cat, catdatum->value - 1))) {
 
3894
                                        sprintf(errormsg, "category %s cannot be associated with level %s", id, levid);
 
3895
                                        yyerror(errormsg);
 
3896
                                        free(id);
 
3897
                                        continue;
 
3898
                                }
 
3899
                                if (ebitmap_set_bit(&rnode->range.level[l].cat, catdatum->value - 1, TRUE)) {
 
3900
                                        yyerror("out of memory");
 
3901
                                        free(id);
 
3902
                                        free(levid);
 
3903
                                        ebitmap_destroy(&rnode->range.level[l].cat);
 
3904
                                        free(rnode);
 
3905
                                        return -1;
 
3906
                                }
 
3907
 
 
3908
                                /*
 
3909
                                 * no need to keep category name
 
3910
                                 */
 
3911
                                free(id);
 
3912
                        }
 
3913
 
 
3914
                        /*
 
3915
                         * no need to keep sensitivity name
 
3916
                         */
 
3917
                        free(levid);
 
3918
 
 
3919
                        id = queue_remove(id_queue);
 
3920
                        if (!id)
 
3921
                                break;
 
3922
                }
 
3923
 
 
3924
                if (l == 0) {
 
3925
                        rnode->range.level[1].sens = rnode->range.level[0].sens;
 
3926
                        if (ebitmap_cpy(&rnode->range.level[1].cat, &rnode->range.level[0].cat)) {
 
3927
                                yyerror("out of memory");
 
3928
                                free(id);
 
3929
                                ebitmap_destroy(&rnode->range.level[0].cat);
 
3930
                                free(rnode);
 
3931
                                return -1;
 
3932
                        }
 
3933
                }
 
3934
                relation = mls_level_relation(rnode->range.level[1], rnode->range.level[0]);
 
3935
                if (!(relation & (MLS_RELATION_DOM | MLS_RELATION_EQ))) {
 
3936
                        /* high does not dominate low */
 
3937
                        yyerror("high does not dominate low");
 
3938
                        ebitmap_destroy(&rnode->range.level[0].cat);
 
3939
                        ebitmap_destroy(&rnode->range.level[1].cat);
 
3940
                        free(rnode);
 
3941
                        return -1;
 
3942
                }
 
3943
                rnode->next = usrdatum->ranges;
 
3944
                usrdatum->ranges = rnode;
 
3945
        } while ((id = queue_remove(id_queue)));
 
3946
skip_mls:
 
3947
#endif
 
3948
 
 
3949
        return 0;
 
3950
}
 
3951
 
 
3952
 
 
3953
static int parse_security_context(context_struct_t * c)
 
3954
{
 
3955
        char *id;
 
3956
        role_datum_t *role;
 
3957
        type_datum_t *typdatum;
 
3958
        user_datum_t *usrdatum;
 
3959
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
3960
        char *levid;
 
3961
        level_datum_t *levdatum;
 
3962
        cat_datum_t *catdatum;
 
3963
        int l;
 
3964
#endif
 
3965
 
 
3966
        if (pass == 1) {
 
3967
                id = queue_remove(id_queue); free(id); /* user  */
 
3968
                id = queue_remove(id_queue); free(id); /* role  */
 
3969
                id = queue_remove(id_queue); free(id); /* type  */
 
3970
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
3971
                id = queue_remove(id_queue); free(id); 
 
3972
                for (l = 0; l < 2; l++) {
 
3973
                        while ((id = queue_remove(id_queue))) {
 
3974
                                free(id);
 
3975
                        }
 
3976
                }
 
3977
#endif 
 
3978
                return 0;
 
3979
        }
 
3980
 
 
3981
        context_init(c);
 
3982
 
 
3983
        /* extract the user */
 
3984
        id = queue_remove(id_queue);
 
3985
        if (!id) {
 
3986
                yyerror("no effective user?");
 
3987
                goto bad;
 
3988
        }
 
3989
        usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
 
3990
                                                   (hashtab_key_t) id);
 
3991
        if (!usrdatum) {
 
3992
                sprintf(errormsg, "user %s is not defined", id);
 
3993
                yyerror(errormsg);
 
3994
                free(id);
 
3995
                goto bad;
 
3996
        }
 
3997
        c->user = usrdatum->value;
 
3998
 
 
3999
        /* no need to keep the user name */
 
4000
        free(id);
 
4001
 
 
4002
        /* extract the role */
 
4003
        id = (char *) queue_remove(id_queue);
 
4004
        if (!id) {
 
4005
                yyerror("no role name for sid context definition?");
 
4006
                return -1;
 
4007
        }
 
4008
        role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
 
4009
                                               (hashtab_key_t) id);
 
4010
        if (!role) {
 
4011
                sprintf(errormsg, "role %s is not defined", id);
 
4012
                yyerror(errormsg);
 
4013
                free(id);
 
4014
                return -1;
 
4015
        }
 
4016
        c->role = role->value;
 
4017
 
 
4018
        /* no need to keep the role name */
 
4019
        free(id);
 
4020
 
 
4021
 
 
4022
        /* extract the type */
 
4023
        id = (char *) queue_remove(id_queue);
 
4024
        if (!id) {
 
4025
                yyerror("no type name for sid context definition?");
 
4026
                return -1;
 
4027
        }
 
4028
        typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
 
4029
                                                   (hashtab_key_t) id);
 
4030
        if (!typdatum || typdatum->isattr) {
 
4031
                sprintf(errormsg, "type %s is not defined", id);
 
4032
                yyerror(errormsg);
 
4033
                free(id);
 
4034
                return -1;
 
4035
        }
 
4036
        c->type = typdatum->value;
 
4037
 
 
4038
        /* no need to keep the type name */
 
4039
        free(id);
 
4040
 
 
4041
#ifdef CONFIG_SECURITY_SELINUX_MLS
 
4042
        /* extract the low sensitivity */
 
4043
        id = (char *) queue_head(id_queue);
 
4044
        if (!id || strcmp(id, "system_u") == 0 /* hack */) {
 
4045
                /* No MLS component to the security context.  Try
 
4046
                   to use a default 'unclassified' value. */
 
4047
                levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
 
4048
                                                            (hashtab_key_t) "unclassified");
 
4049
                if (!levdatum) {
 
4050
                        yyerror("no sensitivity name for sid context definition?");
 
4051
                        return -1;
 
4052
                }
 
4053
                c->range.level[0].sens = levdatum->level->sens;
 
4054
                c->range.level[1].sens = levdatum->level->sens;
 
4055
                goto skip_mls;
 
4056
        }
 
4057
 
 
4058
        id = (char *) queue_remove(id_queue);
 
4059
        for (l = 0; l < 2; l++) {
 
4060
                levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
 
4061
                                                     (hashtab_key_t) id);
 
4062
                if (!levdatum) {
 
4063
                        sprintf(errormsg, "Sensitivity %s is not defined", id);
 
4064
                        yyerror(errormsg);
 
4065
                        free(id);
 
4066
                        return -1;
 
4067
                }
 
4068
                c->range.level[l].sens = levdatum->level->sens;
 
4069
 
 
4070
                /* extract low category set */
 
4071
                levid = id;
 
4072
                while ((id = queue_remove(id_queue))) {
 
4073
                        catdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
 
4074
                                                     (hashtab_key_t) id);
 
4075
                        if (!catdatum) {
 
4076
                                sprintf(errormsg, "unknown category %s used in initial sid context", id);
 
4077
                                yyerror(errormsg);
 
4078
                                free(levid);
 
4079
                                free(id);
 
4080
                                goto bad;
 
4081
                        }
 
4082
                        if (ebitmap_set_bit(&c->range.level[l].cat,
 
4083
                                             catdatum->value - 1, TRUE)) {
 
4084
                                yyerror("out of memory");
 
4085
                                free(levid);
 
4086
                                free(id);
 
4087
                                goto bad;
 
4088
                        }
 
4089
                        /* no need to keep category name */
 
4090
                        free(id);
 
4091
                }
 
4092
 
 
4093
                /* no need to keep the sensitivity name */
 
4094
                free(levid);
 
4095
 
 
4096
                /* extract high sensitivity */
 
4097
                id = (char *) queue_remove(id_queue);
 
4098
                if (!id)
 
4099
                        break;
 
4100
        }
 
4101
 
 
4102
        if (l == 0) {
 
4103
                c->range.level[1].sens = c->range.level[0].sens;
 
4104
                if (ebitmap_cpy(&c->range.level[1].cat, &c->range.level[0].cat)) {
 
4105
 
 
4106
                        yyerror("out of memory");
 
4107
                        goto bad;
 
4108
                }
 
4109
        }
 
4110
skip_mls:
 
4111
#endif
 
4112
 
 
4113
        if (!policydb_context_isvalid(policydbp, c)) {
 
4114
                yyerror("invalid security context");
 
4115
                goto bad;
 
4116
        }
 
4117
        return 0;
 
4118
 
 
4119
      bad:
 
4120
        context_destroy(c);
 
4121
 
 
4122
        return -1;
 
4123
}
 
4124
 
 
4125
 
 
4126
static int define_initial_sid_context(void)
 
4127
{
 
4128
        char *id;
 
4129
        ocontext_t *c, *head;
 
4130
 
 
4131
        if (pass == 1) {
 
4132
                id = (char *) queue_remove(id_queue); free(id);
 
4133
                parse_security_context(NULL);
 
4134
                return 0;
 
4135
        }
 
4136
 
 
4137
        id = (char *) queue_remove(id_queue);
 
4138
        if (!id) {
 
4139
                yyerror("no sid name for SID context definition?");
 
4140
                return -1;
 
4141
        }
 
4142
        head = policydbp->ocontexts[OCON_ISID];
 
4143
        for (c = head; c; c = c->next) {
 
4144
                if (!strcmp(id, c->u.name))
 
4145
                        break;
 
4146
        }
 
4147
 
 
4148
        if (!c) {
 
4149
                sprintf(errormsg, "SID %s is not defined", id);
 
4150
                yyerror(errormsg);
 
4151
                free(id);
 
4152
                return -1;
 
4153
        }
 
4154
        if (c->context[0].user) {
 
4155
                sprintf(errormsg, "The context for SID %s is multiply defined", id);
 
4156
                yyerror(errormsg);
 
4157
                free(id);
 
4158
                return -1;
 
4159
        }
 
4160
        /* no need to keep the sid name */
 
4161
        free(id);
 
4162
 
 
4163
        if (parse_security_context(&c->context[0]))
 
4164
                return -1;
 
4165
 
 
4166
        return 0;
 
4167
}
 
4168
 
 
4169
static int define_fs_context(unsigned int major, unsigned int minor)
 
4170
{
 
4171
        ocontext_t *newc, *c, *head;
 
4172
 
 
4173
        if (pass == 1) {
 
4174
                parse_security_context(NULL);
 
4175
                parse_security_context(NULL);
 
4176
                return 0;
 
4177
        }
 
4178
 
 
4179
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
 
4180
        if (!newc) {
 
4181
                yyerror("out of memory");
 
4182
                return -1;
 
4183
        }
 
4184
        memset(newc, 0, sizeof(ocontext_t));
 
4185
 
 
4186
        newc->u.name = (char *) malloc(6);
 
4187
        if (!newc->u.name) {
 
4188
                yyerror("out of memory");
 
4189
                free(newc);
 
4190
                return -1;
 
4191
        }
 
4192
        sprintf(newc->u.name, "%02x:%02x", major, minor);
 
4193
 
 
4194
        if (parse_security_context(&newc->context[0])) {
 
4195
                free(newc->u.name);
 
4196
                free(newc);
 
4197
                return -1;
 
4198
        }
 
4199
        if (parse_security_context(&newc->context[1])) {
 
4200
                context_destroy(&newc->context[0]);
 
4201
                free(newc->u.name);
 
4202
                free(newc);
 
4203
                return -1;
 
4204
        }
 
4205
        head = policydbp->ocontexts[OCON_FS];
 
4206
 
 
4207
        for (c = head; c; c = c->next) {
 
4208
                if (!strcmp(newc->u.name, c->u.name)) {
 
4209
                        sprintf(errormsg, "duplicate entry for file system %s", newc->u.name);
 
4210
                        yyerror(errormsg);
 
4211
                        context_destroy(&newc->context[0]);
 
4212
                        context_destroy(&newc->context[1]);
 
4213
                        free(newc->u.name);
 
4214
                        free(newc);
 
4215
                        return -1;
 
4216
                }
 
4217
        }
 
4218
 
 
4219
        newc->next = head;
 
4220
        policydbp->ocontexts[OCON_FS] = newc;
 
4221
 
 
4222
        return 0;
 
4223
}
 
4224
 
 
4225
static int define_port_context(unsigned int low, unsigned int high)
 
4226
{
 
4227
        ocontext_t *newc;
 
4228
        char *id;
 
4229
 
 
4230
        if (pass == 1) {
 
4231
                id = (char *) queue_remove(id_queue); free(id);
 
4232
                parse_security_context(NULL);
 
4233
                return 0;
 
4234
        }
 
4235
 
 
4236
        newc = malloc(sizeof(ocontext_t));
 
4237
        if (!newc) {
 
4238
                yyerror("out of memory");
 
4239
                return -1;
 
4240
        }
 
4241
        memset(newc, 0, sizeof(ocontext_t));
 
4242
 
 
4243
        id = (char *) queue_remove(id_queue);
 
4244
        if (!id) {
 
4245
                free(newc);
 
4246
                return -1;
 
4247
        }
 
4248
        if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
 
4249
                newc->u.port.protocol = IPPROTO_TCP;
 
4250
        } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
 
4251
                newc->u.port.protocol = IPPROTO_UDP;
 
4252
        } else {
 
4253
                sprintf(errormsg, "unrecognized protocol %s", id);
 
4254
                yyerror(errormsg);
 
4255
                free(newc);
 
4256
                return -1;
 
4257
        }
 
4258
 
 
4259
        newc->u.port.low_port = low;
 
4260
        newc->u.port.high_port = high;
 
4261
 
 
4262
        if (parse_security_context(&newc->context[0])) {
 
4263
                free(newc);
 
4264
                return -1;
 
4265
        }
 
4266
        newc->next = policydbp->ocontexts[OCON_PORT];
 
4267
        policydbp->ocontexts[OCON_PORT] = newc;
 
4268
        return 0;
 
4269
}
 
4270
 
 
4271
static int define_netif_context(void)
 
4272
{
 
4273
        ocontext_t *newc, *c, *head;
 
4274
 
 
4275
        if (pass == 1) {
 
4276
                free(queue_remove(id_queue));
 
4277
                parse_security_context(NULL);
 
4278
                parse_security_context(NULL);
 
4279
                return 0;
 
4280
        }
 
4281
 
 
4282
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
 
4283
        if (!newc) {
 
4284
                yyerror("out of memory");
 
4285
                return -1;
 
4286
        }
 
4287
        memset(newc, 0, sizeof(ocontext_t));
 
4288
 
 
4289
        newc->u.name = (char *) queue_remove(id_queue);
 
4290
        if (!newc->u.name) {
 
4291
                free(newc);
 
4292
                return -1;
 
4293
        }
 
4294
        if (parse_security_context(&newc->context[0])) {
 
4295
                free(newc->u.name);
 
4296
                free(newc);
 
4297
                return -1;
 
4298
        }
 
4299
        if (parse_security_context(&newc->context[1])) {
 
4300
                context_destroy(&newc->context[0]);
 
4301
                free(newc->u.name);
 
4302
                free(newc);
 
4303
                return -1;
 
4304
        }
 
4305
        head = policydbp->ocontexts[OCON_NETIF];
 
4306
 
 
4307
        for (c = head; c; c = c->next) {
 
4308
                if (!strcmp(newc->u.name, c->u.name)) {
 
4309
                        sprintf(errormsg, "duplicate entry for network interface %s", newc->u.name);
 
4310
                        yyerror(errormsg);
 
4311
                        context_destroy(&newc->context[0]);
 
4312
                        context_destroy(&newc->context[1]);
 
4313
                        free(newc->u.name);
 
4314
                        free(newc);
 
4315
                        return -1;
 
4316
                }
 
4317
        }
 
4318
 
 
4319
        newc->next = head;
 
4320
        policydbp->ocontexts[OCON_NETIF] = newc;
 
4321
        return 0;
 
4322
}
 
4323
 
 
4324
static int define_ipv4_node_context(unsigned int addr, unsigned int mask)
 
4325
{
 
4326
        ocontext_t *newc, *c, *l, *head;
 
4327
 
 
4328
        if (pass == 1) {
 
4329
                parse_security_context(NULL);
 
4330
                return 0;
 
4331
        }
 
4332
 
 
4333
        newc = malloc(sizeof(ocontext_t));
 
4334
        if (!newc) {
 
4335
                yyerror("out of memory");
 
4336
                return -1;
 
4337
        }
 
4338
        memset(newc, 0, sizeof(ocontext_t));
 
4339
 
 
4340
        newc->u.node.addr = addr;
 
4341
        newc->u.node.mask = mask;
 
4342
 
 
4343
        if (parse_security_context(&newc->context[0])) {
 
4344
                free(newc);
 
4345
                return -1;
 
4346
        }
 
4347
        /* Place this at the end of the list, to retain
 
4348
           the matching order specified in the configuration. */
 
4349
        head = policydbp->ocontexts[OCON_NODE];
 
4350
        for (l = NULL, c = head; c; l = c, c = c->next);
 
4351
 
 
4352
        if (l)
 
4353
                l->next = newc;
 
4354
        else
 
4355
                policydbp->ocontexts[OCON_NODE] = newc;
 
4356
 
 
4357
        return 0;
 
4358
}
 
4359
 
 
4360
static int define_ipv6_node_context(void)
 
4361
{
 
4362
        char *id;
 
4363
        int rc = 0;
 
4364
        struct in6_addr addr, mask;
 
4365
        ocontext_t *newc, *c, *l, *head;
 
4366
        
 
4367
        if (pass == 1) {
 
4368
                free(queue_remove(id_queue));
 
4369
                free(queue_remove(id_queue));
 
4370
                parse_security_context(NULL);
 
4371
                goto out;
 
4372
        }
 
4373
        
 
4374
        id = queue_remove(id_queue);
 
4375
        if (!id) {
 
4376
                yyerror("failed to read ipv6 address");
 
4377
                rc = -1;
 
4378
                goto out;
 
4379
        }
 
4380
 
 
4381
        rc = inet_pton(AF_INET6, id, &addr);
 
4382
        free (id);
 
4383
        if (rc < 1) {
 
4384
                yyerror("failed to parse ipv6 address");
 
4385
                if (rc == 0)
 
4386
                        rc = -1;
 
4387
                goto out;
 
4388
        }
 
4389
 
 
4390
        id = queue_remove(id_queue);
 
4391
        if (!id) {
 
4392
                yyerror("failed to read ipv6 address");
 
4393
                rc = -1;
 
4394
                goto out;
 
4395
        }
 
4396
 
 
4397
        rc = inet_pton(AF_INET6, id, &mask);
 
4398
        free(id);
 
4399
        if (rc < 1) {
 
4400
                yyerror("failed to parse ipv6 mask");
 
4401
                if (rc == 0)
 
4402
                        rc = -1;
 
4403
                goto out;
 
4404
        }
 
4405
        
 
4406
        newc = malloc(sizeof(ocontext_t));
 
4407
        if (!newc) {
 
4408
                yyerror("out of memory");
 
4409
                rc = -1;
 
4410
                goto out;
 
4411
        }
 
4412
 
 
4413
        memset(newc, 0, sizeof(ocontext_t));
 
4414
        memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
 
4415
        memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
 
4416
 
 
4417
        if (parse_security_context(&newc->context[0])) {
 
4418
                free(newc);
 
4419
                rc = -1;
 
4420
                goto out;
 
4421
        }
 
4422
 
 
4423
        /* Place this at the end of the list, to retain
 
4424
           the matching order specified in the configuration. */
 
4425
        head = policydbp->ocontexts[OCON_NODE6];
 
4426
        for (l = NULL, c = head; c; l = c, c = c->next);
 
4427
 
 
4428
        if (l)
 
4429
                l->next = newc;
 
4430
        else
 
4431
                policydbp->ocontexts[OCON_NODE6] = newc;
 
4432
 
 
4433
        rc = 0;
 
4434
out:
 
4435
        return rc;
 
4436
}
 
4437
 
 
4438
static int define_fs_use(int behavior)
 
4439
{
 
4440
        ocontext_t *newc, *c, *head;
 
4441
 
 
4442
        if (pass == 1) {
 
4443
                free(queue_remove(id_queue));
 
4444
                parse_security_context(NULL);
 
4445
                return 0;
 
4446
        }
 
4447
 
 
4448
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
 
4449
        if (!newc) {
 
4450
                yyerror("out of memory");
 
4451
                return -1;
 
4452
        }
 
4453
        memset(newc, 0, sizeof(ocontext_t));
 
4454
 
 
4455
        newc->u.name = (char *) queue_remove(id_queue);
 
4456
        if (!newc->u.name) {
 
4457
                free(newc);
 
4458
                return -1;
 
4459
        }
 
4460
        newc->v.behavior = behavior;
 
4461
        if (parse_security_context(&newc->context[0])) {
 
4462
                free(newc->u.name);
 
4463
                free(newc);
 
4464
                return -1;
 
4465
        }
 
4466
 
 
4467
        head = policydbp->ocontexts[OCON_FSUSE];
 
4468
 
 
4469
        for (c = head; c; c = c->next) {
 
4470
                if (!strcmp(newc->u.name, c->u.name)) {
 
4471
                        sprintf(errormsg, "duplicate fs_use entry for filesystem type %s", newc->u.name);
 
4472
                        yyerror(errormsg);
 
4473
                        context_destroy(&newc->context[0]);
 
4474
                        free(newc->u.name);
 
4475
                        free(newc);
 
4476
                        return -1;
 
4477
                }
 
4478
        }
 
4479
 
 
4480
        newc->next = head;
 
4481
        policydbp->ocontexts[OCON_FSUSE] = newc;
 
4482
        return 0;
 
4483
}
 
4484
 
 
4485
static int define_genfs_context_helper(char *fstype, int has_type)
 
4486
{
 
4487
        struct genfs *genfs_p, *genfs, *newgenfs;
 
4488
        ocontext_t *newc, *c, *head, *p;
 
4489
        char *type = NULL;
 
4490
        int len, len2;
 
4491
 
 
4492
        if (pass == 1) {
 
4493
                free(fstype);
 
4494
                free(queue_remove(id_queue));
 
4495
                if (has_type)
 
4496
                        free(queue_remove(id_queue));
 
4497
                parse_security_context(NULL);
 
4498
                return 0;
 
4499
        }
 
4500
 
 
4501
        for (genfs_p = NULL, genfs = policydbp->genfs; 
 
4502
             genfs; genfs_p = genfs, genfs = genfs->next) {
 
4503
                if (strcmp(fstype, genfs->fstype) <= 0)
 
4504
                        break;
 
4505
        }
 
4506
 
 
4507
        if (!genfs || strcmp(fstype, genfs->fstype)) {
 
4508
                newgenfs = malloc(sizeof(struct genfs));
 
4509
                if (!newgenfs) {
 
4510
                        yyerror("out of memory");
 
4511
                        return -1;
 
4512
                }
 
4513
                memset(newgenfs, 0, sizeof(struct genfs));
 
4514
                newgenfs->fstype = fstype;
 
4515
                newgenfs->next = genfs;
 
4516
                if (genfs_p) 
 
4517
                        genfs_p->next = newgenfs;
 
4518
                else
 
4519
                        policydbp->genfs = newgenfs;
 
4520
                genfs = newgenfs;
 
4521
        }
 
4522
 
 
4523
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
 
4524
        if (!newc) {
 
4525
                yyerror("out of memory");
 
4526
                return -1;
 
4527
        }
 
4528
        memset(newc, 0, sizeof(ocontext_t));
 
4529
 
 
4530
        newc->u.name = (char *) queue_remove(id_queue);
 
4531
        if (!newc->u.name) 
 
4532
                goto fail;
 
4533
        if (has_type) {
 
4534
                type = (char *) queue_remove(id_queue);
 
4535
                if (!type) 
 
4536
                        goto fail;
 
4537
                if (type[1] != 0) {
 
4538
                        sprintf(errormsg, "invalid type %s", type);
 
4539
                        yyerror(errormsg);
 
4540
                        goto fail;
 
4541
                }
 
4542
                switch (type[0]) {
 
4543
                case 'b':
 
4544
                        newc->v.sclass = SECCLASS_BLK_FILE;
 
4545
                        break;
 
4546
                case 'c':
 
4547
                        newc->v.sclass = SECCLASS_CHR_FILE;
 
4548
                        break;
 
4549
                case 'd':
 
4550
                        newc->v.sclass = SECCLASS_DIR;
 
4551
                        break;
 
4552
                case 'p':
 
4553
                        newc->v.sclass = SECCLASS_FIFO_FILE;
 
4554
                        break;
 
4555
                case 'l':
 
4556
                        newc->v.sclass = SECCLASS_LNK_FILE;
 
4557
                        break;
 
4558
                case 's':
 
4559
                        newc->v.sclass = SECCLASS_SOCK_FILE;
 
4560
                        break;
 
4561
                case '-':
 
4562
                        newc->v.sclass = SECCLASS_FILE;
 
4563
                        break;
 
4564
                default:
 
4565
                        sprintf(errormsg, "invalid type %s", type);
 
4566
                        yyerror(errormsg);
 
4567
                        goto fail;
 
4568
                }
 
4569
        }
 
4570
        if (parse_security_context(&newc->context[0])) 
 
4571
                goto fail;
 
4572
 
 
4573
        head = genfs->head;
 
4574
 
 
4575
        for (p = NULL, c = head; c; p = c, c = c->next) {
 
4576
                if (!strcmp(newc->u.name, c->u.name) && 
 
4577
                    (!newc->v.sclass || !c->v.sclass || newc->v.sclass == c->v.sclass)) {
 
4578
                        sprintf(errormsg, "duplicate entry for genfs entry (%s, %s)", fstype, newc->u.name);
 
4579
                        yyerror(errormsg);
 
4580
                        goto fail;
 
4581
                }
 
4582
                len = strlen(newc->u.name);
 
4583
                len2 = strlen(c->u.name);
 
4584
                if (len > len2)
 
4585
                        break;
 
4586
        }
 
4587
 
 
4588
        newc->next = c;
 
4589
        if (p) 
 
4590
                p->next = newc;
 
4591
        else
 
4592
                genfs->head = newc;
 
4593
        return 0;
 
4594
fail:
 
4595
        if (type)
 
4596
                free(type);
 
4597
        context_destroy(&newc->context[0]);
 
4598
        if (fstype)
 
4599
                free(fstype);
 
4600
        if (newc->u.name)
 
4601
                free(newc->u.name);
 
4602
        free(newc);
 
4603
        return -1;
 
4604
}
 
4605
 
 
4606
static int define_genfs_context(int has_type)
 
4607
{
 
4608
        return define_genfs_context_helper(queue_remove(id_queue), has_type);
 
4609
}
 
4610
 
 
4611
/* FLASK */
 
4612
 
 
4613