~ubuntu-branches/ubuntu/maverick/checkpolicy/maverick

« back to all changes in this revision

Viewing changes to policy_define.c

  • Committer: Bazaar Package Importer
  • Author(s): Russell Coker
  • Date: 2008-07-12 00:16:59 UTC
  • mfrom: (1.1.10 upstream) (2.1.3 lenny)
  • Revision ID: james.westby@ubuntu.com-20080712001659-vh8tlttve9vi3cc8
Tags: 2.0.16-1
* Non-maintainer upload.
* New upstream version needed for latest policy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 
 
3
 */
 
4
 
 
5
/*
 
6
 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
 
7
 *
 
8
 *      Support for enhanced MLS infrastructure.
 
9
 *
 
10
 * Updated: David Caplan, <dac@tresys.com>
 
11
 *
 
12
 *      Added conditional policy language extensions
 
13
 *
 
14
 * Updated: Joshua Brindle <jbrindle@tresys.com>
 
15
 *          Karl MacMillan <kmacmillan@mentalrootkit.com>
 
16
 *          Jason Tang     <jtang@tresys.com>
 
17
 *
 
18
 *      Added support for binary policy modules
 
19
 *
 
20
 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
 
21
 * Copyright (C) 2003 - 2008 Tresys Technology, LLC
 
22
 * Copyright (C) 2007 Red Hat Inc.
 
23
 *      This program is free software; you can redistribute it and/or modify
 
24
 *      it under the terms of the GNU General Public License as published by
 
25
 *      the Free Software Foundation, version 2.
 
26
 */
 
27
 
 
28
/* FLASK */
 
29
 
 
30
#include <sys/types.h>
 
31
#include <assert.h>
 
32
#include <stdarg.h>
 
33
#include <stdint.h>
 
34
#include <stdio.h>
 
35
#include <stdlib.h>
 
36
#include <string.h>
 
37
#include <sys/socket.h>
 
38
#include <netinet/in.h>
 
39
#include <arpa/inet.h>
 
40
#include <stdlib.h>
 
41
 
 
42
#include <sepol/policydb/expand.h>
 
43
#include <sepol/policydb/policydb.h>
 
44
#include <sepol/policydb/services.h>
 
45
#include <sepol/policydb/conditional.h>
 
46
#include <sepol/policydb/flask.h>
 
47
#include <sepol/policydb/hierarchy.h>
 
48
#include <sepol/policydb/polcaps.h>
 
49
#include "queue.h"
 
50
#include "checkpolicy.h"
 
51
#include "module_compiler.h"
 
52
#include "policy_define.h"
 
53
 
 
54
policydb_t *policydbp;
 
55
queue_t id_queue = 0;
 
56
unsigned int pass;
 
57
char *curfile = 0;
 
58
int mlspol = 0;
 
59
 
 
60
extern unsigned long policydb_lineno;
 
61
extern unsigned long source_lineno;
 
62
extern unsigned int policydb_errors;
 
63
 
 
64
extern int yywarn(char *msg);
 
65
extern int yyerror(char *msg);
 
66
 
 
67
#define ERRORMSG_LEN 255
 
68
static char errormsg[ERRORMSG_LEN + 1] = {0};
 
69
 
 
70
static int id_has_dot(char *id);
 
71
static int parse_security_context(context_struct_t *c);
 
72
 
 
73
/* initialize all of the state variables for the scanner/parser */
 
74
void init_parser(int pass_number)
 
75
{
 
76
        policydb_lineno = 1;
 
77
        source_lineno = 1;
 
78
        policydb_errors = 0;
 
79
        pass = pass_number;
 
80
}
 
81
 
 
82
void yyerror2(char *fmt, ...)
 
83
{
 
84
        va_list ap;
 
85
        va_start(ap, fmt);
 
86
        vsnprintf(errormsg, ERRORMSG_LEN, fmt, ap);
 
87
        yyerror(errormsg);
 
88
        va_end(ap);
 
89
}
 
90
 
 
91
int insert_separator(int push)
 
92
{
 
93
        int error;
 
94
 
 
95
        if (push)
 
96
                error = queue_push(id_queue, 0);
 
97
        else
 
98
                error = queue_insert(id_queue, 0);
 
99
 
 
100
        if (error) {
 
101
                yyerror("queue overflow");
 
102
                return -1;
 
103
        }
 
104
        return 0;
 
105
}
 
106
 
 
107
int insert_id(char *id, int push)
 
108
{
 
109
        char *newid = 0;
 
110
        int error;
 
111
 
 
112
        newid = (char *)malloc(strlen(id) + 1);
 
113
        if (!newid) {
 
114
                yyerror("out of memory");
 
115
                return -1;
 
116
        }
 
117
        strcpy(newid, id);
 
118
        if (push)
 
119
                error = queue_push(id_queue, (queue_element_t) newid);
 
120
        else
 
121
                error = queue_insert(id_queue, (queue_element_t) newid);
 
122
 
 
123
        if (error) {
 
124
                yyerror("queue overflow");
 
125
                free(newid);
 
126
                return -1;
 
127
        }
 
128
        return 0;
 
129
}
 
130
 
 
131
/* If the identifier has a dot within it and that its first character
 
132
   is not a dot then return 1, else return 0. */
 
133
static int id_has_dot(char *id)
 
134
{
 
135
        if (strchr(id, '.') >= id + 1) {
 
136
                return 1;
 
137
        }
 
138
        return 0;
 
139
}
 
140
 
 
141
int define_class(void)
 
142
{
 
143
        char *id = 0;
 
144
        class_datum_t *datum = 0;
 
145
        int ret;
 
146
        uint32_t value;
 
147
 
 
148
        if (pass == 2) {
 
149
                id = queue_remove(id_queue);
 
150
                free(id);
 
151
                return 0;
 
152
        }
 
153
 
 
154
        id = (char *)queue_remove(id_queue);
 
155
        if (!id) {
 
156
                yyerror("no class name for class definition?");
 
157
                return -1;
 
158
        }
 
159
        datum = (class_datum_t *) malloc(sizeof(class_datum_t));
 
160
        if (!datum) {
 
161
                yyerror("out of memory");
 
162
                goto bad;
 
163
        }
 
164
        memset(datum, 0, sizeof(class_datum_t));
 
165
        ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value);
 
166
        switch (ret) {
 
167
        case -3:{
 
168
                        yyerror("Out of memory!");
 
169
                        goto bad;
 
170
                }
 
171
        case -2:{
 
172
                        yyerror2("duplicate declaration of class %s", id);
 
173
                        goto bad;
 
174
                }
 
175
        case -1:{
 
176
                        yyerror("could not declare class here");
 
177
                        goto bad;
 
178
                }
 
179
        case 0:
 
180
        case 1:{
 
181
                        break;
 
182
                }
 
183
        default:{
 
184
                        assert(0);      /* should never get here */
 
185
                }
 
186
        }
 
187
        datum->s.value = value;
 
188
        return 0;
 
189
 
 
190
      bad:
 
191
        if (id)
 
192
                free(id);
 
193
        if (datum)
 
194
                free(datum);
 
195
        return -1;
 
196
}
 
197
 
 
198
int define_permissive(void)
 
199
{
 
200
        char *type = NULL;
 
201
        struct type_datum *t;
 
202
        int rc = 0;
 
203
 
 
204
        type = queue_remove(id_queue);
 
205
 
 
206
        if (!type) {
 
207
                yyerror2("forgot to include type in permissive definition?");
 
208
                rc = -1;
 
209
                goto out;
 
210
        }
 
211
 
 
212
        if (pass == 1)
 
213
                goto out;
 
214
 
 
215
        if (!is_id_in_scope(SYM_TYPES, type)) {
 
216
                yyerror2("type %s is not within scope", type);
 
217
                rc = -1;
 
218
                goto out;
 
219
        }
 
220
 
 
221
        t = hashtab_search(policydbp->p_types.table, type);
 
222
        if (!t) {
 
223
                yyerror2("type is not defined: %s", type);
 
224
                rc = -1;
 
225
                goto out;
 
226
        }
 
227
 
 
228
        if (t->flavor == TYPE_ATTRIB) {
 
229
                yyerror2("attributes may not be permissive: %s\n", type);
 
230
                rc = -1;
 
231
                goto out;
 
232
        }
 
233
 
 
234
        t->flags |= TYPE_FLAGS_PERMISSIVE;
 
235
 
 
236
out:
 
237
        free(type);
 
238
        return rc;
 
239
}
 
240
 
 
241
int define_polcap(void)
 
242
{
 
243
        char *id = 0;
 
244
        int capnum;
 
245
 
 
246
        if (pass == 2) {
 
247
                id = queue_remove(id_queue);
 
248
                free(id);
 
249
                return 0;
 
250
        }
 
251
 
 
252
        id = (char *)queue_remove(id_queue);
 
253
        if (!id) {
 
254
                yyerror("no capability name for policycap definition?");
 
255
                goto bad;
 
256
        }
 
257
 
 
258
        /* Check for valid cap name -> number mapping */
 
259
        capnum = sepol_polcap_getnum(id);
 
260
        if (capnum < 0) {
 
261
                yyerror2("invalid policy capability name %s", id);
 
262
                goto bad;
 
263
        }
 
264
 
 
265
        /* Store it */
 
266
        if (ebitmap_set_bit(&policydbp->policycaps, capnum, TRUE)) {
 
267
                yyerror("out of memory");
 
268
                goto bad;
 
269
        }
 
270
 
 
271
        free(id);
 
272
        return 0;
 
273
 
 
274
      bad:
 
275
        free(id);
 
276
        return -1;
 
277
}
 
278
 
 
279
int define_initial_sid(void)
 
280
{
 
281
        char *id = 0;
 
282
        ocontext_t *newc = 0, *c, *head;
 
283
 
 
284
        if (pass == 2) {
 
285
                id = queue_remove(id_queue);
 
286
                free(id);
 
287
                return 0;
 
288
        }
 
289
 
 
290
        id = (char *)queue_remove(id_queue);
 
291
        if (!id) {
 
292
                yyerror("no sid name for SID definition?");
 
293
                return -1;
 
294
        }
 
295
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
 
296
        if (!newc) {
 
297
                yyerror("out of memory");
 
298
                goto bad;
 
299
        }
 
300
        memset(newc, 0, sizeof(ocontext_t));
 
301
        newc->u.name = id;
 
302
        context_init(&newc->context[0]);
 
303
        head = policydbp->ocontexts[OCON_ISID];
 
304
 
 
305
        for (c = head; c; c = c->next) {
 
306
                if (!strcmp(newc->u.name, c->u.name)) {
 
307
                        yyerror2("duplicate initial SID %s", id);
 
308
                        goto bad;
 
309
                }
 
310
        }
 
311
 
 
312
        if (head) {
 
313
                newc->sid[0] = head->sid[0] + 1;
 
314
        } else {
 
315
                newc->sid[0] = 1;
 
316
        }
 
317
        newc->next = head;
 
318
        policydbp->ocontexts[OCON_ISID] = newc;
 
319
 
 
320
        return 0;
 
321
 
 
322
      bad:
 
323
        if (id)
 
324
                free(id);
 
325
        if (newc)
 
326
                free(newc);
 
327
        return -1;
 
328
}
 
329
 
 
330
int define_common_perms(void)
 
331
{
 
332
        char *id = 0, *perm = 0;
 
333
        common_datum_t *comdatum = 0;
 
334
        perm_datum_t *perdatum = 0;
 
335
        int ret;
 
336
 
 
337
        if (pass == 2) {
 
338
                while ((id = queue_remove(id_queue)))
 
339
                        free(id);
 
340
                return 0;
 
341
        }
 
342
 
 
343
        id = (char *)queue_remove(id_queue);
 
344
        if (!id) {
 
345
                yyerror("no common name for common perm definition?");
 
346
                return -1;
 
347
        }
 
348
        comdatum = hashtab_search(policydbp->p_commons.table, id);
 
349
        if (comdatum) {
 
350
                yyerror2("duplicate declaration for common %s\n", id);
 
351
                return -1;
 
352
        }
 
353
        comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
 
354
        if (!comdatum) {
 
355
                yyerror("out of memory");
 
356
                goto bad;
 
357
        }
 
358
        memset(comdatum, 0, sizeof(common_datum_t));
 
359
        ret = hashtab_insert(policydbp->p_commons.table,
 
360
                             (hashtab_key_t) id, (hashtab_datum_t) comdatum);
 
361
 
 
362
        if (ret == SEPOL_EEXIST) {
 
363
                yyerror("duplicate common definition");
 
364
                goto bad;
 
365
        }
 
366
        if (ret == SEPOL_ENOMEM) {
 
367
                yyerror("hash table overflow");
 
368
                goto bad;
 
369
        }
 
370
        comdatum->s.value = policydbp->p_commons.nprim + 1;
 
371
        if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
 
372
                yyerror("out of memory");
 
373
                goto bad;
 
374
        }
 
375
        policydbp->p_commons.nprim++;
 
376
        while ((perm = queue_remove(id_queue))) {
 
377
                perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
 
378
                if (!perdatum) {
 
379
                        yyerror("out of memory");
 
380
                        goto bad_perm;
 
381
                }
 
382
                memset(perdatum, 0, sizeof(perm_datum_t));
 
383
                perdatum->s.value = comdatum->permissions.nprim + 1;
 
384
 
 
385
                if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
 
386
                        yyerror
 
387
                            ("too many permissions to fit in an access vector");
 
388
                        goto bad_perm;
 
389
                }
 
390
                ret = hashtab_insert(comdatum->permissions.table,
 
391
                                     (hashtab_key_t) perm,
 
392
                                     (hashtab_datum_t) perdatum);
 
393
 
 
394
                if (ret == SEPOL_EEXIST) {
 
395
                        yyerror2("duplicate permission %s in common %s", perm,
 
396
                                 id);
 
397
                        goto bad_perm;
 
398
                }
 
399
                if (ret == SEPOL_ENOMEM) {
 
400
                        yyerror("hash table overflow");
 
401
                        goto bad_perm;
 
402
                }
 
403
                comdatum->permissions.nprim++;
 
404
        }
 
405
 
 
406
        return 0;
 
407
 
 
408
      bad:
 
409
        if (id)
 
410
                free(id);
 
411
        if (comdatum)
 
412
                free(comdatum);
 
413
        return -1;
 
414
 
 
415
      bad_perm:
 
416
        if (perm)
 
417
                free(perm);
 
418
        if (perdatum)
 
419
                free(perdatum);
 
420
        return -1;
 
421
}
 
422
 
 
423
int define_av_perms(int inherits)
 
424
{
 
425
        char *id;
 
426
        class_datum_t *cladatum;
 
427
        common_datum_t *comdatum;
 
428
        perm_datum_t *perdatum = 0, *perdatum2 = 0;
 
429
        int ret;
 
430
 
 
431
        if (pass == 2) {
 
432
                while ((id = queue_remove(id_queue)))
 
433
                        free(id);
 
434
                return 0;
 
435
        }
 
436
 
 
437
        id = (char *)queue_remove(id_queue);
 
438
        if (!id) {
 
439
                yyerror("no tclass name for av perm definition?");
 
440
                return -1;
 
441
        }
 
442
        cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
 
443
                                                    (hashtab_key_t) id);
 
444
        if (!cladatum) {
 
445
                yyerror2("class %s is not defined", id);
 
446
                goto bad;
 
447
        }
 
448
        free(id);
 
449
 
 
450
        if (cladatum->comdatum || cladatum->permissions.nprim) {
 
451
                yyerror("duplicate access vector definition");
 
452
                return -1;
 
453
        }
 
454
        if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) {
 
455
                yyerror("out of memory");
 
456
                return -1;
 
457
        }
 
458
        if (inherits) {
 
459
                id = (char *)queue_remove(id_queue);
 
460
                if (!id) {
 
461
                        yyerror
 
462
                            ("no inherits name for access vector definition?");
 
463
                        return -1;
 
464
                }
 
465
                comdatum =
 
466
                    (common_datum_t *) hashtab_search(policydbp->p_commons.
 
467
                                                      table,
 
468
                                                      (hashtab_key_t) id);
 
469
 
 
470
                if (!comdatum) {
 
471
                        yyerror2("common %s is not defined", id);
 
472
                        goto bad;
 
473
                }
 
474
                cladatum->comkey = id;
 
475
                cladatum->comdatum = comdatum;
 
476
 
 
477
                /*
 
478
                 * Class-specific permissions start with values 
 
479
                 * after the last common permission.
 
480
                 */
 
481
                cladatum->permissions.nprim += comdatum->permissions.nprim;
 
482
        }
 
483
        while ((id = queue_remove(id_queue))) {
 
484
                perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
 
485
                if (!perdatum) {
 
486
                        yyerror("out of memory");
 
487
                        goto bad;
 
488
                }
 
489
                memset(perdatum, 0, sizeof(perm_datum_t));
 
490
                perdatum->s.value = ++cladatum->permissions.nprim;
 
491
 
 
492
                if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
 
493
                        yyerror
 
494
                            ("too many permissions to fit in an access vector");
 
495
                        goto bad;
 
496
                }
 
497
                if (inherits) {
 
498
                        /*
 
499
                         * Class-specific permissions and 
 
500
                         * common permissions exist in the same
 
501
                         * name space.
 
502
                         */
 
503
                        perdatum2 =
 
504
                            (perm_datum_t *) hashtab_search(cladatum->comdatum->
 
505
                                                            permissions.table,
 
506
                                                            (hashtab_key_t) id);
 
507
                        if (perdatum2) {
 
508
                                yyerror2("permission %s conflicts with an "
 
509
                                         "inherited permission", id);
 
510
                                goto bad;
 
511
                        }
 
512
                }
 
513
                ret = hashtab_insert(cladatum->permissions.table,
 
514
                                     (hashtab_key_t) id,
 
515
                                     (hashtab_datum_t) perdatum);
 
516
 
 
517
                if (ret == SEPOL_EEXIST) {
 
518
                        yyerror2("duplicate permission %s", id);
 
519
                        goto bad;
 
520
                }
 
521
                if (ret == SEPOL_ENOMEM) {
 
522
                        yyerror("hash table overflow");
 
523
                        goto bad;
 
524
                }
 
525
                if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) {
 
526
                        yyerror("out of memory");
 
527
                        goto bad;
 
528
                }
 
529
        }
 
530
 
 
531
        return 0;
 
532
 
 
533
      bad:
 
534
        if (id)
 
535
                free(id);
 
536
        if (perdatum)
 
537
                free(perdatum);
 
538
        return -1;
 
539
}
 
540
 
 
541
int define_sens(void)
 
542
{
 
543
        char *id;
 
544
        mls_level_t *level = 0;
 
545
        level_datum_t *datum = 0, *aliasdatum = 0;
 
546
        int ret;
 
547
        uint32_t value;         /* dummy variable -- its value is never used */
 
548
 
 
549
        if (!mlspol) {
 
550
                yyerror("sensitivity definition in non-MLS configuration");
 
551
                return -1;
 
552
        }
 
553
 
 
554
        if (pass == 2) {
 
555
                while ((id = queue_remove(id_queue)))
 
556
                        free(id);
 
557
                return 0;
 
558
        }
 
559
 
 
560
        id = (char *)queue_remove(id_queue);
 
561
        if (!id) {
 
562
                yyerror("no sensitivity name for sensitivity definition?");
 
563
                return -1;
 
564
        }
 
565
        if (id_has_dot(id)) {
 
566
                yyerror("sensitivity identifiers may not contain periods");
 
567
                goto bad;
 
568
        }
 
569
        level = (mls_level_t *) malloc(sizeof(mls_level_t));
 
570
        if (!level) {
 
571
                yyerror("out of memory");
 
572
                goto bad;
 
573
        }
 
574
        mls_level_init(level);
 
575
        level->sens = 0;        /* actual value set in define_dominance */
 
576
        ebitmap_init(&level->cat);      /* actual value set in define_level */
 
577
 
 
578
        datum = (level_datum_t *) malloc(sizeof(level_datum_t));
 
579
        if (!datum) {
 
580
                yyerror("out of memory");
 
581
                goto bad;
 
582
        }
 
583
        level_datum_init(datum);
 
584
        datum->isalias = FALSE;
 
585
        datum->level = level;
 
586
 
 
587
        ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value);
 
588
        switch (ret) {
 
589
        case -3:{
 
590
                        yyerror("Out of memory!");
 
591
                        goto bad;
 
592
                }
 
593
        case -2:{
 
594
                        yyerror("duplicate declaration of sensitivity level");
 
595
                        goto bad;
 
596
                }
 
597
        case -1:{
 
598
                        yyerror("could not declare sensitivity level here");
 
599
                        goto bad;
 
600
                }
 
601
        case 0:
 
602
        case 1:{
 
603
                        break;
 
604
                }
 
605
        default:{
 
606
                        assert(0);      /* should never get here */
 
607
                }
 
608
        }
 
609
 
 
610
        while ((id = queue_remove(id_queue))) {
 
611
                if (id_has_dot(id)) {
 
612
                        yyerror("sensitivity aliases may not contain periods");
 
613
                        goto bad_alias;
 
614
                }
 
615
                aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t));
 
616
                if (!aliasdatum) {
 
617
                        yyerror("out of memory");
 
618
                        goto bad_alias;
 
619
                }
 
620
                level_datum_init(aliasdatum);
 
621
                aliasdatum->isalias = TRUE;
 
622
                aliasdatum->level = level;
 
623
 
 
624
                ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value);
 
625
                switch (ret) {
 
626
                case -3:{
 
627
                                yyerror("Out of memory!");
 
628
                                goto bad_alias;
 
629
                        }
 
630
                case -2:{
 
631
                                yyerror
 
632
                                    ("duplicate declaration of sensitivity alias");
 
633
                                goto bad_alias;
 
634
                        }
 
635
                case -1:{
 
636
                                yyerror
 
637
                                    ("could not declare sensitivity alias here");
 
638
                                goto bad_alias;
 
639
                        }
 
640
                case 0:
 
641
                case 1:{
 
642
                                break;
 
643
                        }
 
644
                default:{
 
645
                                assert(0);      /* should never get here */
 
646
                        }
 
647
                }
 
648
        }
 
649
 
 
650
        return 0;
 
651
 
 
652
      bad:
 
653
        if (id)
 
654
                free(id);
 
655
        if (level)
 
656
                free(level);
 
657
        if (datum) {
 
658
                level_datum_destroy(datum);
 
659
                free(datum);
 
660
        }
 
661
        return -1;
 
662
 
 
663
      bad_alias:
 
664
        if (id)
 
665
                free(id);
 
666
        if (aliasdatum) {
 
667
                level_datum_destroy(aliasdatum);
 
668
                free(aliasdatum);
 
669
        }
 
670
        return -1;
 
671
}
 
672
 
 
673
int define_dominance(void)
 
674
{
 
675
        level_datum_t *datum;
 
676
        int order;
 
677
        char *id;
 
678
 
 
679
        if (!mlspol) {
 
680
                yyerror("dominance definition in non-MLS configuration");
 
681
                return -1;
 
682
        }
 
683
 
 
684
        if (pass == 2) {
 
685
                while ((id = queue_remove(id_queue)))
 
686
                        free(id);
 
687
                return 0;
 
688
        }
 
689
 
 
690
        order = 0;
 
691
        while ((id = (char *)queue_remove(id_queue))) {
 
692
                datum =
 
693
                    (level_datum_t *) hashtab_search(policydbp->p_levels.table,
 
694
                                                     (hashtab_key_t) id);
 
695
                if (!datum) {
 
696
                        yyerror2("unknown sensitivity %s used in dominance "
 
697
                                 "definition", id);
 
698
                        free(id);
 
699
                        return -1;
 
700
                }
 
701
                if (datum->level->sens != 0) {
 
702
                        yyerror2("sensitivity %s occurs multiply in dominance "
 
703
                                 "definition", id);
 
704
                        free(id);
 
705
                        return -1;
 
706
                }
 
707
                datum->level->sens = ++order;
 
708
 
 
709
                /* no need to keep sensitivity name */
 
710
                free(id);
 
711
        }
 
712
 
 
713
        if (order != policydbp->p_levels.nprim) {
 
714
                yyerror
 
715
                    ("all sensitivities must be specified in dominance definition");
 
716
                return -1;
 
717
        }
 
718
        return 0;
 
719
}
 
720
 
 
721
int define_category(void)
 
722
{
 
723
        char *id;
 
724
        cat_datum_t *datum = 0, *aliasdatum = 0;
 
725
        int ret;
 
726
        uint32_t value;
 
727
 
 
728
        if (!mlspol) {
 
729
                yyerror("category definition in non-MLS configuration");
 
730
                return -1;
 
731
        }
 
732
 
 
733
        if (pass == 2) {
 
734
                while ((id = queue_remove(id_queue)))
 
735
                        free(id);
 
736
                return 0;
 
737
        }
 
738
 
 
739
        id = (char *)queue_remove(id_queue);
 
740
        if (!id) {
 
741
                yyerror("no category name for category definition?");
 
742
                return -1;
 
743
        }
 
744
        if (id_has_dot(id)) {
 
745
                yyerror("category identifiers may not contain periods");
 
746
                goto bad;
 
747
        }
 
748
        datum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
 
749
        if (!datum) {
 
750
                yyerror("out of memory");
 
751
                goto bad;
 
752
        }
 
753
        cat_datum_init(datum);
 
754
        datum->isalias = FALSE;
 
755
 
 
756
        ret = declare_symbol(SYM_CATS, id, datum, &value, &value);
 
757
        switch (ret) {
 
758
        case -3:{
 
759
                        yyerror("Out of memory!");
 
760
                        goto bad;
 
761
                }
 
762
        case -2:{
 
763
                        yyerror("duplicate declaration of category");
 
764
                        goto bad;
 
765
                }
 
766
        case -1:{
 
767
                        yyerror("could not declare category here");
 
768
                        goto bad;
 
769
                }
 
770
        case 0:
 
771
        case 1:{
 
772
                        break;
 
773
                }
 
774
        default:{
 
775
                        assert(0);      /* should never get here */
 
776
                }
 
777
        }
 
778
        datum->s.value = value;
 
779
 
 
780
        while ((id = queue_remove(id_queue))) {
 
781
                if (id_has_dot(id)) {
 
782
                        yyerror("category aliases may not contain periods");
 
783
                        goto bad_alias;
 
784
                }
 
785
                aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
 
786
                if (!aliasdatum) {
 
787
                        yyerror("out of memory");
 
788
                        goto bad_alias;
 
789
                }
 
790
                cat_datum_init(aliasdatum);
 
791
                aliasdatum->isalias = TRUE;
 
792
                aliasdatum->s.value = datum->s.value;
 
793
 
 
794
                ret =
 
795
                    declare_symbol(SYM_CATS, id, aliasdatum, NULL,
 
796
                                   &datum->s.value);
 
797
                switch (ret) {
 
798
                case -3:{
 
799
                                yyerror("Out of memory!");
 
800
                                goto bad_alias;
 
801
                        }
 
802
                case -2:{
 
803
                                yyerror
 
804
                                    ("duplicate declaration of category aliases");
 
805
                                goto bad_alias;
 
806
                        }
 
807
                case -1:{
 
808
                                yyerror
 
809
                                    ("could not declare category aliases here");
 
810
                                goto bad_alias;
 
811
                        }
 
812
                case 0:
 
813
                case 1:{
 
814
                                break;
 
815
                        }
 
816
                default:{
 
817
                                assert(0);      /* should never get here */
 
818
                        }
 
819
                }
 
820
        }
 
821
 
 
822
        return 0;
 
823
 
 
824
      bad:
 
825
        if (id)
 
826
                free(id);
 
827
        if (datum) {
 
828
                cat_datum_destroy(datum);
 
829
                free(datum);
 
830
        }
 
831
        return -1;
 
832
 
 
833
      bad_alias:
 
834
        if (id)
 
835
                free(id);
 
836
        if (aliasdatum) {
 
837
                cat_datum_destroy(aliasdatum);
 
838
                free(aliasdatum);
 
839
        }
 
840
        return -1;
 
841
}
 
842
 
 
843
static int clone_level(hashtab_key_t key, hashtab_datum_t datum, void *arg)
 
844
{
 
845
        level_datum_t *levdatum = (level_datum_t *) datum;
 
846
        mls_level_t *level = (mls_level_t *) arg, *newlevel;
 
847
 
 
848
        if (levdatum->level == level) {
 
849
                levdatum->defined = 1;
 
850
                if (!levdatum->isalias)
 
851
                        return 0;
 
852
                newlevel = (mls_level_t *) malloc(sizeof(mls_level_t));
 
853
                if (!newlevel)
 
854
                        return -1;
 
855
                if (mls_level_cpy(newlevel, level)) {
 
856
                        free(newlevel);
 
857
                        return -1;
 
858
                }
 
859
                levdatum->level = newlevel;
 
860
        }
 
861
        return 0;
 
862
}
 
863
 
 
864
int define_level(void)
 
865
{
 
866
        char *id;
 
867
        level_datum_t *levdatum;
 
868
 
 
869
        if (!mlspol) {
 
870
                yyerror("level definition in non-MLS configuration");
 
871
                return -1;
 
872
        }
 
873
 
 
874
        if (pass == 2) {
 
875
                while ((id = queue_remove(id_queue)))
 
876
                        free(id);
 
877
                return 0;
 
878
        }
 
879
 
 
880
        id = (char *)queue_remove(id_queue);
 
881
        if (!id) {
 
882
                yyerror("no level name for level definition?");
 
883
                return -1;
 
884
        }
 
885
        levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
 
886
                                                    (hashtab_key_t) id);
 
887
        if (!levdatum) {
 
888
                yyerror2("unknown sensitivity %s used in level definition", id);
 
889
                free(id);
 
890
                return -1;
 
891
        }
 
892
        if (ebitmap_length(&levdatum->level->cat)) {
 
893
                yyerror2("sensitivity %s used in multiple level definitions",
 
894
                         id);
 
895
                free(id);
 
896
                return -1;
 
897
        }
 
898
        free(id);
 
899
 
 
900
        levdatum->defined = 1;
 
901
 
 
902
        while ((id = queue_remove(id_queue))) {
 
903
                cat_datum_t *cdatum;
 
904
                int range_start, range_end, i;
 
905
 
 
906
                if (id_has_dot(id)) {
 
907
                        char *id_start = id;
 
908
                        char *id_end = strchr(id, '.');
 
909
 
 
910
                        *(id_end++) = '\0';
 
911
 
 
912
                        cdatum =
 
913
                            (cat_datum_t *) hashtab_search(policydbp->p_cats.
 
914
                                                           table,
 
915
                                                           (hashtab_key_t)
 
916
                                                           id_start);
 
917
                        if (!cdatum) {
 
918
                                yyerror2("unknown category %s", id_start);
 
919
                                free(id);
 
920
                                return -1;
 
921
                        }
 
922
                        range_start = cdatum->s.value - 1;
 
923
                        cdatum =
 
924
                            (cat_datum_t *) hashtab_search(policydbp->p_cats.
 
925
                                                           table,
 
926
                                                           (hashtab_key_t)
 
927
                                                           id_end);
 
928
                        if (!cdatum) {
 
929
                                yyerror2("unknown category %s", id_end);
 
930
                                free(id);
 
931
                                return -1;
 
932
                        }
 
933
                        range_end = cdatum->s.value - 1;
 
934
 
 
935
                        if (range_end < range_start) {
 
936
                                yyerror2("category range is invalid");
 
937
                                free(id);
 
938
                                return -1;
 
939
                        }
 
940
                } else {
 
941
                        cdatum =
 
942
                            (cat_datum_t *) hashtab_search(policydbp->p_cats.
 
943
                                                           table,
 
944
                                                           (hashtab_key_t) id);
 
945
                        range_start = range_end = cdatum->s.value - 1;
 
946
                }
 
947
 
 
948
                for (i = range_start; i <= range_end; i++) {
 
949
                        if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) {
 
950
                                yyerror("out of memory");
 
951
                                free(id);
 
952
                                return -1;
 
953
                        }
 
954
                }
 
955
 
 
956
                free(id);
 
957
        }
 
958
 
 
959
        if (hashtab_map
 
960
            (policydbp->p_levels.table, clone_level, levdatum->level)) {
 
961
                yyerror("out of memory");
 
962
                return -1;
 
963
        }
 
964
 
 
965
        return 0;
 
966
}
 
967
 
 
968
int define_attrib(void)
 
969
{
 
970
        if (pass == 2) {
 
971
                free(queue_remove(id_queue));
 
972
                return 0;
 
973
        }
 
974
 
 
975
        if (declare_type(TRUE, TRUE) == NULL) {
 
976
                return -1;
 
977
        }
 
978
        return 0;
 
979
}
 
980
 
 
981
static int add_aliases_to_type(type_datum_t * type)
 
982
{
 
983
        char *id;
 
984
        type_datum_t *aliasdatum = NULL;
 
985
        int ret;
 
986
        while ((id = queue_remove(id_queue))) {
 
987
                if (id_has_dot(id)) {
 
988
                        free(id);
 
989
                        yyerror
 
990
                            ("type alias identifiers may not contain periods");
 
991
                        return -1;
 
992
                }
 
993
                aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
 
994
                if (!aliasdatum) {
 
995
                        free(id);
 
996
                        yyerror("Out of memory!");
 
997
                        return -1;
 
998
                }
 
999
                memset(aliasdatum, 0, sizeof(type_datum_t));
 
1000
                aliasdatum->s.value = type->s.value;
 
1001
 
 
1002
                ret = declare_symbol(SYM_TYPES, id, aliasdatum,
 
1003
                                     NULL, &aliasdatum->s.value);
 
1004
                switch (ret) {
 
1005
                case -3:{
 
1006
                                yyerror("Out of memory!");
 
1007
                                goto cleanup;
 
1008
                        }
 
1009
                case -2:{
 
1010
                                yyerror2("duplicate declaration of alias %s",
 
1011
                                         id);
 
1012
                                goto cleanup;
 
1013
                        }
 
1014
                case -1:{
 
1015
                                yyerror("could not declare alias here");
 
1016
                                goto cleanup;
 
1017
                        }
 
1018
                case 0:
 
1019
                case 1:{
 
1020
                                break;
 
1021
                        }
 
1022
                default:{
 
1023
                                assert(0);      /* should never get here */
 
1024
                        }
 
1025
                }
 
1026
        }
 
1027
        return 0;
 
1028
      cleanup:
 
1029
        free(id);
 
1030
        type_datum_destroy(aliasdatum);
 
1031
        free(aliasdatum);
 
1032
        return -1;
 
1033
}
 
1034
 
 
1035
int define_typealias(void)
 
1036
{
 
1037
        char *id;
 
1038
        type_datum_t *t;
 
1039
 
 
1040
        if (pass == 2) {
 
1041
                while ((id = queue_remove(id_queue)))
 
1042
                        free(id);
 
1043
                return 0;
 
1044
        }
 
1045
 
 
1046
        id = (char *)queue_remove(id_queue);
 
1047
        if (!id) {
 
1048
                yyerror("no type name for typealias definition?");
 
1049
                return -1;
 
1050
        }
 
1051
 
 
1052
        if (!is_id_in_scope(SYM_TYPES, id)) {
 
1053
                yyerror2("type %s is not within scope", id);
 
1054
                free(id);
 
1055
                return -1;
 
1056
        }
 
1057
        t = hashtab_search(policydbp->p_types.table, id);
 
1058
        if (!t || t->flavor == TYPE_ATTRIB) {
 
1059
                yyerror2("unknown type %s, or it was already declared as an "
 
1060
                         "attribute", id);
 
1061
                free(id);
 
1062
                return -1;
 
1063
        }
 
1064
        return add_aliases_to_type(t);
 
1065
}
 
1066
 
 
1067
int define_typeattribute(void)
 
1068
{
 
1069
        char *id;
 
1070
        type_datum_t *t, *attr;
 
1071
 
 
1072
        if (pass == 2) {
 
1073
                while ((id = queue_remove(id_queue)))
 
1074
                        free(id);
 
1075
                return 0;
 
1076
        }
 
1077
 
 
1078
        id = (char *)queue_remove(id_queue);
 
1079
        if (!id) {
 
1080
                yyerror("no type name for typeattribute definition?");
 
1081
                return -1;
 
1082
        }
 
1083
 
 
1084
        if (!is_id_in_scope(SYM_TYPES, id)) {
 
1085
                yyerror2("type %s is not within scope", id);
 
1086
                free(id);
 
1087
                return -1;
 
1088
        }
 
1089
        t = hashtab_search(policydbp->p_types.table, id);
 
1090
        if (!t || t->flavor == TYPE_ATTRIB) {
 
1091
                yyerror2("unknown type %s", id);
 
1092
                free(id);
 
1093
                return -1;
 
1094
        }
 
1095
 
 
1096
        while ((id = queue_remove(id_queue))) {
 
1097
                if (!is_id_in_scope(SYM_TYPES, id)) {
 
1098
                        yyerror2("attribute %s is not within scope", id);
 
1099
                        free(id);
 
1100
                        return -1;
 
1101
                }
 
1102
                attr = hashtab_search(policydbp->p_types.table, id);
 
1103
                if (!attr) {
 
1104
                        /* treat it as a fatal error */
 
1105
                        yyerror2("attribute %s is not declared", id);
 
1106
                        free(id);
 
1107
                        return -1;
 
1108
                }
 
1109
 
 
1110
                if (attr->flavor != TYPE_ATTRIB) {
 
1111
                        yyerror2("%s is a type, not an attribute", id);
 
1112
                        free(id);
 
1113
                        return -1;
 
1114
                }
 
1115
 
 
1116
                if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
 
1117
                        yyerror("Out of memory!");
 
1118
                        return -1;
 
1119
                }
 
1120
 
 
1121
                if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) {
 
1122
                        yyerror("out of memory");
 
1123
                        return -1;
 
1124
                }
 
1125
        }
 
1126
 
 
1127
        return 0;
 
1128
}
 
1129
 
 
1130
int define_type(int alias)
 
1131
{
 
1132
        char *id;
 
1133
        type_datum_t *datum, *attr;
 
1134
        int newattr = 0;
 
1135
 
 
1136
        if (pass == 2) {
 
1137
                while ((id = queue_remove(id_queue)))
 
1138
                        free(id);
 
1139
                if (alias) {
 
1140
                        while ((id = queue_remove(id_queue)))
 
1141
                                free(id);
 
1142
                }
 
1143
                return 0;
 
1144
        }
 
1145
 
 
1146
        if ((datum = declare_type(TRUE, FALSE)) == NULL) {
 
1147
                return -1;
 
1148
        }
 
1149
 
 
1150
        if (alias) {
 
1151
                if (add_aliases_to_type(datum) == -1) {
 
1152
                        return -1;
 
1153
                }
 
1154
        }
 
1155
 
 
1156
        while ((id = queue_remove(id_queue))) {
 
1157
                if (!is_id_in_scope(SYM_TYPES, id)) {
 
1158
                        yyerror2("attribute %s is not within scope", id);
 
1159
                        free(id);
 
1160
                        return -1;
 
1161
                }
 
1162
                attr = hashtab_search(policydbp->p_types.table, id);
 
1163
                if (!attr) {
 
1164
                        /* treat it as a fatal error */
 
1165
                        yyerror2("attribute %s is not declared", id);
 
1166
                        return -1;
 
1167
                } else {
 
1168
                        newattr = 0;
 
1169
                }
 
1170
 
 
1171
                if (attr->flavor != TYPE_ATTRIB) {
 
1172
                        yyerror2("%s is a type, not an attribute", id);
 
1173
                        return -1;
 
1174
                }
 
1175
 
 
1176
                if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
 
1177
                        yyerror("Out of memory!");
 
1178
                        return -1;
 
1179
                }
 
1180
 
 
1181
                if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) {
 
1182
                        yyerror("Out of memory");
 
1183
                        return -1;
 
1184
                }
 
1185
        }
 
1186
 
 
1187
        return 0;
 
1188
}
 
1189
 
 
1190
struct val_to_name {
 
1191
        unsigned int val;
 
1192
        char *name;
 
1193
};
 
1194
 
 
1195
/* Adds a type, given by its textual name, to a typeset.  If *add is
 
1196
   0, then add the type to the negative set; otherwise if *add is 1
 
1197
   then add it to the positive side. */
 
1198
static int set_types(type_set_t * set, char *id, int *add, char starallowed)
 
1199
{
 
1200
        type_datum_t *t;
 
1201
 
 
1202
        if (strcmp(id, "*") == 0) {
 
1203
                if (!starallowed) {
 
1204
                        yyerror("* not allowed in this type of rule");
 
1205
                        return -1;
 
1206
                }
 
1207
                /* set TYPE_STAR flag */
 
1208
                set->flags = TYPE_STAR;
 
1209
                free(id);
 
1210
                *add = 1;
 
1211
                return 0;
 
1212
        }
 
1213
 
 
1214
        if (strcmp(id, "~") == 0) {
 
1215
                if (!starallowed) {
 
1216
                        yyerror("~ not allowed in this type of rule");
 
1217
                        return -1;
 
1218
                }
 
1219
                /* complement the set */
 
1220
                set->flags = TYPE_COMP;
 
1221
                free(id);
 
1222
                *add = 1;
 
1223
                return 0;
 
1224
        }
 
1225
 
 
1226
        if (strcmp(id, "-") == 0) {
 
1227
                *add = 0;
 
1228
                free(id);
 
1229
                return 0;
 
1230
        }
 
1231
 
 
1232
        if (!is_id_in_scope(SYM_TYPES, id)) {
 
1233
                yyerror2("type %s is not within scope", id);
 
1234
                free(id);
 
1235
                return -1;
 
1236
        }
 
1237
        t = hashtab_search(policydbp->p_types.table, id);
 
1238
        if (!t) {
 
1239
                yyerror2("unknown type %s", id);
 
1240
                free(id);
 
1241
                return -1;
 
1242
        }
 
1243
 
 
1244
        if (*add == 0) {
 
1245
                if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE))
 
1246
                        goto oom;
 
1247
        } else {
 
1248
                if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE))
 
1249
                        goto oom;
 
1250
        }
 
1251
        free(id);
 
1252
        *add = 1;
 
1253
        return 0;
 
1254
      oom:
 
1255
        yyerror("Out of memory");
 
1256
        free(id);
 
1257
        return -1;
 
1258
}
 
1259
 
 
1260
int define_compute_type_helper(int which, avrule_t ** rule)
 
1261
{
 
1262
        char *id;
 
1263
        type_datum_t *datum;
 
1264
        class_datum_t *cladatum;
 
1265
        ebitmap_t tclasses;
 
1266
        ebitmap_node_t *node;
 
1267
        avrule_t *avrule;
 
1268
        class_perm_node_t *perm;
 
1269
        int i, add = 1;
 
1270
 
 
1271
        avrule = malloc(sizeof(avrule_t));
 
1272
        if (!avrule) {
 
1273
                yyerror("out of memory");
 
1274
                return -1;
 
1275
        }
 
1276
        avrule_init(avrule);
 
1277
        avrule->specified = which;
 
1278
        avrule->line = policydb_lineno;
 
1279
 
 
1280
        while ((id = queue_remove(id_queue))) {
 
1281
                if (set_types(&avrule->stypes, id, &add, 0))
 
1282
                        return -1;
 
1283
        }
 
1284
        add = 1;
 
1285
        while ((id = queue_remove(id_queue))) {
 
1286
                if (set_types(&avrule->ttypes, id, &add, 0))
 
1287
                        return -1;
 
1288
        }
 
1289
 
 
1290
        ebitmap_init(&tclasses);
 
1291
        while ((id = queue_remove(id_queue))) {
 
1292
                if (!is_id_in_scope(SYM_CLASSES, id)) {
 
1293
                        yyerror2("class %s is not within scope", id);
 
1294
                        free(id);
 
1295
                        goto bad;
 
1296
                }
 
1297
                cladatum = hashtab_search(policydbp->p_classes.table, id);
 
1298
                if (!cladatum) {
 
1299
                        yyerror2("unknown class %s", id);
 
1300
                        goto bad;
 
1301
                }
 
1302
                if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) {
 
1303
                        yyerror("Out of memory");
 
1304
                        goto bad;
 
1305
                }
 
1306
                free(id);
 
1307
        }
 
1308
 
 
1309
        id = (char *)queue_remove(id_queue);
 
1310
        if (!id) {
 
1311
                yyerror("no newtype?");
 
1312
                goto bad;
 
1313
        }
 
1314
        if (!is_id_in_scope(SYM_TYPES, id)) {
 
1315
                yyerror2("type %s is not within scope", id);
 
1316
                free(id);
 
1317
                goto bad;
 
1318
        }
 
1319
        datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
 
1320
                                                (hashtab_key_t) id);
 
1321
        if (!datum || datum->flavor == TYPE_ATTRIB) {
 
1322
                yyerror2("unknown type %s", id);
 
1323
                goto bad;
 
1324
        }
 
1325
 
 
1326
        ebitmap_for_each_bit(&tclasses, node, i) {
 
1327
                if (ebitmap_node_get_bit(node, i)) {
 
1328
                        perm = malloc(sizeof(class_perm_node_t));
 
1329
                        if (!perm) {
 
1330
                                yyerror("out of memory");
 
1331
                                return -1;
 
1332
                        }
 
1333
                        class_perm_node_init(perm);
 
1334
                        perm->class = i + 1;
 
1335
                        perm->data = datum->s.value;
 
1336
                        perm->next = avrule->perms;
 
1337
                        avrule->perms = perm;
 
1338
                }
 
1339
        }
 
1340
        ebitmap_destroy(&tclasses);
 
1341
 
 
1342
        *rule = avrule;
 
1343
        return 0;
 
1344
 
 
1345
      bad:
 
1346
        avrule_destroy(avrule);
 
1347
        free(avrule);
 
1348
        return -1;
 
1349
}
 
1350
 
 
1351
int define_compute_type(int which)
 
1352
{
 
1353
        char *id;
 
1354
        avrule_t *avrule;
 
1355
 
 
1356
        if (pass == 1) {
 
1357
                while ((id = queue_remove(id_queue)))
 
1358
                        free(id);
 
1359
                while ((id = queue_remove(id_queue)))
 
1360
                        free(id);
 
1361
                while ((id = queue_remove(id_queue)))
 
1362
                        free(id);
 
1363
                id = queue_remove(id_queue);
 
1364
                free(id);
 
1365
                return 0;
 
1366
        }
 
1367
 
 
1368
        if (define_compute_type_helper(which, &avrule))
 
1369
                return -1;
 
1370
 
 
1371
        append_avrule(avrule);
 
1372
        return 0;
 
1373
}
 
1374
 
 
1375
avrule_t *define_cond_compute_type(int which)
 
1376
{
 
1377
        char *id;
 
1378
        avrule_t *avrule;
 
1379
 
 
1380
        if (pass == 1) {
 
1381
                while ((id = queue_remove(id_queue)))
 
1382
                        free(id);
 
1383
                while ((id = queue_remove(id_queue)))
 
1384
                        free(id);
 
1385
                while ((id = queue_remove(id_queue)))
 
1386
                        free(id);
 
1387
                id = queue_remove(id_queue);
 
1388
                free(id);
 
1389
                return (avrule_t *) 1;
 
1390
        }
 
1391
 
 
1392
        if (define_compute_type_helper(which, &avrule))
 
1393
                return COND_ERR;
 
1394
 
 
1395
        return avrule;
 
1396
}
 
1397
 
 
1398
int define_bool(void)
 
1399
{
 
1400
        char *id, *bool_value;
 
1401
        cond_bool_datum_t *datum;
 
1402
        int ret;
 
1403
        uint32_t value;
 
1404
 
 
1405
        if (pass == 2) {
 
1406
                while ((id = queue_remove(id_queue)))
 
1407
                        free(id);
 
1408
                return 0;
 
1409
        }
 
1410
 
 
1411
        id = (char *)queue_remove(id_queue);
 
1412
        if (!id) {
 
1413
                yyerror("no identifier for bool definition?");
 
1414
                return -1;
 
1415
        }
 
1416
        if (id_has_dot(id)) {
 
1417
                free(id);
 
1418
                yyerror("boolean identifiers may not contain periods");
 
1419
                return -1;
 
1420
        }
 
1421
        datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
 
1422
        if (!datum) {
 
1423
                yyerror("out of memory");
 
1424
                free(id);
 
1425
                return -1;
 
1426
        }
 
1427
        memset(datum, 0, sizeof(cond_bool_datum_t));
 
1428
        ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
 
1429
        switch (ret) {
 
1430
        case -3:{
 
1431
                        yyerror("Out of memory!");
 
1432
                        goto cleanup;
 
1433
                }
 
1434
        case -2:{
 
1435
                        yyerror2("duplicate declaration of boolean %s", id);
 
1436
                        goto cleanup;
 
1437
                }
 
1438
        case -1:{
 
1439
                        yyerror("could not declare boolean here");
 
1440
                        goto cleanup;
 
1441
                }
 
1442
        case 0:
 
1443
        case 1:{
 
1444
                        break;
 
1445
                }
 
1446
        default:{
 
1447
                        assert(0);      /* should never get here */
 
1448
                }
 
1449
        }
 
1450
        datum->s.value = value;
 
1451
 
 
1452
        bool_value = (char *)queue_remove(id_queue);
 
1453
        if (!bool_value) {
 
1454
                yyerror("no default value for bool definition?");
 
1455
                free(id);
 
1456
                return -1;
 
1457
        }
 
1458
 
 
1459
        datum->state = (int)(bool_value[0] == 'T') ? 1 : 0;
 
1460
        return 0;
 
1461
      cleanup:
 
1462
        cond_destroy_bool(id, datum, NULL);
 
1463
        return -1;
 
1464
}
 
1465
 
 
1466
avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
 
1467
{
 
1468
        if (pass == 1) {
 
1469
                /* return something so we get through pass 1 */
 
1470
                return (avrule_t *) 1;
 
1471
        }
 
1472
 
 
1473
        if (sl == NULL) {
 
1474
                /* This is a require block, return previous list */
 
1475
                return avlist;
 
1476
        }
 
1477
 
 
1478
        /* prepend the new avlist to the pre-existing one */
 
1479
        sl->next = avlist;
 
1480
        return sl;
 
1481
}
 
1482
 
 
1483
int define_te_avtab_helper(int which, avrule_t ** rule)
 
1484
{
 
1485
        char *id;
 
1486
        class_datum_t *cladatum;
 
1487
        perm_datum_t *perdatum = NULL;
 
1488
        class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
 
1489
        ebitmap_t tclasses;
 
1490
        ebitmap_node_t *node;
 
1491
        avrule_t *avrule;
 
1492
        unsigned int i;
 
1493
        int add = 1, ret = 0;
 
1494
        int suppress = 0;
 
1495
 
 
1496
        avrule = (avrule_t *) malloc(sizeof(avrule_t));
 
1497
        if (!avrule) {
 
1498
                yyerror("memory error");
 
1499
                ret = -1;
 
1500
                goto out;
 
1501
        }
 
1502
        avrule_init(avrule);
 
1503
        avrule->specified = which;
 
1504
        avrule->line = policydb_lineno;
 
1505
 
 
1506
        while ((id = queue_remove(id_queue))) {
 
1507
                if (set_types
 
1508
                    (&avrule->stypes, id, &add,
 
1509
                     which == AVRULE_NEVERALLOW ? 1 : 0)) {
 
1510
                        ret = -1;
 
1511
                        goto out;
 
1512
                }
 
1513
        }
 
1514
        add = 1;
 
1515
        while ((id = queue_remove(id_queue))) {
 
1516
                if (strcmp(id, "self") == 0) {
 
1517
                        free(id);
 
1518
                        avrule->flags |= RULE_SELF;
 
1519
                        continue;
 
1520
                }
 
1521
                if (set_types
 
1522
                    (&avrule->ttypes, id, &add,
 
1523
                     which == AVRULE_NEVERALLOW ? 1 : 0)) {
 
1524
                        ret = -1;
 
1525
                        goto out;
 
1526
                }
 
1527
        }
 
1528
 
 
1529
        ebitmap_init(&tclasses);
 
1530
        while ((id = queue_remove(id_queue))) {
 
1531
                if (!is_id_in_scope(SYM_CLASSES, id)) {
 
1532
                        yyerror2("class %s is not within scope", id);
 
1533
                        ret = -1;
 
1534
                        goto out;
 
1535
                }
 
1536
                cladatum = hashtab_search(policydbp->p_classes.table, id);
 
1537
                if (!cladatum) {
 
1538
                        yyerror2("unknown class %s used in rule", id);
 
1539
                        ret = -1;
 
1540
                        goto out;
 
1541
                }
 
1542
                if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) {
 
1543
                        yyerror("Out of memory");
 
1544
                        ret = -1;
 
1545
                        goto out;
 
1546
                }
 
1547
                free(id);
 
1548
        }
 
1549
 
 
1550
        perms = NULL;
 
1551
        ebitmap_for_each_bit(&tclasses, node, i) {
 
1552
                if (!ebitmap_node_get_bit(node, i))
 
1553
                        continue;
 
1554
                cur_perms =
 
1555
                    (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
 
1556
                if (!cur_perms) {
 
1557
                        yyerror("out of memory");
 
1558
                        ret = -1;
 
1559
                        goto out;
 
1560
                }
 
1561
                class_perm_node_init(cur_perms);
 
1562
                cur_perms->class = i + 1;
 
1563
                if (!perms)
 
1564
                        perms = cur_perms;
 
1565
                if (tail)
 
1566
                        tail->next = cur_perms;
 
1567
                tail = cur_perms;
 
1568
        }
 
1569
 
 
1570
        while ((id = queue_remove(id_queue))) {
 
1571
                cur_perms = perms;
 
1572
                ebitmap_for_each_bit(&tclasses, node, i) {
 
1573
                        if (!ebitmap_node_get_bit(node, i))
 
1574
                                continue;
 
1575
                        cladatum = policydbp->class_val_to_struct[i];
 
1576
 
 
1577
                        if (strcmp(id, "*") == 0) {
 
1578
                                /* set all permissions in the class */
 
1579
                                cur_perms->data = ~0U;
 
1580
                                goto next;
 
1581
                        }
 
1582
 
 
1583
                        if (strcmp(id, "~") == 0) {
 
1584
                                /* complement the set */
 
1585
                                if (which == AVRULE_DONTAUDIT)
 
1586
                                        yywarn("dontaudit rule with a ~?");
 
1587
                                cur_perms->data = ~cur_perms->data;
 
1588
                                goto next;
 
1589
                        }
 
1590
 
 
1591
                        perdatum =
 
1592
                            hashtab_search(cladatum->permissions.table, id);
 
1593
                        if (!perdatum) {
 
1594
                                if (cladatum->comdatum) {
 
1595
                                        perdatum =
 
1596
                                            hashtab_search(cladatum->comdatum->
 
1597
                                                           permissions.table,
 
1598
                                                           id);
 
1599
                                }
 
1600
                        }
 
1601
                        if (!perdatum) {
 
1602
                                if (!suppress)
 
1603
                                        yyerror2("permission %s is not defined"
 
1604
                                             " for class %s", id,
 
1605
                                             policydbp->p_class_val_to_name[i]);
 
1606
                                continue;
 
1607
                        } else
 
1608
                            if (!is_perm_in_scope
 
1609
                                (id, policydbp->p_class_val_to_name[i])) {
 
1610
                                if (!suppress) {
 
1611
                                        yyerror2("permission %s of class %s is"
 
1612
                                             " not within scope", id,
 
1613
                                             policydbp->p_class_val_to_name[i]);
 
1614
                                }
 
1615
                                continue;
 
1616
                        } else {
 
1617
                                cur_perms->data |= 1U << (perdatum->s.value - 1);
 
1618
                        }
 
1619
                      next:
 
1620
                        cur_perms = cur_perms->next;
 
1621
                }
 
1622
 
 
1623
                free(id);
 
1624
        }
 
1625
 
 
1626
        ebitmap_destroy(&tclasses);
 
1627
 
 
1628
        avrule->perms = perms;
 
1629
        *rule = avrule;
 
1630
 
 
1631
      out:
 
1632
        return ret;
 
1633
 
 
1634
}
 
1635
 
 
1636
avrule_t *define_cond_te_avtab(int which)
 
1637
{
 
1638
        char *id;
 
1639
        avrule_t *avrule;
 
1640
        int i;
 
1641
 
 
1642
        if (pass == 1) {
 
1643
                for (i = 0; i < 4; i++) {
 
1644
                        while ((id = queue_remove(id_queue)))
 
1645
                                free(id);
 
1646
                }
 
1647
                return (avrule_t *) 1;  /* any non-NULL value */
 
1648
        }
 
1649
 
 
1650
        if (define_te_avtab_helper(which, &avrule))
 
1651
                return COND_ERR;
 
1652
 
 
1653
        return avrule;
 
1654
}
 
1655
 
 
1656
int define_te_avtab(int which)
 
1657
{
 
1658
        char *id;
 
1659
        avrule_t *avrule;
 
1660
        int i;
 
1661
 
 
1662
        if (pass == 1) {
 
1663
                for (i = 0; i < 4; i++) {
 
1664
                        while ((id = queue_remove(id_queue)))
 
1665
                                free(id);
 
1666
                }
 
1667
                return 0;
 
1668
        }
 
1669
 
 
1670
        if (define_te_avtab_helper(which, &avrule))
 
1671
                return -1;
 
1672
 
 
1673
        /* append this avrule to the end of the current rules list */
 
1674
        append_avrule(avrule);
 
1675
        return 0;
 
1676
}
 
1677
 
 
1678
int define_role_types(void)
 
1679
{
 
1680
        role_datum_t *role;
 
1681
        char *id;
 
1682
        int add = 1;
 
1683
 
 
1684
        if (pass == 1) {
 
1685
                while ((id = queue_remove(id_queue)))
 
1686
                        free(id);
 
1687
                return 0;
 
1688
        }
 
1689
 
 
1690
        if ((role = declare_role()) == NULL) {
 
1691
                return -1;
 
1692
        }
 
1693
        while ((id = queue_remove(id_queue))) {
 
1694
                if (set_types(&role->types, id, &add, 0))
 
1695
                        return -1;
 
1696
        }
 
1697
 
 
1698
        return 0;
 
1699
}
 
1700
 
 
1701
role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
 
1702
{
 
1703
        role_datum_t *new;
 
1704
 
 
1705
        if (pass == 1) {
 
1706
                return (role_datum_t *) 1;      /* any non-NULL value */
 
1707
        }
 
1708
 
 
1709
        new = malloc(sizeof(role_datum_t));
 
1710
        if (!new) {
 
1711
                yyerror("out of memory");
 
1712
                return NULL;
 
1713
        }
 
1714
        memset(new, 0, sizeof(role_datum_t));
 
1715
        new->s.value = 0;               /* temporary role */
 
1716
        if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
 
1717
                yyerror("out of memory");
 
1718
                return NULL;
 
1719
        }
 
1720
        if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
 
1721
                yyerror("out of memory");
 
1722
                return NULL;
 
1723
        }
 
1724
        if (!r1->s.value) {
 
1725
                /* free intermediate result */
 
1726
                type_set_destroy(&r1->types);
 
1727
                ebitmap_destroy(&r1->dominates);
 
1728
                free(r1);
 
1729
        }
 
1730
        if (!r2->s.value) {
 
1731
                /* free intermediate result */
 
1732
                yyerror("right hand role is temporary?");
 
1733
                type_set_destroy(&r2->types);
 
1734
                ebitmap_destroy(&r2->dominates);
 
1735
                free(r2);
 
1736
        }
 
1737
        return new;
 
1738
}
 
1739
 
 
1740
/* This function eliminates the ordering dependency of role dominance rule */
 
1741
static int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum,
 
1742
                                 void *arg)
 
1743
{
 
1744
        role_datum_t *rdp = (role_datum_t *) arg;
 
1745
        role_datum_t *rdatum = (role_datum_t *) datum;
 
1746
        ebitmap_node_t *node;
 
1747
        int i;
 
1748
 
 
1749
        /* Don't bother to process against self role */
 
1750
        if (rdatum->s.value == rdp->s.value)
 
1751
                return 0;
 
1752
 
 
1753
        /* If a dominating role found */
 
1754
        if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) {
 
1755
                ebitmap_t types;
 
1756
                ebitmap_init(&types);
 
1757
                if (type_set_expand(&rdp->types, &types, policydbp, 1)) {
 
1758
                        ebitmap_destroy(&types);
 
1759
                        return -1;
 
1760
                }
 
1761
                /* raise types and dominates from dominated role */
 
1762
                ebitmap_for_each_bit(&rdp->dominates, node, i) {
 
1763
                        if (ebitmap_node_get_bit(node, i))
 
1764
                                if (ebitmap_set_bit
 
1765
                                    (&rdatum->dominates, i, TRUE))
 
1766
                                        goto oom;
 
1767
                }
 
1768
                ebitmap_for_each_bit(&types, node, i) {
 
1769
                        if (ebitmap_node_get_bit(node, i))
 
1770
                                if (ebitmap_set_bit
 
1771
                                    (&rdatum->types.types, i, TRUE))
 
1772
                                        goto oom;
 
1773
                }
 
1774
                ebitmap_destroy(&types);
 
1775
        }
 
1776
 
 
1777
        /* go through all the roles */
 
1778
        return 0;
 
1779
      oom:
 
1780
        yyerror("Out of memory");
 
1781
        return -1;
 
1782
}
 
1783
 
 
1784
role_datum_t *define_role_dom(role_datum_t * r)
 
1785
{
 
1786
        role_datum_t *role;
 
1787
        char *role_id;
 
1788
        ebitmap_node_t *node;
 
1789
        unsigned int i;
 
1790
        int ret;
 
1791
 
 
1792
        if (pass == 1) {
 
1793
                role_id = queue_remove(id_queue);
 
1794
                free(role_id);
 
1795
                return (role_datum_t *) 1;      /* any non-NULL value */
 
1796
        }
 
1797
 
 
1798
        yywarn("Role dominance has been deprecated");
 
1799
 
 
1800
        role_id = queue_remove(id_queue);
 
1801
        if (!is_id_in_scope(SYM_ROLES, role_id)) {
 
1802
                yyerror2("role %s is not within scope", role_id);
 
1803
                free(role_id);
 
1804
                return NULL;
 
1805
        }
 
1806
        role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
 
1807
                                               role_id);
 
1808
        if (!role) {
 
1809
                role = (role_datum_t *) malloc(sizeof(role_datum_t));
 
1810
                if (!role) {
 
1811
                        yyerror("out of memory");
 
1812
                        free(role_id);
 
1813
                        return NULL;
 
1814
                }
 
1815
                memset(role, 0, sizeof(role_datum_t));
 
1816
                ret =
 
1817
                    declare_symbol(SYM_ROLES, (hashtab_key_t) role_id,
 
1818
                                   (hashtab_datum_t) role, &role->s.value,
 
1819
                                   &role->s.value);
 
1820
                switch (ret) {
 
1821
                case -3:{
 
1822
                                yyerror("Out of memory!");
 
1823
                                goto cleanup;
 
1824
                        }
 
1825
                case -2:{
 
1826
                                yyerror2("duplicate declaration of role %s",
 
1827
                                         role_id);
 
1828
                                goto cleanup;
 
1829
                        }
 
1830
                case -1:{
 
1831
                                yyerror("could not declare role here");
 
1832
                                goto cleanup;
 
1833
                        }
 
1834
                case 0:
 
1835
                case 1:{
 
1836
                                break;
 
1837
                        }
 
1838
                default:{
 
1839
                                assert(0);      /* should never get here */
 
1840
                        }
 
1841
                }
 
1842
                if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) {
 
1843
                        yyerror("Out of memory!");
 
1844
                        goto cleanup;
 
1845
                }
 
1846
        }
 
1847
        if (r) {
 
1848
                ebitmap_t types;
 
1849
                ebitmap_init(&types);
 
1850
                ebitmap_for_each_bit(&r->dominates, node, i) {
 
1851
                        if (ebitmap_node_get_bit(node, i))
 
1852
                                if (ebitmap_set_bit(&role->dominates, i, TRUE))
 
1853
                                        goto oom;
 
1854
                }
 
1855
                if (type_set_expand(&r->types, &types, policydbp, 1)) {
 
1856
                        ebitmap_destroy(&types);
 
1857
                        return NULL;
 
1858
                }
 
1859
                ebitmap_for_each_bit(&types, node, i) {
 
1860
                        if (ebitmap_node_get_bit(node, i))
 
1861
                                if (ebitmap_set_bit
 
1862
                                    (&role->types.types, i, TRUE))
 
1863
                                        goto oom;
 
1864
                }
 
1865
                ebitmap_destroy(&types);
 
1866
                if (!r->s.value) {
 
1867
                        /* free intermediate result */
 
1868
                        type_set_destroy(&r->types);
 
1869
                        ebitmap_destroy(&r->dominates);
 
1870
                        free(r);
 
1871
                }
 
1872
                /*
 
1873
                 * Now go through all the roles and escalate this role's
 
1874
                 * dominates and types if a role dominates this role.
 
1875
                 */
 
1876
                hashtab_map(policydbp->p_roles.table,
 
1877
                            dominate_role_recheck, role);
 
1878
        }
 
1879
        return role;
 
1880
      cleanup:
 
1881
        free(role_id);
 
1882
        role_datum_destroy(role);
 
1883
        free(role);
 
1884
        return NULL;
 
1885
      oom:
 
1886
        yyerror("Out of memory");
 
1887
        goto cleanup;
 
1888
}
 
1889
 
 
1890
static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum,
 
1891
                                   void *p)
 
1892
{
 
1893
        struct val_to_name *v = p;
 
1894
        role_datum_t *roldatum;
 
1895
 
 
1896
        roldatum = (role_datum_t *) datum;
 
1897
 
 
1898
        if (v->val == roldatum->s.value) {
 
1899
                v->name = key;
 
1900
                return 1;
 
1901
        }
 
1902
 
 
1903
        return 0;
 
1904
}
 
1905
 
 
1906
static char *role_val_to_name(unsigned int val)
 
1907
{
 
1908
        struct val_to_name v;
 
1909
        int rc;
 
1910
 
 
1911
        v.val = val;
 
1912
        rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
 
1913
        if (rc)
 
1914
                return v.name;
 
1915
        return NULL;
 
1916
}
 
1917
 
 
1918
static int set_roles(role_set_t * set, char *id)
 
1919
{
 
1920
        role_datum_t *r;
 
1921
 
 
1922
        if (strcmp(id, "*") == 0) {
 
1923
                free(id);
 
1924
                yyerror("* is not allowed for role sets");
 
1925
                return -1;
 
1926
        }
 
1927
 
 
1928
        if (strcmp(id, "~") == 0) {
 
1929
                free(id);
 
1930
                yyerror("~ is not allowed for role sets");
 
1931
                return -1;
 
1932
        }
 
1933
        if (!is_id_in_scope(SYM_ROLES, id)) {
 
1934
                yyerror2("role %s is not within scope", id);
 
1935
                free(id);
 
1936
                return -1;
 
1937
        }
 
1938
        r = hashtab_search(policydbp->p_roles.table, id);
 
1939
        if (!r) {
 
1940
                yyerror2("unknown role %s", id);
 
1941
                free(id);
 
1942
                return -1;
 
1943
        }
 
1944
 
 
1945
        if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
 
1946
                yyerror("out of memory");
 
1947
                free(id);
 
1948
                return -1;
 
1949
        }
 
1950
        free(id);
 
1951
        return 0;
 
1952
}
 
1953
 
 
1954
int define_role_trans(void)
 
1955
{
 
1956
        char *id;
 
1957
        role_datum_t *role;
 
1958
        role_set_t roles;
 
1959
        type_set_t types;
 
1960
        ebitmap_t e_types, e_roles;
 
1961
        ebitmap_node_t *tnode, *rnode;
 
1962
        struct role_trans *tr = NULL;
 
1963
        struct role_trans_rule *rule = NULL;
 
1964
        unsigned int i, j;
 
1965
        int add = 1;
 
1966
 
 
1967
        if (pass == 1) {
 
1968
                while ((id = queue_remove(id_queue)))
 
1969
                        free(id);
 
1970
                while ((id = queue_remove(id_queue)))
 
1971
                        free(id);
 
1972
                id = queue_remove(id_queue);
 
1973
                free(id);
 
1974
                return 0;
 
1975
        }
 
1976
 
 
1977
        role_set_init(&roles);
 
1978
        ebitmap_init(&e_roles);
 
1979
        type_set_init(&types);
 
1980
        ebitmap_init(&e_types);
 
1981
 
 
1982
        while ((id = queue_remove(id_queue))) {
 
1983
                if (set_roles(&roles, id))
 
1984
                        return -1;
 
1985
        }
 
1986
        add = 1;
 
1987
        while ((id = queue_remove(id_queue))) {
 
1988
                if (set_types(&types, id, &add, 0))
 
1989
                        return -1;
 
1990
        }
 
1991
 
 
1992
        id = (char *)queue_remove(id_queue);
 
1993
        if (!id) {
 
1994
                yyerror("no new role in transition definition?");
 
1995
                goto bad;
 
1996
        }
 
1997
        if (!is_id_in_scope(SYM_ROLES, id)) {
 
1998
                yyerror2("role %s is not within scope", id);
 
1999
                free(id);
 
2000
                goto bad;
 
2001
        }
 
2002
        role = hashtab_search(policydbp->p_roles.table, id);
 
2003
        if (!role) {
 
2004
                yyerror2("unknown role %s used in transition definition", id);
 
2005
                goto bad;
 
2006
        }
 
2007
 
 
2008
        /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
 
2009
        if (role_set_expand(&roles, &e_roles, policydbp, NULL))
 
2010
                goto bad;
 
2011
 
 
2012
        if (type_set_expand(&types, &e_types, policydbp, 1))
 
2013
                goto bad;
 
2014
 
 
2015
        ebitmap_for_each_bit(&e_roles, rnode, i) {
 
2016
                if (!ebitmap_node_get_bit(rnode, i))
 
2017
                        continue;
 
2018
                ebitmap_for_each_bit(&e_types, tnode, j) {
 
2019
                        if (!ebitmap_node_get_bit(tnode, j))
 
2020
                                continue;
 
2021
 
 
2022
                        for (tr = policydbp->role_tr; tr; tr = tr->next) {
 
2023
                                if (tr->role == (i + 1) && tr->type == (j + 1)) {
 
2024
                                        yyerror2("duplicate role transition for (%s,%s)",
 
2025
                                              role_val_to_name(i + 1),
 
2026
                                              policydbp->p_type_val_to_name[j]);
 
2027
                                        goto bad;
 
2028
                                }
 
2029
                        }
 
2030
 
 
2031
                        tr = malloc(sizeof(struct role_trans));
 
2032
                        if (!tr) {
 
2033
                                yyerror("out of memory");
 
2034
                                return -1;
 
2035
                        }
 
2036
                        memset(tr, 0, sizeof(struct role_trans));
 
2037
                        tr->role = i + 1;
 
2038
                        tr->type = j + 1;
 
2039
                        tr->new_role = role->s.value;
 
2040
                        tr->next = policydbp->role_tr;
 
2041
                        policydbp->role_tr = tr;
 
2042
                }
 
2043
        }
 
2044
        /* Now add the real rule */
 
2045
        rule = malloc(sizeof(struct role_trans_rule));
 
2046
        if (!rule) {
 
2047
                yyerror("out of memory");
 
2048
                return -1;
 
2049
        }
 
2050
        memset(rule, 0, sizeof(struct role_trans_rule));
 
2051
        rule->roles = roles;
 
2052
        rule->types = types;
 
2053
        rule->new_role = role->s.value;
 
2054
 
 
2055
        append_role_trans(rule);
 
2056
 
 
2057
        ebitmap_destroy(&e_roles);
 
2058
        ebitmap_destroy(&e_types);
 
2059
 
 
2060
        return 0;
 
2061
 
 
2062
      bad:
 
2063
        return -1;
 
2064
}
 
2065
 
 
2066
int define_role_allow(void)
 
2067
{
 
2068
        char *id;
 
2069
        struct role_allow_rule *ra = 0;
 
2070
 
 
2071
        if (pass == 1) {
 
2072
                while ((id = queue_remove(id_queue)))
 
2073
                        free(id);
 
2074
                while ((id = queue_remove(id_queue)))
 
2075
                        free(id);
 
2076
                return 0;
 
2077
        }
 
2078
 
 
2079
        ra = malloc(sizeof(role_allow_rule_t));
 
2080
        if (!ra) {
 
2081
                yyerror("out of memory");
 
2082
                return -1;
 
2083
        }
 
2084
        role_allow_rule_init(ra);
 
2085
 
 
2086
        while ((id = queue_remove(id_queue))) {
 
2087
                if (set_roles(&ra->roles, id))
 
2088
                        return -1;
 
2089
        }
 
2090
 
 
2091
        while ((id = queue_remove(id_queue))) {
 
2092
                if (set_roles(&ra->new_roles, id))
 
2093
                        return -1;
 
2094
        }
 
2095
 
 
2096
        append_role_allow(ra);
 
2097
        return 0;
 
2098
}
 
2099
 
 
2100
static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
 
2101
{
 
2102
        constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
 
2103
        for (e = expr; e; e = e->next) {
 
2104
                newe = malloc(sizeof(*newe));
 
2105
                if (!newe)
 
2106
                        goto oom;
 
2107
                if (constraint_expr_init(newe) == -1) {
 
2108
                        free(newe);
 
2109
                        goto oom;
 
2110
                }
 
2111
                if (l)
 
2112
                        l->next = newe;
 
2113
                else
 
2114
                        h = newe;
 
2115
                l = newe;
 
2116
                newe->expr_type = e->expr_type;
 
2117
                newe->attr = e->attr;
 
2118
                newe->op = e->op;
 
2119
                if (newe->expr_type == CEXPR_NAMES) {
 
2120
                        if (newe->attr & CEXPR_TYPE) {
 
2121
                                if (type_set_cpy
 
2122
                                    (newe->type_names, e->type_names))
 
2123
                                        goto oom;
 
2124
                        } else {
 
2125
                                if (ebitmap_cpy(&newe->names, &e->names))
 
2126
                                        goto oom;
 
2127
                        }
 
2128
                }
 
2129
        }
 
2130
 
 
2131
        return h;
 
2132
      oom:
 
2133
        e = h;
 
2134
        while (e) {
 
2135
                l = e;
 
2136
                e = e->next;
 
2137
                constraint_expr_destroy(l);
 
2138
        }
 
2139
        return NULL;
 
2140
}
 
2141
 
 
2142
int define_constraint(constraint_expr_t * expr)
 
2143
{
 
2144
        struct constraint_node *node;
 
2145
        char *id;
 
2146
        class_datum_t *cladatum;
 
2147
        perm_datum_t *perdatum;
 
2148
        ebitmap_t classmap;
 
2149
        ebitmap_node_t *enode;
 
2150
        constraint_expr_t *e;
 
2151
        unsigned int i;
 
2152
        int depth;
 
2153
        unsigned char useexpr = 1;
 
2154
 
 
2155
        if (pass == 1) {
 
2156
                while ((id = queue_remove(id_queue)))
 
2157
                        free(id);
 
2158
                while ((id = queue_remove(id_queue)))
 
2159
                        free(id);
 
2160
                return 0;
 
2161
        }
 
2162
 
 
2163
        depth = -1;
 
2164
        for (e = expr; e; e = e->next) {
 
2165
                switch (e->expr_type) {
 
2166
                case CEXPR_NOT:
 
2167
                        if (depth < 0) {
 
2168
                                yyerror("illegal constraint expression");
 
2169
                                return -1;
 
2170
                        }
 
2171
                        break;
 
2172
                case CEXPR_AND:
 
2173
                case CEXPR_OR:
 
2174
                        if (depth < 1) {
 
2175
                                yyerror("illegal constraint expression");
 
2176
                                return -1;
 
2177
                        }
 
2178
                        depth--;
 
2179
                        break;
 
2180
                case CEXPR_ATTR:
 
2181
                case CEXPR_NAMES:
 
2182
                        if (e->attr & CEXPR_XTARGET) {
 
2183
                                yyerror("illegal constraint expression");
 
2184
                                return -1;      /* only for validatetrans rules */
 
2185
                        }
 
2186
                        if (depth == (CEXPR_MAXDEPTH - 1)) {
 
2187
                                yyerror("constraint expression is too deep");
 
2188
                                return -1;
 
2189
                        }
 
2190
                        depth++;
 
2191
                        break;
 
2192
                default:
 
2193
                        yyerror("illegal constraint expression");
 
2194
                        return -1;
 
2195
                }
 
2196
        }
 
2197
        if (depth != 0) {
 
2198
                yyerror("illegal constraint expression");
 
2199
                return -1;
 
2200
        }
 
2201
 
 
2202
        ebitmap_init(&classmap);
 
2203
        while ((id = queue_remove(id_queue))) {
 
2204
                if (!is_id_in_scope(SYM_CLASSES, id)) {
 
2205
                        yyerror2("class %s is not within scope", id);
 
2206
                        free(id);
 
2207
                        return -1;
 
2208
                }
 
2209
                cladatum =
 
2210
                    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
 
2211
                                                     (hashtab_key_t) id);
 
2212
                if (!cladatum) {
 
2213
                        yyerror2("class %s is not defined", id);
 
2214
                        ebitmap_destroy(&classmap);
 
2215
                        free(id);
 
2216
                        return -1;
 
2217
                }
 
2218
                if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
 
2219
                        yyerror("out of memory");
 
2220
                        ebitmap_destroy(&classmap);
 
2221
                        free(id);
 
2222
                        return -1;
 
2223
                }
 
2224
                node = malloc(sizeof(struct constraint_node));
 
2225
                if (!node) {
 
2226
                        yyerror("out of memory");
 
2227
                        return -1;
 
2228
                }
 
2229
                memset(node, 0, sizeof(constraint_node_t));
 
2230
                if (useexpr) {
 
2231
                        node->expr = expr;
 
2232
                        useexpr = 0;
 
2233
                } else {
 
2234
                        node->expr = constraint_expr_clone(expr);
 
2235
                }
 
2236
                if (!node->expr) {
 
2237
                        yyerror("out of memory");
 
2238
                        return -1;
 
2239
                }
 
2240
                node->permissions = 0;
 
2241
 
 
2242
                node->next = cladatum->constraints;
 
2243
                cladatum->constraints = node;
 
2244
 
 
2245
                free(id);
 
2246
        }
 
2247
 
 
2248
        while ((id = queue_remove(id_queue))) {
 
2249
                ebitmap_for_each_bit(&classmap, enode, i) {
 
2250
                        if (ebitmap_node_get_bit(enode, i)) {
 
2251
                                cladatum = policydbp->class_val_to_struct[i];
 
2252
                                node = cladatum->constraints;
 
2253
 
 
2254
                                perdatum =
 
2255
                                    (perm_datum_t *) hashtab_search(cladatum->
 
2256
                                                                    permissions.
 
2257
                                                                    table,
 
2258
                                                                    (hashtab_key_t)
 
2259
                                                                    id);
 
2260
                                if (!perdatum) {
 
2261
                                        if (cladatum->comdatum) {
 
2262
                                                perdatum =
 
2263
                                                    (perm_datum_t *)
 
2264
                                                    hashtab_search(cladatum->
 
2265
                                                                   comdatum->
 
2266
                                                                   permissions.
 
2267
                                                                   table,
 
2268
                                                                   (hashtab_key_t)
 
2269
                                                                   id);
 
2270
                                        }
 
2271
                                        if (!perdatum) {
 
2272
                                                yyerror2("permission %s is not"
 
2273
                                                         " defined", id);
 
2274
                                                free(id);
 
2275
                                                ebitmap_destroy(&classmap);
 
2276
                                                return -1;
 
2277
                                        }
 
2278
                                }
 
2279
                                node->permissions |=
 
2280
                                    (1 << (perdatum->s.value - 1));
 
2281
                        }
 
2282
                }
 
2283
                free(id);
 
2284
        }
 
2285
 
 
2286
        ebitmap_destroy(&classmap);
 
2287
 
 
2288
        return 0;
 
2289
}
 
2290
 
 
2291
int define_validatetrans(constraint_expr_t * expr)
 
2292
{
 
2293
        struct constraint_node *node;
 
2294
        char *id;
 
2295
        class_datum_t *cladatum;
 
2296
        ebitmap_t classmap;
 
2297
        constraint_expr_t *e;
 
2298
        int depth;
 
2299
        unsigned char useexpr = 1;
 
2300
 
 
2301
        if (pass == 1) {
 
2302
                while ((id = queue_remove(id_queue)))
 
2303
                        free(id);
 
2304
                return 0;
 
2305
        }
 
2306
 
 
2307
        depth = -1;
 
2308
        for (e = expr; e; e = e->next) {
 
2309
                switch (e->expr_type) {
 
2310
                case CEXPR_NOT:
 
2311
                        if (depth < 0) {
 
2312
                                yyerror("illegal validatetrans expression");
 
2313
                                return -1;
 
2314
                        }
 
2315
                        break;
 
2316
                case CEXPR_AND:
 
2317
                case CEXPR_OR:
 
2318
                        if (depth < 1) {
 
2319
                                yyerror("illegal validatetrans expression");
 
2320
                                return -1;
 
2321
                        }
 
2322
                        depth--;
 
2323
                        break;
 
2324
                case CEXPR_ATTR:
 
2325
                case CEXPR_NAMES:
 
2326
                        if (depth == (CEXPR_MAXDEPTH - 1)) {
 
2327
                                yyerror("validatetrans expression is too deep");
 
2328
                                return -1;
 
2329
                        }
 
2330
                        depth++;
 
2331
                        break;
 
2332
                default:
 
2333
                        yyerror("illegal validatetrans expression");
 
2334
                        return -1;
 
2335
                }
 
2336
        }
 
2337
        if (depth != 0) {
 
2338
                yyerror("illegal validatetrans expression");
 
2339
                return -1;
 
2340
        }
 
2341
 
 
2342
        ebitmap_init(&classmap);
 
2343
        while ((id = queue_remove(id_queue))) {
 
2344
                if (!is_id_in_scope(SYM_CLASSES, id)) {
 
2345
                        yyerror2("class %s is not within scope", id);
 
2346
                        free(id);
 
2347
                        return -1;
 
2348
                }
 
2349
                cladatum =
 
2350
                    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
 
2351
                                                     (hashtab_key_t) id);
 
2352
                if (!cladatum) {
 
2353
                        yyerror2("class %s is not defined", id);
 
2354
                        ebitmap_destroy(&classmap);
 
2355
                        free(id);
 
2356
                        return -1;
 
2357
                }
 
2358
                if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
 
2359
                        yyerror("out of memory");
 
2360
                        ebitmap_destroy(&classmap);
 
2361
                        free(id);
 
2362
                        return -1;
 
2363
                }
 
2364
 
 
2365
                node = malloc(sizeof(struct constraint_node));
 
2366
                if (!node) {
 
2367
                        yyerror("out of memory");
 
2368
                        return -1;
 
2369
                }
 
2370
                memset(node, 0, sizeof(constraint_node_t));
 
2371
                if (useexpr) {
 
2372
                        node->expr = expr;
 
2373
                        useexpr = 0;
 
2374
                } else {
 
2375
                        node->expr = constraint_expr_clone(expr);
 
2376
                }
 
2377
                node->permissions = 0;
 
2378
 
 
2379
                node->next = cladatum->validatetrans;
 
2380
                cladatum->validatetrans = node;
 
2381
 
 
2382
                free(id);
 
2383
        }
 
2384
 
 
2385
        ebitmap_destroy(&classmap);
 
2386
 
 
2387
        return 0;
 
2388
}
 
2389
 
 
2390
uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
 
2391
{
 
2392
        struct constraint_expr *expr, *e1 = NULL, *e2;
 
2393
        user_datum_t *user;
 
2394
        role_datum_t *role;
 
2395
        ebitmap_t negset;
 
2396
        char *id;
 
2397
        uint32_t val;
 
2398
        int add = 1;
 
2399
 
 
2400
        if (pass == 1) {
 
2401
                if (expr_type == CEXPR_NAMES) {
 
2402
                        while ((id = queue_remove(id_queue)))
 
2403
                                free(id);
 
2404
                }
 
2405
                return 1;       /* any non-NULL value */
 
2406
        }
 
2407
 
 
2408
        if ((expr = malloc(sizeof(*expr))) == NULL ||
 
2409
            constraint_expr_init(expr) == -1) {
 
2410
                yyerror("out of memory");
 
2411
                free(expr);
 
2412
                return 0;
 
2413
        }
 
2414
        expr->expr_type = expr_type;
 
2415
 
 
2416
        switch (expr_type) {
 
2417
        case CEXPR_NOT:
 
2418
                e1 = NULL;
 
2419
                e2 = (struct constraint_expr *)arg1;
 
2420
                while (e2) {
 
2421
                        e1 = e2;
 
2422
                        e2 = e2->next;
 
2423
                }
 
2424
                if (!e1 || e1->next) {
 
2425
                        yyerror("illegal constraint expression");
 
2426
                        constraint_expr_destroy(expr);
 
2427
                        return 0;
 
2428
                }
 
2429
                e1->next = expr;
 
2430
                return arg1;
 
2431
        case CEXPR_AND:
 
2432
        case CEXPR_OR:
 
2433
                e1 = NULL;
 
2434
                e2 = (struct constraint_expr *)arg1;
 
2435
                while (e2) {
 
2436
                        e1 = e2;
 
2437
                        e2 = e2->next;
 
2438
                }
 
2439
                if (!e1 || e1->next) {
 
2440
                        yyerror("illegal constraint expression");
 
2441
                        constraint_expr_destroy(expr);
 
2442
                        return 0;
 
2443
                }
 
2444
                e1->next = (struct constraint_expr *)arg2;
 
2445
 
 
2446
                e1 = NULL;
 
2447
                e2 = (struct constraint_expr *)arg2;
 
2448
                while (e2) {
 
2449
                        e1 = e2;
 
2450
                        e2 = e2->next;
 
2451
                }
 
2452
                if (!e1 || e1->next) {
 
2453
                        yyerror("illegal constraint expression");
 
2454
                        constraint_expr_destroy(expr);
 
2455
                        return 0;
 
2456
                }
 
2457
                e1->next = expr;
 
2458
                return arg1;
 
2459
        case CEXPR_ATTR:
 
2460
                expr->attr = arg1;
 
2461
                expr->op = arg2;
 
2462
                return (uintptr_t) expr;
 
2463
        case CEXPR_NAMES:
 
2464
                add = 1;
 
2465
                expr->attr = arg1;
 
2466
                expr->op = arg2;
 
2467
                ebitmap_init(&negset);
 
2468
                while ((id = (char *)queue_remove(id_queue))) {
 
2469
                        if (expr->attr & CEXPR_USER) {
 
2470
                                if (!is_id_in_scope(SYM_USERS, id)) {
 
2471
                                        yyerror2("user %s is not within scope",
 
2472
                                                 id);
 
2473
                                        constraint_expr_destroy(expr);
 
2474
                                        return 0;
 
2475
                                }
 
2476
                                user =
 
2477
                                    (user_datum_t *) hashtab_search(policydbp->
 
2478
                                                                    p_users.
 
2479
                                                                    table,
 
2480
                                                                    (hashtab_key_t)
 
2481
                                                                    id);
 
2482
                                if (!user) {
 
2483
                                        yyerror2("unknown user %s", id);
 
2484
                                        constraint_expr_destroy(expr);
 
2485
                                        return 0;
 
2486
                                }
 
2487
                                val = user->s.value;
 
2488
                        } else if (expr->attr & CEXPR_ROLE) {
 
2489
                                if (!is_id_in_scope(SYM_ROLES, id)) {
 
2490
                                        yyerror2("role %s is not within scope",
 
2491
                                                 id);
 
2492
                                        constraint_expr_destroy(expr);
 
2493
                                        return 0;
 
2494
                                }
 
2495
                                role =
 
2496
                                    (role_datum_t *) hashtab_search(policydbp->
 
2497
                                                                    p_roles.
 
2498
                                                                    table,
 
2499
                                                                    (hashtab_key_t)
 
2500
                                                                    id);
 
2501
                                if (!role) {
 
2502
                                        yyerror2("unknown role %s", id);
 
2503
                                        constraint_expr_destroy(expr);
 
2504
                                        return 0;
 
2505
                                }
 
2506
                                val = role->s.value;
 
2507
                        } else if (expr->attr & CEXPR_TYPE) {
 
2508
                                if (set_types(expr->type_names, id, &add, 0)) {
 
2509
                                        constraint_expr_destroy(expr);
 
2510
                                        return 0;
 
2511
                                }
 
2512
                                continue;
 
2513
                        } else {
 
2514
                                yyerror("invalid constraint expression");
 
2515
                                constraint_expr_destroy(expr);
 
2516
                                return 0;
 
2517
                        }
 
2518
                        if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
 
2519
                                yyerror("out of memory");
 
2520
                                ebitmap_destroy(&expr->names);
 
2521
                                constraint_expr_destroy(expr);
 
2522
                                return 0;
 
2523
                        }
 
2524
                        free(id);
 
2525
                }
 
2526
                ebitmap_destroy(&negset);
 
2527
                return (uintptr_t) expr;
 
2528
        default:
 
2529
                yyerror("invalid constraint expression");
 
2530
                constraint_expr_destroy(expr);
 
2531
                return 0;
 
2532
        }
 
2533
 
 
2534
        yyerror("invalid constraint expression");
 
2535
        free(expr);
 
2536
        return 0;
 
2537
}
 
2538
 
 
2539
int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f)
 
2540
{
 
2541
        cond_expr_t *e;
 
2542
        int depth;
 
2543
        cond_node_t cn, *cn_old;
 
2544
 
 
2545
        /* expression cannot be NULL */
 
2546
        if (!expr) {
 
2547
                yyerror("illegal conditional expression");
 
2548
                return -1;
 
2549
        }
 
2550
        if (!t) {
 
2551
                if (!f) {
 
2552
                        /* empty is fine, destroy expression and return */
 
2553
                        cond_expr_destroy(expr);
 
2554
                        return 0;
 
2555
                }
 
2556
                /* Invert */
 
2557
                t = f;
 
2558
                f = 0;
 
2559
                expr = define_cond_expr(COND_NOT, expr, 0);
 
2560
                if (!expr) {
 
2561
                        yyerror("unable to invert");
 
2562
                        return -1;
 
2563
                }
 
2564
        }
 
2565
 
 
2566
        /* verify expression */
 
2567
        depth = -1;
 
2568
        for (e = expr; e; e = e->next) {
 
2569
                switch (e->expr_type) {
 
2570
                case COND_NOT:
 
2571
                        if (depth < 0) {
 
2572
                                yyerror
 
2573
                                    ("illegal conditional expression; Bad NOT");
 
2574
                                return -1;
 
2575
                        }
 
2576
                        break;
 
2577
                case COND_AND:
 
2578
                case COND_OR:
 
2579
                case COND_XOR:
 
2580
                case COND_EQ:
 
2581
                case COND_NEQ:
 
2582
                        if (depth < 1) {
 
2583
                                yyerror
 
2584
                                    ("illegal conditional expression; Bad binary op");
 
2585
                                return -1;
 
2586
                        }
 
2587
                        depth--;
 
2588
                        break;
 
2589
                case COND_BOOL:
 
2590
                        if (depth == (COND_EXPR_MAXDEPTH - 1)) {
 
2591
                                yyerror
 
2592
                                    ("conditional expression is like totally too deep");
 
2593
                                return -1;
 
2594
                        }
 
2595
                        depth++;
 
2596
                        break;
 
2597
                default:
 
2598
                        yyerror("illegal conditional expression");
 
2599
                        return -1;
 
2600
                }
 
2601
        }
 
2602
        if (depth != 0) {
 
2603
                yyerror("illegal conditional expression");
 
2604
                return -1;
 
2605
        }
 
2606
 
 
2607
        /*  use tmp conditional node to partially build new node */
 
2608
        memset(&cn, 0, sizeof(cn));
 
2609
        cn.expr = expr;
 
2610
        cn.avtrue_list = t;
 
2611
        cn.avfalse_list = f;
 
2612
 
 
2613
        /* normalize/precompute expression */
 
2614
        if (cond_normalize_expr(policydbp, &cn) < 0) {
 
2615
                yyerror("problem normalizing conditional expression");
 
2616
                return -1;
 
2617
        }
 
2618
 
 
2619
        /* get the existing conditional node, or create a new one */
 
2620
        cn_old = get_current_cond_list(&cn);
 
2621
        if (!cn_old) {
 
2622
                return -1;
 
2623
        }
 
2624
 
 
2625
        append_cond_list(&cn);
 
2626
 
 
2627
        /* note that there is no check here for duplicate rules, nor
 
2628
         * check that rule already exists in base -- that will be
 
2629
         * handled during conditional expansion, in expand.c */
 
2630
 
 
2631
        cn.avtrue_list = NULL;
 
2632
        cn.avfalse_list = NULL;
 
2633
        cond_node_destroy(&cn);
 
2634
 
 
2635
        return 0;
 
2636
}
 
2637
 
 
2638
cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
 
2639
{
 
2640
        struct cond_expr *expr, *e1 = NULL, *e2;
 
2641
        cond_bool_datum_t *bool_var;
 
2642
        char *id;
 
2643
 
 
2644
        /* expressions are handled in the second pass */
 
2645
        if (pass == 1) {
 
2646
                if (expr_type == COND_BOOL) {
 
2647
                        while ((id = queue_remove(id_queue))) {
 
2648
                                free(id);
 
2649
                        }
 
2650
                }
 
2651
                return (cond_expr_t *) 1;       /* any non-NULL value */
 
2652
        }
 
2653
 
 
2654
        /* create a new expression struct */
 
2655
        expr = malloc(sizeof(struct cond_expr));
 
2656
        if (!expr) {
 
2657
                yyerror("out of memory");
 
2658
                return NULL;
 
2659
        }
 
2660
        memset(expr, 0, sizeof(cond_expr_t));
 
2661
        expr->expr_type = expr_type;
 
2662
 
 
2663
        /* create the type asked for */
 
2664
        switch (expr_type) {
 
2665
        case COND_NOT:
 
2666
                e1 = NULL;
 
2667
                e2 = (struct cond_expr *)arg1;
 
2668
                while (e2) {
 
2669
                        e1 = e2;
 
2670
                        e2 = e2->next;
 
2671
                }
 
2672
                if (!e1 || e1->next) {
 
2673
                        yyerror("illegal conditional NOT expression");
 
2674
                        free(expr);
 
2675
                        return NULL;
 
2676
                }
 
2677
                e1->next = expr;
 
2678
                return (struct cond_expr *)arg1;
 
2679
        case COND_AND:
 
2680
        case COND_OR:
 
2681
        case COND_XOR:
 
2682
        case COND_EQ:
 
2683
        case COND_NEQ:
 
2684
                e1 = NULL;
 
2685
                e2 = (struct cond_expr *)arg1;
 
2686
                while (e2) {
 
2687
                        e1 = e2;
 
2688
                        e2 = e2->next;
 
2689
                }
 
2690
                if (!e1 || e1->next) {
 
2691
                        yyerror
 
2692
                            ("illegal left side of conditional binary op expression");
 
2693
                        free(expr);
 
2694
                        return NULL;
 
2695
                }
 
2696
                e1->next = (struct cond_expr *)arg2;
 
2697
 
 
2698
                e1 = NULL;
 
2699
                e2 = (struct cond_expr *)arg2;
 
2700
                while (e2) {
 
2701
                        e1 = e2;
 
2702
                        e2 = e2->next;
 
2703
                }
 
2704
                if (!e1 || e1->next) {
 
2705
                        yyerror
 
2706
                            ("illegal right side of conditional binary op expression");
 
2707
                        free(expr);
 
2708
                        return NULL;
 
2709
                }
 
2710
                e1->next = expr;
 
2711
                return (struct cond_expr *)arg1;
 
2712
        case COND_BOOL:
 
2713
                id = (char *)queue_remove(id_queue);
 
2714
                if (!id) {
 
2715
                        yyerror("bad conditional; expected boolean id");
 
2716
                        free(id);
 
2717
                        free(expr);
 
2718
                        return NULL;
 
2719
                }
 
2720
                if (!is_id_in_scope(SYM_BOOLS, id)) {
 
2721
                        yyerror2("boolean %s is not within scope", id);
 
2722
                        free(id);
 
2723
                        free(expr);
 
2724
                        return NULL;
 
2725
                }
 
2726
                bool_var =
 
2727
                    (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.
 
2728
                                                         table,
 
2729
                                                         (hashtab_key_t) id);
 
2730
                if (!bool_var) {
 
2731
                        yyerror2("unknown boolean %s in conditional expression",
 
2732
                                 id);
 
2733
                        free(expr);
 
2734
                        free(id);
 
2735
                        return NULL;
 
2736
                }
 
2737
                expr->bool = bool_var->s.value;
 
2738
                free(id);
 
2739
                return expr;
 
2740
        default:
 
2741
                yyerror("illegal conditional expression");
 
2742
                return NULL;
 
2743
        }
 
2744
}
 
2745
 
 
2746
static int set_user_roles(role_set_t * set, char *id)
 
2747
{
 
2748
        role_datum_t *r;
 
2749
        unsigned int i;
 
2750
        ebitmap_node_t *node;
 
2751
 
 
2752
        if (strcmp(id, "*") == 0) {
 
2753
                free(id);
 
2754
                yyerror("* is not allowed in user declarations");
 
2755
                return -1;
 
2756
        }
 
2757
 
 
2758
        if (strcmp(id, "~") == 0) {
 
2759
                free(id);
 
2760
                yyerror("~ is not allowed in user declarations");
 
2761
                return -1;
 
2762
        }
 
2763
 
 
2764
        if (!is_id_in_scope(SYM_ROLES, id)) {
 
2765
                yyerror2("role %s is not within scope", id);
 
2766
                free(id);
 
2767
                return -1;
 
2768
        }
 
2769
        r = hashtab_search(policydbp->p_roles.table, id);
 
2770
        if (!r) {
 
2771
                yyerror2("unknown role %s", id);
 
2772
                free(id);
 
2773
                return -1;
 
2774
        }
 
2775
 
 
2776
        /* set the role and every role it dominates */
 
2777
        ebitmap_for_each_bit(&r->dominates, node, i) {
 
2778
                if (ebitmap_node_get_bit(node, i))
 
2779
                        if (ebitmap_set_bit(&set->roles, i, TRUE))
 
2780
                                goto oom;
 
2781
        }
 
2782
        free(id);
 
2783
        return 0;
 
2784
      oom:
 
2785
        yyerror("out of memory");
 
2786
        return -1;
 
2787
}
 
2788
 
 
2789
static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
 
2790
{
 
2791
        cat_datum_t *cdatum;
 
2792
        int range_start, range_end, i;
 
2793
 
 
2794
        if (id_has_dot(id)) {
 
2795
                char *id_start = id;
 
2796
                char *id_end = strchr(id, '.');
 
2797
 
 
2798
                *(id_end++) = '\0';
 
2799
 
 
2800
                cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
 
2801
                                                        (hashtab_key_t)
 
2802
                                                        id_start);
 
2803
                if (!cdatum) {
 
2804
                        yyerror2("unknown category %s", id_start);
 
2805
                        return -1;
 
2806
                }
 
2807
                range_start = cdatum->s.value - 1;
 
2808
                cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
 
2809
                                                        (hashtab_key_t) id_end);
 
2810
                if (!cdatum) {
 
2811
                        yyerror2("unknown category %s", id_end);
 
2812
                        return -1;
 
2813
                }
 
2814
                range_end = cdatum->s.value - 1;
 
2815
 
 
2816
                if (range_end < range_start) {
 
2817
                        yyerror2("category range is invalid");
 
2818
                        return -1;
 
2819
                }
 
2820
        } else {
 
2821
                cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
 
2822
                                                        (hashtab_key_t) id);
 
2823
                if (!cdatum) {
 
2824
                        yyerror2("unknown category %s", id);
 
2825
                        return -1;
 
2826
                }
 
2827
                range_start = range_end = cdatum->s.value - 1;
 
2828
        }
 
2829
 
 
2830
        for (i = range_start; i <= range_end; i++) {
 
2831
                if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
 
2832
                        uint32_t level_value = levdatum->level->sens - 1;
 
2833
                        policydb_index_others(NULL, policydbp, 0);
 
2834
                        yyerror2("category %s can not be associated "
 
2835
                                 "with level %s",
 
2836
                                 policydbp->p_cat_val_to_name[i],
 
2837
                                 policydbp->p_sens_val_to_name[level_value]);
 
2838
                        return -1;
 
2839
                }
 
2840
                if (ebitmap_set_bit(cats, i, TRUE)) {
 
2841
                        yyerror("out of memory");
 
2842
                        return -1;
 
2843
                }
 
2844
        }
 
2845
 
 
2846
        return 0;
 
2847
}
 
2848
 
 
2849
static int parse_semantic_categories(char *id, level_datum_t * levdatum,
 
2850
                                     mls_semantic_cat_t ** cats)
 
2851
{
 
2852
        cat_datum_t *cdatum;
 
2853
        mls_semantic_cat_t *newcat;
 
2854
        unsigned int range_start, range_end;
 
2855
 
 
2856
        if (id_has_dot(id)) {
 
2857
                char *id_start = id;
 
2858
                char *id_end = strchr(id, '.');
 
2859
 
 
2860
                *(id_end++) = '\0';
 
2861
 
 
2862
                cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
 
2863
                                                        (hashtab_key_t)
 
2864
                                                        id_start);
 
2865
                if (!cdatum) {
 
2866
                        yyerror2("unknown category %s", id_start);
 
2867
                        return -1;
 
2868
                }
 
2869
                range_start = cdatum->s.value;
 
2870
 
 
2871
                cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
 
2872
                                                        (hashtab_key_t) id_end);
 
2873
                if (!cdatum) {
 
2874
                        yyerror2("unknown category %s", id_end);
 
2875
                        return -1;
 
2876
                }
 
2877
                range_end = cdatum->s.value;
 
2878
        } else {
 
2879
                cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
 
2880
                                                        (hashtab_key_t) id);
 
2881
                if (!cdatum) {
 
2882
                        yyerror2("unknown category %s", id);
 
2883
                        return -1;
 
2884
                }
 
2885
                range_start = range_end = cdatum->s.value;
 
2886
        }
 
2887
 
 
2888
        newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
 
2889
        if (!newcat) {
 
2890
                yyerror("out of memory");
 
2891
                return -1;
 
2892
        }
 
2893
 
 
2894
        mls_semantic_cat_init(newcat);
 
2895
        newcat->next = *cats;
 
2896
        newcat->low = range_start;
 
2897
        newcat->high = range_end;
 
2898
 
 
2899
        *cats = newcat;
 
2900
 
 
2901
        return 0;
 
2902
}
 
2903
 
 
2904
int define_user(void)
 
2905
{
 
2906
        char *id;
 
2907
        user_datum_t *usrdatum;
 
2908
        level_datum_t *levdatum;
 
2909
        int l;
 
2910
 
 
2911
        if (pass == 1) {
 
2912
                while ((id = queue_remove(id_queue)))
 
2913
                        free(id);
 
2914
                if (mlspol) {
 
2915
                        while ((id = queue_remove(id_queue)))
 
2916
                                free(id);
 
2917
                        id = queue_remove(id_queue);
 
2918
                        free(id);
 
2919
                        for (l = 0; l < 2; l++) {
 
2920
                                while ((id = queue_remove(id_queue))) {
 
2921
                                        free(id);
 
2922
                                }
 
2923
                                id = queue_remove(id_queue);
 
2924
                                if (!id)
 
2925
                                        break;
 
2926
                                free(id);
 
2927
                        }
 
2928
                }
 
2929
                return 0;
 
2930
        }
 
2931
 
 
2932
        if ((usrdatum = declare_user()) == NULL) {
 
2933
                return -1;
 
2934
        }
 
2935
 
 
2936
        while ((id = queue_remove(id_queue))) {
 
2937
                if (set_user_roles(&usrdatum->roles, id))
 
2938
                        continue;
 
2939
        }
 
2940
 
 
2941
        if (mlspol) {
 
2942
                id = queue_remove(id_queue);
 
2943
                if (!id) {
 
2944
                        yyerror("no default level specified for user");
 
2945
                        return -1;
 
2946
                }
 
2947
 
 
2948
                levdatum = (level_datum_t *)
 
2949
                    hashtab_search(policydbp->p_levels.table,
 
2950
                                   (hashtab_key_t) id);
 
2951
                if (!levdatum) {
 
2952
                        yyerror2("unknown sensitivity %s used in user"
 
2953
                                 " level definition", id);
 
2954
                        free(id);
 
2955
                        return -1;
 
2956
                }
 
2957
                free(id);
 
2958
 
 
2959
                usrdatum->dfltlevel.sens = levdatum->level->sens;
 
2960
 
 
2961
                while ((id = queue_remove(id_queue))) {
 
2962
                        if (parse_semantic_categories(id, levdatum,
 
2963
                                                    &usrdatum->dfltlevel.cat)) {
 
2964
                                free(id);
 
2965
                                return -1;
 
2966
                        }
 
2967
                        free(id);
 
2968
                }
 
2969
 
 
2970
                id = queue_remove(id_queue);
 
2971
 
 
2972
                for (l = 0; l < 2; l++) {
 
2973
                        levdatum = (level_datum_t *)
 
2974
                            hashtab_search(policydbp->p_levels.table,
 
2975
                                           (hashtab_key_t) id);
 
2976
                        if (!levdatum) {
 
2977
                                yyerror2("unknown sensitivity %s used in user"
 
2978
                                         " range definition", id);
 
2979
                                free(id);
 
2980
                                return -1;
 
2981
                        }
 
2982
                        free(id);
 
2983
 
 
2984
                        usrdatum->range.level[l].sens = levdatum->level->sens;
 
2985
 
 
2986
                        while ((id = queue_remove(id_queue))) {
 
2987
                                if (parse_semantic_categories(id, levdatum,
 
2988
                                               &usrdatum->range.level[l].cat)) {
 
2989
                                        free(id);
 
2990
                                        return -1;
 
2991
                                }
 
2992
                                free(id);
 
2993
                        }
 
2994
 
 
2995
                        id = queue_remove(id_queue);
 
2996
                        if (!id)
 
2997
                                break;
 
2998
                }
 
2999
 
 
3000
                if (l == 0) {
 
3001
                        if (mls_semantic_level_cpy(&usrdatum->range.level[1],
 
3002
                                                   &usrdatum->range.level[0])) {
 
3003
                                yyerror("out of memory");
 
3004
                                return -1;
 
3005
                        }
 
3006
                }
 
3007
        }
 
3008
        return 0;
 
3009
}
 
3010
 
 
3011
static int parse_security_context(context_struct_t * c)
 
3012
{
 
3013
        char *id;
 
3014
        role_datum_t *role;
 
3015
        type_datum_t *typdatum;
 
3016
        user_datum_t *usrdatum;
 
3017
        level_datum_t *levdatum;
 
3018
        int l;
 
3019
 
 
3020
        if (pass == 1) {
 
3021
                id = queue_remove(id_queue);
 
3022
                free(id);       /* user  */
 
3023
                id = queue_remove(id_queue);
 
3024
                free(id);       /* role  */
 
3025
                id = queue_remove(id_queue);
 
3026
                free(id);       /* type  */
 
3027
                if (mlspol) {
 
3028
                        id = queue_remove(id_queue);
 
3029
                        free(id);
 
3030
                        for (l = 0; l < 2; l++) {
 
3031
                                while ((id = queue_remove(id_queue))) {
 
3032
                                        free(id);
 
3033
                                }
 
3034
                                id = queue_remove(id_queue);
 
3035
                                if (!id)
 
3036
                                        break;
 
3037
                                free(id);
 
3038
                        }
 
3039
                }
 
3040
                return 0;
 
3041
        }
 
3042
 
 
3043
        context_init(c);
 
3044
 
 
3045
        /* extract the user */
 
3046
        id = queue_remove(id_queue);
 
3047
        if (!id) {
 
3048
                yyerror("no effective user?");
 
3049
                goto bad;
 
3050
        }
 
3051
        if (!is_id_in_scope(SYM_USERS, id)) {
 
3052
                yyerror2("user %s is not within scope", id);
 
3053
                free(id);
 
3054
                goto bad;
 
3055
        }
 
3056
        usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
 
3057
                                                   (hashtab_key_t) id);
 
3058
        if (!usrdatum) {
 
3059
                yyerror2("user %s is not defined", id);
 
3060
                free(id);
 
3061
                goto bad;
 
3062
        }
 
3063
        c->user = usrdatum->s.value;
 
3064
 
 
3065
        /* no need to keep the user name */
 
3066
        free(id);
 
3067
 
 
3068
        /* extract the role */
 
3069
        id = (char *)queue_remove(id_queue);
 
3070
        if (!id) {
 
3071
                yyerror("no role name for sid context definition?");
 
3072
                return -1;
 
3073
        }
 
3074
        if (!is_id_in_scope(SYM_ROLES, id)) {
 
3075
                yyerror2("role %s is not within scope", id);
 
3076
                free(id);
 
3077
                return -1;
 
3078
        }
 
3079
        role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
 
3080
                                               (hashtab_key_t) id);
 
3081
        if (!role) {
 
3082
                yyerror2("role %s is not defined", id);
 
3083
                free(id);
 
3084
                return -1;
 
3085
        }
 
3086
        c->role = role->s.value;
 
3087
 
 
3088
        /* no need to keep the role name */
 
3089
        free(id);
 
3090
 
 
3091
        /* extract the type */
 
3092
        id = (char *)queue_remove(id_queue);
 
3093
        if (!id) {
 
3094
                yyerror("no type name for sid context definition?");
 
3095
                return -1;
 
3096
        }
 
3097
        if (!is_id_in_scope(SYM_TYPES, id)) {
 
3098
                yyerror2("type %s is not within scope", id);
 
3099
                free(id);
 
3100
                return -1;
 
3101
        }
 
3102
        typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
 
3103
                                                   (hashtab_key_t) id);
 
3104
        if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
 
3105
                yyerror2("type %s is not defined or is an attribute", id);
 
3106
                free(id);
 
3107
                return -1;
 
3108
        }
 
3109
        c->type = typdatum->s.value;
 
3110
 
 
3111
        /* no need to keep the type name */
 
3112
        free(id);
 
3113
 
 
3114
        if (mlspol) {
 
3115
                /* extract the low sensitivity */
 
3116
                id = (char *)queue_head(id_queue);
 
3117
                if (!id) {
 
3118
                        yyerror("no sensitivity name for sid context"
 
3119
                                " definition?");
 
3120
                        return -1;
 
3121
                }
 
3122
 
 
3123
                id = (char *)queue_remove(id_queue);
 
3124
                for (l = 0; l < 2; l++) {
 
3125
                        levdatum = (level_datum_t *)
 
3126
                            hashtab_search(policydbp->p_levels.table,
 
3127
                                           (hashtab_key_t) id);
 
3128
                        if (!levdatum) {
 
3129
                                yyerror2("Sensitivity %s is not defined", id);
 
3130
                                free(id);
 
3131
                                return -1;
 
3132
                        }
 
3133
                        free(id);
 
3134
                        c->range.level[l].sens = levdatum->level->sens;
 
3135
 
 
3136
                        /* extract low category set */
 
3137
                        while ((id = queue_remove(id_queue))) {
 
3138
                                if (parse_categories(id, levdatum,
 
3139
                                                     &c->range.level[l].cat)) {
 
3140
                                        free(id);
 
3141
                                        return -1;
 
3142
                                }
 
3143
                                free(id);
 
3144
                        }
 
3145
 
 
3146
                        /* extract high sensitivity */
 
3147
                        id = (char *)queue_remove(id_queue);
 
3148
                        if (!id)
 
3149
                                break;
 
3150
                }
 
3151
 
 
3152
                if (l == 0) {
 
3153
                        c->range.level[1].sens = c->range.level[0].sens;
 
3154
                        if (ebitmap_cpy(&c->range.level[1].cat,
 
3155
                                        &c->range.level[0].cat)) {
 
3156
 
 
3157
                                yyerror("out of memory");
 
3158
                                goto bad;
 
3159
                        }
 
3160
                }
 
3161
        }
 
3162
 
 
3163
        if (!policydb_context_isvalid(policydbp, c)) {
 
3164
                yyerror("invalid security context");
 
3165
                goto bad;
 
3166
        }
 
3167
        return 0;
 
3168
 
 
3169
      bad:
 
3170
        context_destroy(c);
 
3171
 
 
3172
        return -1;
 
3173
}
 
3174
 
 
3175
int define_initial_sid_context(void)
 
3176
{
 
3177
        char *id;
 
3178
        ocontext_t *c, *head;
 
3179
 
 
3180
        if (pass == 1) {
 
3181
                id = (char *)queue_remove(id_queue);
 
3182
                free(id);
 
3183
                parse_security_context(NULL);
 
3184
                return 0;
 
3185
        }
 
3186
 
 
3187
        id = (char *)queue_remove(id_queue);
 
3188
        if (!id) {
 
3189
                yyerror("no sid name for SID context definition?");
 
3190
                return -1;
 
3191
        }
 
3192
        head = policydbp->ocontexts[OCON_ISID];
 
3193
        for (c = head; c; c = c->next) {
 
3194
                if (!strcmp(id, c->u.name))
 
3195
                        break;
 
3196
        }
 
3197
 
 
3198
        if (!c) {
 
3199
                yyerror2("SID %s is not defined", id);
 
3200
                free(id);
 
3201
                return -1;
 
3202
        }
 
3203
        if (c->context[0].user) {
 
3204
                yyerror2("The context for SID %s is multiply defined", id);
 
3205
                free(id);
 
3206
                return -1;
 
3207
        }
 
3208
        /* no need to keep the sid name */
 
3209
        free(id);
 
3210
 
 
3211
        if (parse_security_context(&c->context[0]))
 
3212
                return -1;
 
3213
 
 
3214
        return 0;
 
3215
}
 
3216
 
 
3217
int define_fs_context(unsigned int major, unsigned int minor)
 
3218
{
 
3219
        ocontext_t *newc, *c, *head;
 
3220
 
 
3221
        if (pass == 1) {
 
3222
                parse_security_context(NULL);
 
3223
                parse_security_context(NULL);
 
3224
                return 0;
 
3225
        }
 
3226
 
 
3227
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
 
3228
        if (!newc) {
 
3229
                yyerror("out of memory");
 
3230
                return -1;
 
3231
        }
 
3232
        memset(newc, 0, sizeof(ocontext_t));
 
3233
 
 
3234
        newc->u.name = (char *)malloc(6);
 
3235
        if (!newc->u.name) {
 
3236
                yyerror("out of memory");
 
3237
                free(newc);
 
3238
                return -1;
 
3239
        }
 
3240
        sprintf(newc->u.name, "%02x:%02x", major, minor);
 
3241
 
 
3242
        if (parse_security_context(&newc->context[0])) {
 
3243
                free(newc->u.name);
 
3244
                free(newc);
 
3245
                return -1;
 
3246
        }
 
3247
        if (parse_security_context(&newc->context[1])) {
 
3248
                context_destroy(&newc->context[0]);
 
3249
                free(newc->u.name);
 
3250
                free(newc);
 
3251
                return -1;
 
3252
        }
 
3253
        head = policydbp->ocontexts[OCON_FS];
 
3254
 
 
3255
        for (c = head; c; c = c->next) {
 
3256
                if (!strcmp(newc->u.name, c->u.name)) {
 
3257
                        yyerror2("duplicate entry for file system %s",
 
3258
                                 newc->u.name);
 
3259
                        context_destroy(&newc->context[0]);
 
3260
                        context_destroy(&newc->context[1]);
 
3261
                        free(newc->u.name);
 
3262
                        free(newc);
 
3263
                        return -1;
 
3264
                }
 
3265
        }
 
3266
 
 
3267
        newc->next = head;
 
3268
        policydbp->ocontexts[OCON_FS] = newc;
 
3269
 
 
3270
        return 0;
 
3271
}
 
3272
 
 
3273
int define_port_context(unsigned int low, unsigned int high)
 
3274
{
 
3275
        ocontext_t *newc, *c, *l, *head;
 
3276
        unsigned int protocol;
 
3277
        char *id;
 
3278
 
 
3279
        if (pass == 1) {
 
3280
                id = (char *)queue_remove(id_queue);
 
3281
                free(id);
 
3282
                parse_security_context(NULL);
 
3283
                return 0;
 
3284
        }
 
3285
 
 
3286
        newc = malloc(sizeof(ocontext_t));
 
3287
        if (!newc) {
 
3288
                yyerror("out of memory");
 
3289
                return -1;
 
3290
        }
 
3291
        memset(newc, 0, sizeof(ocontext_t));
 
3292
 
 
3293
        id = (char *)queue_remove(id_queue);
 
3294
        if (!id) {
 
3295
                free(newc);
 
3296
                return -1;
 
3297
        }
 
3298
        if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
 
3299
                protocol = IPPROTO_TCP;
 
3300
        } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
 
3301
                protocol = IPPROTO_UDP;
 
3302
        } else {
 
3303
                yyerror2("unrecognized protocol %s", id);
 
3304
                free(newc);
 
3305
                return -1;
 
3306
        }
 
3307
 
 
3308
        newc->u.port.protocol = protocol;
 
3309
        newc->u.port.low_port = low;
 
3310
        newc->u.port.high_port = high;
 
3311
 
 
3312
        if (low > high) {
 
3313
                yyerror2("low port %d exceeds high port %d", low, high);
 
3314
                free(newc);
 
3315
                return -1;
 
3316
        }
 
3317
 
 
3318
        if (parse_security_context(&newc->context[0])) {
 
3319
                free(newc);
 
3320
                return -1;
 
3321
        }
 
3322
 
 
3323
        /* Preserve the matching order specified in the configuration. */
 
3324
        head = policydbp->ocontexts[OCON_PORT];
 
3325
        for (l = NULL, c = head; c; l = c, c = c->next) {
 
3326
                unsigned int prot2, low2, high2;
 
3327
 
 
3328
                prot2 = c->u.port.protocol;
 
3329
                low2 = c->u.port.low_port;
 
3330
                high2 = c->u.port.high_port;
 
3331
                if (protocol != prot2)
 
3332
                        continue;
 
3333
                if (low == low2 && high == high2) {
 
3334
                        yyerror2("duplicate portcon entry for %s %d-%d ", id,
 
3335
                                 low, high);
 
3336
                        goto bad;
 
3337
                }
 
3338
                if (low2 <= low && high2 >= high) {
 
3339
                        yyerror2("portcon entry for %s %d-%d hidden by earlier "
 
3340
                                 "entry for %d-%d", id, low, high, low2, high2);
 
3341
                        goto bad;
 
3342
                }
 
3343
        }
 
3344
 
 
3345
        if (l)
 
3346
                l->next = newc;
 
3347
        else
 
3348
                policydbp->ocontexts[OCON_PORT] = newc;
 
3349
 
 
3350
        return 0;
 
3351
 
 
3352
      bad:
 
3353
        free(newc);
 
3354
        return -1;
 
3355
}
 
3356
 
 
3357
int define_netif_context(void)
 
3358
{
 
3359
        ocontext_t *newc, *c, *head;
 
3360
 
 
3361
        if (pass == 1) {
 
3362
                free(queue_remove(id_queue));
 
3363
                parse_security_context(NULL);
 
3364
                parse_security_context(NULL);
 
3365
                return 0;
 
3366
        }
 
3367
 
 
3368
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
 
3369
        if (!newc) {
 
3370
                yyerror("out of memory");
 
3371
                return -1;
 
3372
        }
 
3373
        memset(newc, 0, sizeof(ocontext_t));
 
3374
 
 
3375
        newc->u.name = (char *)queue_remove(id_queue);
 
3376
        if (!newc->u.name) {
 
3377
                free(newc);
 
3378
                return -1;
 
3379
        }
 
3380
        if (parse_security_context(&newc->context[0])) {
 
3381
                free(newc->u.name);
 
3382
                free(newc);
 
3383
                return -1;
 
3384
        }
 
3385
        if (parse_security_context(&newc->context[1])) {
 
3386
                context_destroy(&newc->context[0]);
 
3387
                free(newc->u.name);
 
3388
                free(newc);
 
3389
                return -1;
 
3390
        }
 
3391
        head = policydbp->ocontexts[OCON_NETIF];
 
3392
 
 
3393
        for (c = head; c; c = c->next) {
 
3394
                if (!strcmp(newc->u.name, c->u.name)) {
 
3395
                        yyerror2("duplicate entry for network interface %s",
 
3396
                                 newc->u.name);
 
3397
                        context_destroy(&newc->context[0]);
 
3398
                        context_destroy(&newc->context[1]);
 
3399
                        free(newc->u.name);
 
3400
                        free(newc);
 
3401
                        return -1;
 
3402
                }
 
3403
        }
 
3404
 
 
3405
        newc->next = head;
 
3406
        policydbp->ocontexts[OCON_NETIF] = newc;
 
3407
        return 0;
 
3408
}
 
3409
 
 
3410
int define_ipv4_node_context()
 
3411
{       
 
3412
        char *id;
 
3413
        int rc = 0;
 
3414
        struct in_addr addr, mask;
 
3415
        ocontext_t *newc, *c, *l, *head;
 
3416
 
 
3417
        if (pass == 1) {
 
3418
                free(queue_remove(id_queue));
 
3419
                free(queue_remove(id_queue));
 
3420
                parse_security_context(NULL);
 
3421
                goto out;
 
3422
        }
 
3423
 
 
3424
        id = queue_remove(id_queue);
 
3425
        if (!id) {
 
3426
                yyerror("failed to read ipv4 address");
 
3427
                rc = -1;
 
3428
                goto out;
 
3429
        }
 
3430
 
 
3431
        rc = inet_pton(AF_INET, id, &addr);
 
3432
        free(id);
 
3433
        if (rc < 1) {
 
3434
                yyerror("failed to parse ipv4 address");
 
3435
                if (rc == 0)
 
3436
                        rc = -1;
 
3437
                goto out;
 
3438
        }
 
3439
 
 
3440
        id = queue_remove(id_queue);
 
3441
        if (!id) {
 
3442
                yyerror("failed to read ipv4 address");
 
3443
                rc = -1;
 
3444
                goto out;
 
3445
        }
 
3446
 
 
3447
        rc = inet_pton(AF_INET, id, &mask);
 
3448
        free(id);
 
3449
        if (rc < 1) {
 
3450
                yyerror("failed to parse ipv4 mask");
 
3451
                if (rc == 0)
 
3452
                        rc = -1;
 
3453
                goto out;
 
3454
        }
 
3455
 
 
3456
        newc = malloc(sizeof(ocontext_t));
 
3457
        if (!newc) {
 
3458
                yyerror("out of memory");
 
3459
                rc = -1;
 
3460
                goto out;
 
3461
        }
 
3462
 
 
3463
        memset(newc, 0, sizeof(ocontext_t));
 
3464
        newc->u.node.addr = addr.s_addr;
 
3465
        newc->u.node.mask = mask.s_addr;
 
3466
 
 
3467
        if (parse_security_context(&newc->context[0])) {
 
3468
                free(newc);
 
3469
                return -1;
 
3470
        }
 
3471
 
 
3472
        /* Create order of most specific to least retaining
 
3473
           the order specified in the configuration. */
 
3474
        head = policydbp->ocontexts[OCON_NODE];
 
3475
        for (l = NULL, c = head; c; l = c, c = c->next) {
 
3476
                if (newc->u.node.mask > c->u.node.mask)
 
3477
                        break;
 
3478
        }
 
3479
 
 
3480
        newc->next = c;
 
3481
 
 
3482
        if (l)
 
3483
                l->next = newc;
 
3484
        else
 
3485
                policydbp->ocontexts[OCON_NODE] = newc;
 
3486
        rc = 0;
 
3487
out:
 
3488
        return rc;
 
3489
}
 
3490
 
 
3491
int define_ipv6_node_context(void)
 
3492
{
 
3493
        char *id;
 
3494
        int rc = 0;
 
3495
        struct in6_addr addr, mask;
 
3496
        ocontext_t *newc, *c, *l, *head;
 
3497
 
 
3498
        if (pass == 1) {
 
3499
                free(queue_remove(id_queue));
 
3500
                free(queue_remove(id_queue));
 
3501
                parse_security_context(NULL);
 
3502
                goto out;
 
3503
        }
 
3504
 
 
3505
        id = queue_remove(id_queue);
 
3506
        if (!id) {
 
3507
                yyerror("failed to read ipv6 address");
 
3508
                rc = -1;
 
3509
                goto out;
 
3510
        }
 
3511
 
 
3512
        rc = inet_pton(AF_INET6, id, &addr);
 
3513
        free(id);
 
3514
        if (rc < 1) {
 
3515
                yyerror("failed to parse ipv6 address");
 
3516
                if (rc == 0)
 
3517
                        rc = -1;
 
3518
                goto out;
 
3519
        }
 
3520
 
 
3521
        id = queue_remove(id_queue);
 
3522
        if (!id) {
 
3523
                yyerror("failed to read ipv6 address");
 
3524
                rc = -1;
 
3525
                goto out;
 
3526
        }
 
3527
 
 
3528
        rc = inet_pton(AF_INET6, id, &mask);
 
3529
        free(id);
 
3530
        if (rc < 1) {
 
3531
                yyerror("failed to parse ipv6 mask");
 
3532
                if (rc == 0)
 
3533
                        rc = -1;
 
3534
                goto out;
 
3535
        }
 
3536
 
 
3537
        newc = malloc(sizeof(ocontext_t));
 
3538
        if (!newc) {
 
3539
                yyerror("out of memory");
 
3540
                rc = -1;
 
3541
                goto out;
 
3542
        }
 
3543
 
 
3544
        memset(newc, 0, sizeof(ocontext_t));
 
3545
        memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
 
3546
        memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
 
3547
 
 
3548
        if (parse_security_context(&newc->context[0])) {
 
3549
                free(newc);
 
3550
                rc = -1;
 
3551
                goto out;
 
3552
        }
 
3553
 
 
3554
        /* Create order of most specific to least retaining
 
3555
           the order specified in the configuration. */
 
3556
        head = policydbp->ocontexts[OCON_NODE6];
 
3557
        for (l = NULL, c = head; c; l = c, c = c->next) {
 
3558
                if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
 
3559
                        break;
 
3560
        }
 
3561
 
 
3562
        newc->next = c;
 
3563
 
 
3564
        if (l)
 
3565
                l->next = newc;
 
3566
        else
 
3567
                policydbp->ocontexts[OCON_NODE6] = newc;
 
3568
 
 
3569
        rc = 0;
 
3570
      out:
 
3571
        return rc;
 
3572
}
 
3573
 
 
3574
int define_fs_use(int behavior)
 
3575
{
 
3576
        ocontext_t *newc, *c, *head;
 
3577
 
 
3578
        if (pass == 1) {
 
3579
                free(queue_remove(id_queue));
 
3580
                parse_security_context(NULL);
 
3581
                return 0;
 
3582
        }
 
3583
 
 
3584
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
 
3585
        if (!newc) {
 
3586
                yyerror("out of memory");
 
3587
                return -1;
 
3588
        }
 
3589
        memset(newc, 0, sizeof(ocontext_t));
 
3590
 
 
3591
        newc->u.name = (char *)queue_remove(id_queue);
 
3592
        if (!newc->u.name) {
 
3593
                free(newc);
 
3594
                return -1;
 
3595
        }
 
3596
        newc->v.behavior = behavior;
 
3597
        if (parse_security_context(&newc->context[0])) {
 
3598
                free(newc->u.name);
 
3599
                free(newc);
 
3600
                return -1;
 
3601
        }
 
3602
 
 
3603
        head = policydbp->ocontexts[OCON_FSUSE];
 
3604
 
 
3605
        for (c = head; c; c = c->next) {
 
3606
                if (!strcmp(newc->u.name, c->u.name)) {
 
3607
                        yyerror2("duplicate fs_use entry for filesystem type %s",
 
3608
                                 newc->u.name);
 
3609
                        context_destroy(&newc->context[0]);
 
3610
                        free(newc->u.name);
 
3611
                        free(newc);
 
3612
                        return -1;
 
3613
                }
 
3614
        }
 
3615
 
 
3616
        newc->next = head;
 
3617
        policydbp->ocontexts[OCON_FSUSE] = newc;
 
3618
        return 0;
 
3619
}
 
3620
 
 
3621
int define_genfs_context_helper(char *fstype, int has_type)
 
3622
{
 
3623
        struct genfs *genfs_p, *genfs, *newgenfs;
 
3624
        ocontext_t *newc, *c, *head, *p;
 
3625
        char *type = NULL;
 
3626
        int len, len2;
 
3627
 
 
3628
        if (pass == 1) {
 
3629
                free(fstype);
 
3630
                free(queue_remove(id_queue));
 
3631
                if (has_type)
 
3632
                        free(queue_remove(id_queue));
 
3633
                parse_security_context(NULL);
 
3634
                return 0;
 
3635
        }
 
3636
 
 
3637
        for (genfs_p = NULL, genfs = policydbp->genfs;
 
3638
             genfs; genfs_p = genfs, genfs = genfs->next) {
 
3639
                if (strcmp(fstype, genfs->fstype) <= 0)
 
3640
                        break;
 
3641
        }
 
3642
 
 
3643
        if (!genfs || strcmp(fstype, genfs->fstype)) {
 
3644
                newgenfs = malloc(sizeof(struct genfs));
 
3645
                if (!newgenfs) {
 
3646
                        yyerror("out of memory");
 
3647
                        return -1;
 
3648
                }
 
3649
                memset(newgenfs, 0, sizeof(struct genfs));
 
3650
                newgenfs->fstype = fstype;
 
3651
                newgenfs->next = genfs;
 
3652
                if (genfs_p)
 
3653
                        genfs_p->next = newgenfs;
 
3654
                else
 
3655
                        policydbp->genfs = newgenfs;
 
3656
                genfs = newgenfs;
 
3657
        }
 
3658
 
 
3659
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
 
3660
        if (!newc) {
 
3661
                yyerror("out of memory");
 
3662
                return -1;
 
3663
        }
 
3664
        memset(newc, 0, sizeof(ocontext_t));
 
3665
 
 
3666
        newc->u.name = (char *)queue_remove(id_queue);
 
3667
        if (!newc->u.name)
 
3668
                goto fail;
 
3669
        if (has_type) {
 
3670
                type = (char *)queue_remove(id_queue);
 
3671
                if (!type)
 
3672
                        goto fail;
 
3673
                if (type[1] != 0) {
 
3674
                        yyerror2("invalid type %s", type);
 
3675
                        goto fail;
 
3676
                }
 
3677
                switch (type[0]) {
 
3678
                case 'b':
 
3679
                        newc->v.sclass = SECCLASS_BLK_FILE;
 
3680
                        break;
 
3681
                case 'c':
 
3682
                        newc->v.sclass = SECCLASS_CHR_FILE;
 
3683
                        break;
 
3684
                case 'd':
 
3685
                        newc->v.sclass = SECCLASS_DIR;
 
3686
                        break;
 
3687
                case 'p':
 
3688
                        newc->v.sclass = SECCLASS_FIFO_FILE;
 
3689
                        break;
 
3690
                case 'l':
 
3691
                        newc->v.sclass = SECCLASS_LNK_FILE;
 
3692
                        break;
 
3693
                case 's':
 
3694
                        newc->v.sclass = SECCLASS_SOCK_FILE;
 
3695
                        break;
 
3696
                case '-':
 
3697
                        newc->v.sclass = SECCLASS_FILE;
 
3698
                        break;
 
3699
                default:
 
3700
                        yyerror2("invalid type %s", type);
 
3701
                        goto fail;
 
3702
                }
 
3703
        }
 
3704
        if (parse_security_context(&newc->context[0]))
 
3705
                goto fail;
 
3706
 
 
3707
        head = genfs->head;
 
3708
 
 
3709
        for (p = NULL, c = head; c; p = c, c = c->next) {
 
3710
                if (!strcmp(newc->u.name, c->u.name) &&
 
3711
                    (!newc->v.sclass || !c->v.sclass
 
3712
                     || newc->v.sclass == c->v.sclass)) {
 
3713
                        yyerror2("duplicate entry for genfs entry (%s, %s)",
 
3714
                                 fstype, newc->u.name);
 
3715
                        goto fail;
 
3716
                }
 
3717
                len = strlen(newc->u.name);
 
3718
                len2 = strlen(c->u.name);
 
3719
                if (len > len2)
 
3720
                        break;
 
3721
        }
 
3722
 
 
3723
        newc->next = c;
 
3724
        if (p)
 
3725
                p->next = newc;
 
3726
        else
 
3727
                genfs->head = newc;
 
3728
        return 0;
 
3729
      fail:
 
3730
        if (type)
 
3731
                free(type);
 
3732
        context_destroy(&newc->context[0]);
 
3733
        if (fstype)
 
3734
                free(fstype);
 
3735
        if (newc->u.name)
 
3736
                free(newc->u.name);
 
3737
        free(newc);
 
3738
        return -1;
 
3739
}
 
3740
 
 
3741
int define_genfs_context(int has_type)
 
3742
{
 
3743
        return define_genfs_context_helper(queue_remove(id_queue), has_type);
 
3744
}
 
3745
 
 
3746
int define_range_trans(int class_specified)
 
3747
{
 
3748
        char *id;
 
3749
        level_datum_t *levdatum = 0;
 
3750
        class_datum_t *cladatum;
 
3751
        range_trans_rule_t *rule;
 
3752
        int l, add = 1;
 
3753
 
 
3754
        if (!mlspol) {
 
3755
                yyerror("range_transition rule in non-MLS configuration");
 
3756
                return -1;
 
3757
        }
 
3758
 
 
3759
        if (pass == 1) {
 
3760
                while ((id = queue_remove(id_queue)))
 
3761
                        free(id);
 
3762
                while ((id = queue_remove(id_queue)))
 
3763
                        free(id);
 
3764
                if (class_specified)
 
3765
                        while ((id = queue_remove(id_queue)))
 
3766
                                free(id);
 
3767
                id = queue_remove(id_queue);
 
3768
                free(id);
 
3769
                for (l = 0; l < 2; l++) {
 
3770
                        while ((id = queue_remove(id_queue))) {
 
3771
                                free(id);
 
3772
                        }
 
3773
                        id = queue_remove(id_queue);
 
3774
                        if (!id)
 
3775
                                break;
 
3776
                        free(id);
 
3777
                }
 
3778
                return 0;
 
3779
        }
 
3780
 
 
3781
        rule = malloc(sizeof(struct range_trans_rule));
 
3782
        if (!rule) {
 
3783
                yyerror("out of memory");
 
3784
                return -1;
 
3785
        }
 
3786
        range_trans_rule_init(rule);
 
3787
 
 
3788
        while ((id = queue_remove(id_queue))) {
 
3789
                if (set_types(&rule->stypes, id, &add, 0))
 
3790
                        goto out;
 
3791
        }
 
3792
        add = 1;
 
3793
        while ((id = queue_remove(id_queue))) {
 
3794
                if (set_types(&rule->ttypes, id, &add, 0))
 
3795
                        goto out;
 
3796
        }
 
3797
 
 
3798
        if (class_specified) {
 
3799
                while ((id = queue_remove(id_queue))) {
 
3800
                        if (!is_id_in_scope(SYM_CLASSES, id)) {
 
3801
                                yyerror2("class %s is not within scope", id);
 
3802
                                free(id);
 
3803
                                goto out;
 
3804
                        }
 
3805
                        cladatum = hashtab_search(policydbp->p_classes.table,
 
3806
                                                  id);
 
3807
                        if (!cladatum) {
 
3808
                                yyerror2("unknown class %s", id);
 
3809
                                goto out;
 
3810
                        }
 
3811
 
 
3812
                        ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1,
 
3813
                                        TRUE);
 
3814
                        free(id);
 
3815
                }
 
3816
        } else {
 
3817
                cladatum = hashtab_search(policydbp->p_classes.table,
 
3818
                                          "process");
 
3819
                if (!cladatum) {
 
3820
                        yyerror2("could not find process class for "
 
3821
                                 "legacy range_transition statement");
 
3822
                        goto out;
 
3823
                }
 
3824
 
 
3825
                ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE);
 
3826
        }
 
3827
 
 
3828
        id = (char *)queue_remove(id_queue);
 
3829
        if (!id) {
 
3830
                yyerror("no range in range_transition definition?");
 
3831
                goto out;
 
3832
        }
 
3833
        for (l = 0; l < 2; l++) {
 
3834
                levdatum = hashtab_search(policydbp->p_levels.table, id);
 
3835
                if (!levdatum) {
 
3836
                        yyerror2("unknown level %s used in range_transition "
 
3837
                                 "definition", id);
 
3838
                        free(id);
 
3839
                        goto out;
 
3840
                }
 
3841
                free(id);
 
3842
 
 
3843
                rule->trange.level[l].sens = levdatum->level->sens;
 
3844
 
 
3845
                while ((id = queue_remove(id_queue))) {
 
3846
                        if (parse_semantic_categories(id, levdatum,
 
3847
                                                  &rule->trange.level[l].cat)) {
 
3848
                                free(id);
 
3849
                                goto out;
 
3850
                        }
 
3851
                        free(id);
 
3852
                }
 
3853
 
 
3854
                id = (char *)queue_remove(id_queue);
 
3855
                if (!id)
 
3856
                        break;
 
3857
        }
 
3858
        if (l == 0) {
 
3859
                if (mls_semantic_level_cpy(&rule->trange.level[1],
 
3860
                                           &rule->trange.level[0])) {
 
3861
                        yyerror("out of memory");
 
3862
                        goto out;
 
3863
                }
 
3864
        }
 
3865
 
 
3866
        append_range_trans(rule);
 
3867
        return 0;
 
3868
 
 
3869
out:
 
3870
        range_trans_rule_destroy(rule);
 
3871
        return -1;
 
3872
}
 
3873
 
 
3874
/* FLASK */