~ubuntu-branches/ubuntu/natty/checkpolicy/natty

« back to all changes in this revision

Viewing changes to policy_parse.y

  • 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:
19
19
 *      Added support for binary policy modules
20
20
 *
21
21
 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
22
 
 * Copyright (C) 2003 - 2005 Tresys Technology, LLC
 
22
 * Copyright (C) 2003 - 2008 Tresys Technology, LLC
23
23
 * Copyright (C) 2007 Red Hat Inc.
24
24
 *      This program is free software; you can redistribute it and/or modify
25
25
 *      it under the terms of the GNU General Public License as published by
51
51
#include "queue.h"
52
52
#include "checkpolicy.h"
53
53
#include "module_compiler.h"
54
 
 
55
 
/* 
56
 
 * We need the following so we have a valid error return code in yacc
57
 
 * when we have a parse error for a conditional rule.  We can't check 
58
 
 * for NULL (ie 0) because that is a potentially valid return.
59
 
 */
60
 
static avrule_t *conditional_unused_error_code;
61
 
#define COND_ERR (avrule_t *)&conditional_unused_error_code
62
 
 
63
 
#define TRUE 1
64
 
#define FALSE 0
65
 
 
66
 
policydb_t *policydbp;
67
 
queue_t id_queue = 0;
68
 
static unsigned int pass;
69
 
char *curfile = 0;
70
 
int mlspol = 0;
71
 
int handle_unknown = 0;
72
 
 
73
 
extern unsigned long policydb_lineno;
74
 
extern unsigned long source_lineno;
75
 
extern unsigned int policydb_errors;
76
 
extern unsigned int policyvers;
 
54
#include "policy_define.h"
 
55
 
 
56
extern policydb_t *policydbp;
 
57
extern unsigned int pass;
77
58
 
78
59
extern char yytext[];
79
60
extern int yylex(void);
80
61
extern int yywarn(char *msg);
81
62
extern int yyerror(char *msg);
82
63
 
83
 
#define ERRORMSG_LEN 255
84
 
static char errormsg[ERRORMSG_LEN + 1] = {0};
85
 
 
86
 
static int insert_separator(int push);
87
 
static int insert_id(char *id,int push);
88
 
static int id_has_dot(char *id);
89
 
static int define_class(void);
90
 
static int define_initial_sid(void);
91
 
static int define_common_perms(void);
92
 
static int define_av_perms(int inherits);
93
 
static int define_sens(void);
94
 
static int define_dominance(void);
95
 
static int define_category(void);
96
 
static int define_level(void);
97
 
static int define_attrib(void);
98
 
static int define_typealias(void);
99
 
static int define_typeattribute(void);
100
 
static int define_type(int alias);
101
 
static int define_compute_type(int which);
102
 
static int define_te_avtab(int which);
103
 
static int define_role_types(void);
104
 
static role_datum_t *merge_roles_dom(role_datum_t *r1,role_datum_t *r2);
105
 
static role_datum_t *define_role_dom(role_datum_t *r);
106
 
static int define_role_trans(void);
107
 
static int define_range_trans(int class_specified);
108
 
static int define_role_allow(void);
109
 
static int define_constraint(constraint_expr_t *expr);
110
 
static int define_validatetrans(constraint_expr_t *expr);
111
 
static int define_bool(void);
112
 
static int define_conditional(cond_expr_t *expr, avrule_t *t_list, avrule_t *f_list );
113
 
static cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void* arg2);
114
 
static avrule_t *define_cond_pol_list(avrule_t *avlist, avrule_t *stmt);
115
 
static avrule_t *define_cond_compute_type(int which);
116
 
static avrule_t *define_cond_te_avtab(int which);
117
 
static uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2);
118
 
static int define_user(void);
119
 
static int parse_security_context(context_struct_t *c);
120
 
static int define_initial_sid_context(void);
121
 
static int define_fs_use(int behavior);
122
 
static int define_genfs_context(int has_type);
123
 
static int define_fs_context(unsigned int major, unsigned int minor);
124
 
static int define_port_context(unsigned int low, unsigned int high);
125
 
static int define_netif_context(void);
126
 
static int define_ipv4_node_context(void);
127
 
static int define_ipv6_node_context(void);
128
 
static int define_polcap(void);
129
 
 
130
64
typedef int (* require_func_t)();
131
65
 
132
66
%}
201
135
%token IPV6_ADDR
202
136
%token MODULE VERSION_IDENTIFIER REQUIRE OPTIONAL
203
137
%token POLICYCAP
 
138
%token PERMISSIVE
204
139
 
205
140
%left OR
206
141
%left XOR
327
262
                        | transition_def
328
263
                        | range_trans_def
329
264
                        | te_avtab_def
 
265
                        | permissive_def
330
266
                        ;
331
267
attribute_def           : ATTRIBUTE identifier ';'
332
268
                        { if (define_attrib()) return -1;}
772
708
policycap_def           : POLICYCAP identifier ';'
773
709
                        {if (define_polcap()) return -1;}
774
710
                        ;
 
711
permissive_def          : PERMISSIVE identifier ';'
 
712
                        {if (define_permissive()) return -1;}
775
713
 
776
714
/*********** module grammar below ***********/
777
715
 
785
723
                        ;
786
724
version_identifier      : VERSION_IDENTIFIER
787
725
                        { if (insert_id(yytext,0)) return -1; }
 
726
                        | ipv4_addr_def /* version can look like ipv4 address */
788
727
                        ;
789
728
avrules_block           : avrule_decls avrule_user_defs
790
729
                        ;
840
779
avrule_user_defs        : user_def avrule_user_defs
841
780
                        | /* empty */
842
781
                        ;
843
 
%%
844
 
 
845
 
/* initialize all of the state variables for the scanner/parser */
846
 
void init_parser(int pass_number)
847
 
{
848
 
        policydb_lineno = 1;
849
 
        source_lineno = 1;
850
 
        policydb_errors = 0;
851
 
        pass = pass_number;
852
 
}
853
 
 
854
 
void yyerror2(char *fmt, ...)
855
 
{
856
 
        va_list ap;
857
 
        va_start(ap, fmt);
858
 
        vsnprintf(errormsg, ERRORMSG_LEN, fmt, ap);
859
 
        yyerror(errormsg);
860
 
        va_end(ap);
861
 
}
862
 
 
863
 
#define DEBUG 1
864
 
 
865
 
static int insert_separator(int push)
866
 
{
867
 
        int error;
868
 
 
869
 
        if (push)
870
 
                error = queue_push(id_queue, 0);
871
 
        else
872
 
                error = queue_insert(id_queue, 0);
873
 
 
874
 
        if (error) {
875
 
                yyerror("queue overflow");
876
 
                return -1;
877
 
        }
878
 
        return 0;
879
 
}
880
 
 
881
 
static int insert_id(char *id, int push)
882
 
{
883
 
        char *newid = 0;
884
 
        int error;
885
 
 
886
 
        newid = (char *)malloc(strlen(id) + 1);
887
 
        if (!newid) {
888
 
                yyerror("out of memory");
889
 
                return -1;
890
 
        }
891
 
        strcpy(newid, id);
892
 
        if (push)
893
 
                error = queue_push(id_queue, (queue_element_t) newid);
894
 
        else
895
 
                error = queue_insert(id_queue, (queue_element_t) newid);
896
 
 
897
 
        if (error) {
898
 
                yyerror("queue overflow");
899
 
                free(newid);
900
 
                return -1;
901
 
        }
902
 
        return 0;
903
 
}
904
 
 
905
 
/* If the identifier has a dot within it and that its first character
906
 
   is not a dot then return 1, else return 0. */
907
 
static int id_has_dot(char *id)
908
 
{
909
 
        if (strchr(id, '.') >= id + 1) {
910
 
                return 1;
911
 
        }
912
 
        return 0;
913
 
}
914
 
 
915
 
static int define_class(void)
916
 
{
917
 
        char *id = 0;
918
 
        class_datum_t *datum = 0;
919
 
        int ret;
920
 
        uint32_t value;
921
 
 
922
 
        if (pass == 2) {
923
 
                id = queue_remove(id_queue);
924
 
                free(id);
925
 
                return 0;
926
 
        }
927
 
 
928
 
        id = (char *)queue_remove(id_queue);
929
 
        if (!id) {
930
 
                yyerror("no class name for class definition?");
931
 
                return -1;
932
 
        }
933
 
        datum = (class_datum_t *) malloc(sizeof(class_datum_t));
934
 
        if (!datum) {
935
 
                yyerror("out of memory");
936
 
                goto bad;
937
 
        }
938
 
        memset(datum, 0, sizeof(class_datum_t));
939
 
        ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value);
940
 
        switch (ret) {
941
 
        case -3:{
942
 
                        yyerror("Out of memory!");
943
 
                        goto bad;
944
 
                }
945
 
        case -2:{
946
 
                        yyerror2("duplicate declaration of class %s", id);
947
 
                        goto bad;
948
 
                }
949
 
        case -1:{
950
 
                        yyerror("could not declare class here");
951
 
                        goto bad;
952
 
                }
953
 
        case 0:
954
 
        case 1:{
955
 
                        break;
956
 
                }
957
 
        default:{
958
 
                        assert(0);      /* should never get here */
959
 
                }
960
 
        }
961
 
        datum->s.value = value;
962
 
        return 0;
963
 
 
964
 
      bad:
965
 
        if (id)
966
 
                free(id);
967
 
        if (datum)
968
 
                free(datum);
969
 
        return -1;
970
 
}
971
 
 
972
 
static int define_polcap(void)
973
 
{
974
 
        char *id = 0;
975
 
        int capnum;
976
 
 
977
 
        if (pass == 2) {
978
 
                id = queue_remove(id_queue);
979
 
                free(id);
980
 
                return 0;
981
 
        }
982
 
 
983
 
        id = (char *)queue_remove(id_queue);
984
 
        if (!id) {
985
 
                yyerror("no capability name for policycap definition?");
986
 
                goto bad;
987
 
        }
988
 
 
989
 
        /* Check for valid cap name -> number mapping */
990
 
        capnum = sepol_polcap_getnum(id);
991
 
        if (capnum < 0) {
992
 
                yyerror2("invalid policy capability name %s", id);
993
 
                goto bad;
994
 
        }
995
 
 
996
 
        /* Store it */
997
 
        if (ebitmap_set_bit(&policydbp->policycaps, capnum, TRUE)) {
998
 
                yyerror("out of memory");
999
 
                goto bad;
1000
 
        }
1001
 
 
1002
 
        free(id);
1003
 
        return 0;
1004
 
 
1005
 
      bad:
1006
 
        free(id);
1007
 
        return -1;
1008
 
}
1009
 
 
1010
 
static int define_initial_sid(void)
1011
 
{
1012
 
        char *id = 0;
1013
 
        ocontext_t *newc = 0, *c, *head;
1014
 
 
1015
 
        if (pass == 2) {
1016
 
                id = queue_remove(id_queue);
1017
 
                free(id);
1018
 
                return 0;
1019
 
        }
1020
 
 
1021
 
        id = (char *)queue_remove(id_queue);
1022
 
        if (!id) {
1023
 
                yyerror("no sid name for SID definition?");
1024
 
                return -1;
1025
 
        }
1026
 
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
1027
 
        if (!newc) {
1028
 
                yyerror("out of memory");
1029
 
                goto bad;
1030
 
        }
1031
 
        memset(newc, 0, sizeof(ocontext_t));
1032
 
        newc->u.name = id;
1033
 
        context_init(&newc->context[0]);
1034
 
        head = policydbp->ocontexts[OCON_ISID];
1035
 
 
1036
 
        for (c = head; c; c = c->next) {
1037
 
                if (!strcmp(newc->u.name, c->u.name)) {
1038
 
                        sprintf(errormsg, "duplicate initial SID %s", id);
1039
 
                        yyerror(errormsg);
1040
 
                        goto bad;
1041
 
                }
1042
 
        }
1043
 
 
1044
 
        if (head) {
1045
 
                newc->sid[0] = head->sid[0] + 1;
1046
 
        } else {
1047
 
                newc->sid[0] = 1;
1048
 
        }
1049
 
        newc->next = head;
1050
 
        policydbp->ocontexts[OCON_ISID] = newc;
1051
 
 
1052
 
        return 0;
1053
 
 
1054
 
      bad:
1055
 
        if (id)
1056
 
                free(id);
1057
 
        if (newc)
1058
 
                free(newc);
1059
 
        return -1;
1060
 
}
1061
 
 
1062
 
static int define_common_perms(void)
1063
 
{
1064
 
        char *id = 0, *perm = 0;
1065
 
        common_datum_t *comdatum = 0;
1066
 
        perm_datum_t *perdatum = 0;
1067
 
        int ret;
1068
 
 
1069
 
        if (pass == 2) {
1070
 
                while ((id = queue_remove(id_queue)))
1071
 
                        free(id);
1072
 
                return 0;
1073
 
        }
1074
 
 
1075
 
        id = (char *)queue_remove(id_queue);
1076
 
        if (!id) {
1077
 
                yyerror("no common name for common perm definition?");
1078
 
                return -1;
1079
 
        }
1080
 
        comdatum = hashtab_search(policydbp->p_commons.table, id);
1081
 
        if (comdatum) {
1082
 
                snprintf(errormsg, ERRORMSG_LEN,
1083
 
                         "duplicate declaration for common %s\n", id);
1084
 
                yyerror(errormsg);
1085
 
                return -1;
1086
 
        }
1087
 
        comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
1088
 
        if (!comdatum) {
1089
 
                yyerror("out of memory");
1090
 
                goto bad;
1091
 
        }
1092
 
        memset(comdatum, 0, sizeof(common_datum_t));
1093
 
        ret = hashtab_insert(policydbp->p_commons.table,
1094
 
                             (hashtab_key_t) id, (hashtab_datum_t) comdatum);
1095
 
 
1096
 
        if (ret == SEPOL_EEXIST) {
1097
 
                yyerror("duplicate common definition");
1098
 
                goto bad;
1099
 
        }
1100
 
        if (ret == SEPOL_ENOMEM) {
1101
 
                yyerror("hash table overflow");
1102
 
                goto bad;
1103
 
        }
1104
 
        comdatum->s.value = policydbp->p_commons.nprim + 1;
1105
 
        if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
1106
 
                yyerror("out of memory");
1107
 
                goto bad;
1108
 
        }
1109
 
        policydbp->p_commons.nprim++;
1110
 
        while ((perm = queue_remove(id_queue))) {
1111
 
                perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
1112
 
                if (!perdatum) {
1113
 
                        yyerror("out of memory");
1114
 
                        goto bad_perm;
1115
 
                }
1116
 
                memset(perdatum, 0, sizeof(perm_datum_t));
1117
 
                perdatum->s.value = comdatum->permissions.nprim + 1;
1118
 
 
1119
 
                if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
1120
 
                        yyerror
1121
 
                            ("too many permissions to fit in an access vector");
1122
 
                        goto bad_perm;
1123
 
                }
1124
 
                ret = hashtab_insert(comdatum->permissions.table,
1125
 
                                     (hashtab_key_t) perm,
1126
 
                                     (hashtab_datum_t) perdatum);
1127
 
 
1128
 
                if (ret == SEPOL_EEXIST) {
1129
 
                        sprintf(errormsg,
1130
 
                                "duplicate permission %s in common %s", perm,
1131
 
                                id);
1132
 
                        yyerror(errormsg);
1133
 
                        goto bad_perm;
1134
 
                }
1135
 
                if (ret == SEPOL_ENOMEM) {
1136
 
                        yyerror("hash table overflow");
1137
 
                        goto bad_perm;
1138
 
                }
1139
 
                comdatum->permissions.nprim++;
1140
 
        }
1141
 
 
1142
 
        return 0;
1143
 
 
1144
 
      bad:
1145
 
        if (id)
1146
 
                free(id);
1147
 
        if (comdatum)
1148
 
                free(comdatum);
1149
 
        return -1;
1150
 
 
1151
 
      bad_perm:
1152
 
        if (perm)
1153
 
                free(perm);
1154
 
        if (perdatum)
1155
 
                free(perdatum);
1156
 
        return -1;
1157
 
}
1158
 
 
1159
 
static int define_av_perms(int inherits)
1160
 
{
1161
 
        char *id;
1162
 
        class_datum_t *cladatum;
1163
 
        common_datum_t *comdatum;
1164
 
        perm_datum_t *perdatum = 0, *perdatum2 = 0;
1165
 
        int ret;
1166
 
 
1167
 
        if (pass == 2) {
1168
 
                while ((id = queue_remove(id_queue)))
1169
 
                        free(id);
1170
 
                return 0;
1171
 
        }
1172
 
 
1173
 
        id = (char *)queue_remove(id_queue);
1174
 
        if (!id) {
1175
 
                yyerror("no tclass name for av perm definition?");
1176
 
                return -1;
1177
 
        }
1178
 
        cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
1179
 
                                                    (hashtab_key_t) id);
1180
 
        if (!cladatum) {
1181
 
                sprintf(errormsg, "class %s is not defined", id);
1182
 
                yyerror(errormsg);
1183
 
                goto bad;
1184
 
        }
1185
 
        free(id);
1186
 
 
1187
 
        if (cladatum->comdatum || cladatum->permissions.nprim) {
1188
 
                yyerror("duplicate access vector definition");
1189
 
                return -1;
1190
 
        }
1191
 
        if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) {
1192
 
                yyerror("out of memory");
1193
 
                return -1;
1194
 
        }
1195
 
        if (inherits) {
1196
 
                id = (char *)queue_remove(id_queue);
1197
 
                if (!id) {
1198
 
                        yyerror
1199
 
                            ("no inherits name for access vector definition?");
1200
 
                        return -1;
1201
 
                }
1202
 
                comdatum =
1203
 
                    (common_datum_t *) hashtab_search(policydbp->p_commons.
1204
 
                                                      table,
1205
 
                                                      (hashtab_key_t) id);
1206
 
 
1207
 
                if (!comdatum) {
1208
 
                        sprintf(errormsg, "common %s is not defined", id);
1209
 
                        yyerror(errormsg);
1210
 
                        goto bad;
1211
 
                }
1212
 
                cladatum->comkey = id;
1213
 
                cladatum->comdatum = comdatum;
1214
 
 
1215
 
                /*
1216
 
                 * Class-specific permissions start with values 
1217
 
                 * after the last common permission.
1218
 
                 */
1219
 
                cladatum->permissions.nprim += comdatum->permissions.nprim;
1220
 
        }
1221
 
        while ((id = queue_remove(id_queue))) {
1222
 
                perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
1223
 
                if (!perdatum) {
1224
 
                        yyerror("out of memory");
1225
 
                        goto bad;
1226
 
                }
1227
 
                memset(perdatum, 0, sizeof(perm_datum_t));
1228
 
                perdatum->s.value = ++cladatum->permissions.nprim;
1229
 
 
1230
 
                if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
1231
 
                        yyerror
1232
 
                            ("too many permissions to fit in an access vector");
1233
 
                        goto bad;
1234
 
                }
1235
 
                if (inherits) {
1236
 
                        /*
1237
 
                         * Class-specific permissions and 
1238
 
                         * common permissions exist in the same
1239
 
                         * name space.
1240
 
                         */
1241
 
                        perdatum2 =
1242
 
                            (perm_datum_t *) hashtab_search(cladatum->comdatum->
1243
 
                                                            permissions.table,
1244
 
                                                            (hashtab_key_t) id);
1245
 
                        if (perdatum2) {
1246
 
                                sprintf(errormsg,
1247
 
                                        "permission %s conflicts with an inherited permission",
1248
 
                                        id);
1249
 
                                yyerror(errormsg);
1250
 
                                goto bad;
1251
 
                        }
1252
 
                }
1253
 
                ret = hashtab_insert(cladatum->permissions.table,
1254
 
                                     (hashtab_key_t) id,
1255
 
                                     (hashtab_datum_t) perdatum);
1256
 
 
1257
 
                if (ret == SEPOL_EEXIST) {
1258
 
                        sprintf(errormsg, "duplicate permission %s", id);
1259
 
                        yyerror(errormsg);
1260
 
                        goto bad;
1261
 
                }
1262
 
                if (ret == SEPOL_ENOMEM) {
1263
 
                        yyerror("hash table overflow");
1264
 
                        goto bad;
1265
 
                }
1266
 
                if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) {
1267
 
                        yyerror("out of memory");
1268
 
                        goto bad;
1269
 
                }
1270
 
        }
1271
 
 
1272
 
        return 0;
1273
 
 
1274
 
      bad:
1275
 
        if (id)
1276
 
                free(id);
1277
 
        if (perdatum)
1278
 
                free(perdatum);
1279
 
        return -1;
1280
 
}
1281
 
 
1282
 
static int define_sens(void)
1283
 
{
1284
 
        char *id;
1285
 
        mls_level_t *level = 0;
1286
 
        level_datum_t *datum = 0, *aliasdatum = 0;
1287
 
        int ret;
1288
 
        uint32_t value;         /* dummy variable -- its value is never used */
1289
 
 
1290
 
        if (!mlspol) {
1291
 
                yyerror("sensitivity definition in non-MLS configuration");
1292
 
                return -1;
1293
 
        }
1294
 
 
1295
 
        if (pass == 2) {
1296
 
                while ((id = queue_remove(id_queue)))
1297
 
                        free(id);
1298
 
                return 0;
1299
 
        }
1300
 
 
1301
 
        id = (char *)queue_remove(id_queue);
1302
 
        if (!id) {
1303
 
                yyerror("no sensitivity name for sensitivity definition?");
1304
 
                return -1;
1305
 
        }
1306
 
        if (id_has_dot(id)) {
1307
 
                yyerror("sensitivity identifiers may not contain periods");
1308
 
                goto bad;
1309
 
        }
1310
 
        level = (mls_level_t *) malloc(sizeof(mls_level_t));
1311
 
        if (!level) {
1312
 
                yyerror("out of memory");
1313
 
                goto bad;
1314
 
        }
1315
 
        mls_level_init(level);
1316
 
        level->sens = 0;        /* actual value set in define_dominance */
1317
 
        ebitmap_init(&level->cat);      /* actual value set in define_level */
1318
 
 
1319
 
        datum = (level_datum_t *) malloc(sizeof(level_datum_t));
1320
 
        if (!datum) {
1321
 
                yyerror("out of memory");
1322
 
                goto bad;
1323
 
        }
1324
 
        level_datum_init(datum);
1325
 
        datum->isalias = FALSE;
1326
 
        datum->level = level;
1327
 
 
1328
 
        ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value);
1329
 
        switch (ret) {
1330
 
        case -3:{
1331
 
                        yyerror("Out of memory!");
1332
 
                        goto bad;
1333
 
                }
1334
 
        case -2:{
1335
 
                        yyerror("duplicate declaration of sensitivity level");
1336
 
                        goto bad;
1337
 
                }
1338
 
        case -1:{
1339
 
                        yyerror("could not declare sensitivity level here");
1340
 
                        goto bad;
1341
 
                }
1342
 
        case 0:
1343
 
        case 1:{
1344
 
                        break;
1345
 
                }
1346
 
        default:{
1347
 
                        assert(0);      /* should never get here */
1348
 
                }
1349
 
        }
1350
 
 
1351
 
        while ((id = queue_remove(id_queue))) {
1352
 
                if (id_has_dot(id)) {
1353
 
                        yyerror("sensitivity aliases may not contain periods");
1354
 
                        goto bad_alias;
1355
 
                }
1356
 
                aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t));
1357
 
                if (!aliasdatum) {
1358
 
                        yyerror("out of memory");
1359
 
                        goto bad_alias;
1360
 
                }
1361
 
                level_datum_init(aliasdatum);
1362
 
                aliasdatum->isalias = TRUE;
1363
 
                aliasdatum->level = level;
1364
 
 
1365
 
                ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value);
1366
 
                switch (ret) {
1367
 
                case -3:{
1368
 
                                yyerror("Out of memory!");
1369
 
                                goto bad_alias;
1370
 
                        }
1371
 
                case -2:{
1372
 
                                yyerror
1373
 
                                    ("duplicate declaration of sensitivity alias");
1374
 
                                goto bad_alias;
1375
 
                        }
1376
 
                case -1:{
1377
 
                                yyerror
1378
 
                                    ("could not declare sensitivity alias here");
1379
 
                                goto bad_alias;
1380
 
                        }
1381
 
                case 0:
1382
 
                case 1:{
1383
 
                                break;
1384
 
                        }
1385
 
                default:{
1386
 
                                assert(0);      /* should never get here */
1387
 
                        }
1388
 
                }
1389
 
        }
1390
 
 
1391
 
        return 0;
1392
 
 
1393
 
      bad:
1394
 
        if (id)
1395
 
                free(id);
1396
 
        if (level)
1397
 
                free(level);
1398
 
        if (datum) {
1399
 
                level_datum_destroy(datum);
1400
 
                free(datum);
1401
 
        }
1402
 
        return -1;
1403
 
 
1404
 
      bad_alias:
1405
 
        if (id)
1406
 
                free(id);
1407
 
        if (aliasdatum) {
1408
 
                level_datum_destroy(aliasdatum);
1409
 
                free(aliasdatum);
1410
 
        }
1411
 
        return -1;
1412
 
}
1413
 
 
1414
 
static int define_dominance(void)
1415
 
{
1416
 
        level_datum_t *datum;
1417
 
        int order;
1418
 
        char *id;
1419
 
 
1420
 
        if (!mlspol) {
1421
 
                yyerror("dominance definition in non-MLS configuration");
1422
 
                return -1;
1423
 
        }
1424
 
 
1425
 
        if (pass == 2) {
1426
 
                while ((id = queue_remove(id_queue)))
1427
 
                        free(id);
1428
 
                return 0;
1429
 
        }
1430
 
 
1431
 
        order = 0;
1432
 
        while ((id = (char *)queue_remove(id_queue))) {
1433
 
                datum =
1434
 
                    (level_datum_t *) hashtab_search(policydbp->p_levels.table,
1435
 
                                                     (hashtab_key_t) id);
1436
 
                if (!datum) {
1437
 
                        sprintf(errormsg,
1438
 
                                "unknown sensitivity %s used in dominance definition",
1439
 
                                id);
1440
 
                        yyerror(errormsg);
1441
 
                        free(id);
1442
 
                        return -1;
1443
 
                }
1444
 
                if (datum->level->sens != 0) {
1445
 
                        sprintf(errormsg,
1446
 
                                "sensitivity %s occurs multiply in dominance definition",
1447
 
                                id);
1448
 
                        yyerror(errormsg);
1449
 
                        free(id);
1450
 
                        return -1;
1451
 
                }
1452
 
                datum->level->sens = ++order;
1453
 
 
1454
 
                /* no need to keep sensitivity name */
1455
 
                free(id);
1456
 
        }
1457
 
 
1458
 
        if (order != policydbp->p_levels.nprim) {
1459
 
                yyerror
1460
 
                    ("all sensitivities must be specified in dominance definition");
1461
 
                return -1;
1462
 
        }
1463
 
        return 0;
1464
 
}
1465
 
 
1466
 
static int define_category(void)
1467
 
{
1468
 
        char *id;
1469
 
        cat_datum_t *datum = 0, *aliasdatum = 0;
1470
 
        int ret;
1471
 
        uint32_t value;
1472
 
 
1473
 
        if (!mlspol) {
1474
 
                yyerror("category definition in non-MLS configuration");
1475
 
                return -1;
1476
 
        }
1477
 
 
1478
 
        if (pass == 2) {
1479
 
                while ((id = queue_remove(id_queue)))
1480
 
                        free(id);
1481
 
                return 0;
1482
 
        }
1483
 
 
1484
 
        id = (char *)queue_remove(id_queue);
1485
 
        if (!id) {
1486
 
                yyerror("no category name for category definition?");
1487
 
                return -1;
1488
 
        }
1489
 
        if (id_has_dot(id)) {
1490
 
                yyerror("category identifiers may not contain periods");
1491
 
                goto bad;
1492
 
        }
1493
 
        datum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
1494
 
        if (!datum) {
1495
 
                yyerror("out of memory");
1496
 
                goto bad;
1497
 
        }
1498
 
        cat_datum_init(datum);
1499
 
        datum->isalias = FALSE;
1500
 
 
1501
 
        ret = declare_symbol(SYM_CATS, id, datum, &value, &value);
1502
 
        switch (ret) {
1503
 
        case -3:{
1504
 
                        yyerror("Out of memory!");
1505
 
                        goto bad;
1506
 
                }
1507
 
        case -2:{
1508
 
                        yyerror("duplicate declaration of category");
1509
 
                        goto bad;
1510
 
                }
1511
 
        case -1:{
1512
 
                        yyerror("could not declare category here");
1513
 
                        goto bad;
1514
 
                }
1515
 
        case 0:
1516
 
        case 1:{
1517
 
                        break;
1518
 
                }
1519
 
        default:{
1520
 
                        assert(0);      /* should never get here */
1521
 
                }
1522
 
        }
1523
 
        datum->s.value = value;
1524
 
 
1525
 
        while ((id = queue_remove(id_queue))) {
1526
 
                if (id_has_dot(id)) {
1527
 
                        yyerror("category aliases may not contain periods");
1528
 
                        goto bad_alias;
1529
 
                }
1530
 
                aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
1531
 
                if (!aliasdatum) {
1532
 
                        yyerror("out of memory");
1533
 
                        goto bad_alias;
1534
 
                }
1535
 
                cat_datum_init(aliasdatum);
1536
 
                aliasdatum->isalias = TRUE;
1537
 
                aliasdatum->s.value = datum->s.value;
1538
 
 
1539
 
                ret =
1540
 
                    declare_symbol(SYM_CATS, id, aliasdatum, NULL,
1541
 
                                   &datum->s.value);
1542
 
                switch (ret) {
1543
 
                case -3:{
1544
 
                                yyerror("Out of memory!");
1545
 
                                goto bad_alias;
1546
 
                        }
1547
 
                case -2:{
1548
 
                                yyerror
1549
 
                                    ("duplicate declaration of category aliases");
1550
 
                                goto bad_alias;
1551
 
                        }
1552
 
                case -1:{
1553
 
                                yyerror
1554
 
                                    ("could not declare category aliases here");
1555
 
                                goto bad_alias;
1556
 
                        }
1557
 
                case 0:
1558
 
                case 1:{
1559
 
                                break;
1560
 
                        }
1561
 
                default:{
1562
 
                                assert(0);      /* should never get here */
1563
 
                        }
1564
 
                }
1565
 
        }
1566
 
 
1567
 
        return 0;
1568
 
 
1569
 
      bad:
1570
 
        if (id)
1571
 
                free(id);
1572
 
        if (datum) {
1573
 
                cat_datum_destroy(datum);
1574
 
                free(datum);
1575
 
        }
1576
 
        return -1;
1577
 
 
1578
 
      bad_alias:
1579
 
        if (id)
1580
 
                free(id);
1581
 
        if (aliasdatum) {
1582
 
                cat_datum_destroy(aliasdatum);
1583
 
                free(aliasdatum);
1584
 
        }
1585
 
        return -1;
1586
 
}
1587
 
 
1588
 
static int clone_level(hashtab_key_t key, hashtab_datum_t datum, void *arg)
1589
 
{
1590
 
        level_datum_t *levdatum = (level_datum_t *) datum;
1591
 
        mls_level_t *level = (mls_level_t *) arg, *newlevel;
1592
 
 
1593
 
        if (levdatum->level == level) {
1594
 
                levdatum->defined = 1;
1595
 
                if (!levdatum->isalias)
1596
 
                        return 0;
1597
 
                newlevel = (mls_level_t *) malloc(sizeof(mls_level_t));
1598
 
                if (!newlevel)
1599
 
                        return -1;
1600
 
                if (mls_level_cpy(newlevel, level)) {
1601
 
                        free(newlevel);
1602
 
                        return -1;
1603
 
                }
1604
 
                levdatum->level = newlevel;
1605
 
        }
1606
 
        return 0;
1607
 
}
1608
 
 
1609
 
static int define_level(void)
1610
 
{
1611
 
        char *id;
1612
 
        level_datum_t *levdatum;
1613
 
 
1614
 
        if (!mlspol) {
1615
 
                yyerror("level definition in non-MLS configuration");
1616
 
                return -1;
1617
 
        }
1618
 
 
1619
 
        if (pass == 2) {
1620
 
                while ((id = queue_remove(id_queue)))
1621
 
                        free(id);
1622
 
                return 0;
1623
 
        }
1624
 
 
1625
 
        id = (char *)queue_remove(id_queue);
1626
 
        if (!id) {
1627
 
                yyerror("no level name for level definition?");
1628
 
                return -1;
1629
 
        }
1630
 
        levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
1631
 
                                                    (hashtab_key_t) id);
1632
 
        if (!levdatum) {
1633
 
                sprintf(errormsg,
1634
 
                        "unknown sensitivity %s used in level definition", id);
1635
 
                yyerror(errormsg);
1636
 
                free(id);
1637
 
                return -1;
1638
 
        }
1639
 
        if (ebitmap_length(&levdatum->level->cat)) {
1640
 
                sprintf(errormsg,
1641
 
                        "sensitivity %s used in multiple level definitions",
1642
 
                        id);
1643
 
                yyerror(errormsg);
1644
 
                free(id);
1645
 
                return -1;
1646
 
        }
1647
 
        free(id);
1648
 
 
1649
 
        levdatum->defined = 1;
1650
 
 
1651
 
        while ((id = queue_remove(id_queue))) {
1652
 
                cat_datum_t *cdatum;
1653
 
                int range_start, range_end, i;
1654
 
 
1655
 
                if (id_has_dot(id)) {
1656
 
                        char *id_start = id;
1657
 
                        char *id_end = strchr(id, '.');
1658
 
 
1659
 
                        *(id_end++) = '\0';
1660
 
 
1661
 
                        cdatum =
1662
 
                            (cat_datum_t *) hashtab_search(policydbp->p_cats.
1663
 
                                                           table,
1664
 
                                                           (hashtab_key_t)
1665
 
                                                           id_start);
1666
 
                        if (!cdatum) {
1667
 
                                sprintf(errormsg, "unknown category %s",
1668
 
                                        id_start);
1669
 
                                yyerror(errormsg);
1670
 
                                free(id);
1671
 
                                return -1;
1672
 
                        }
1673
 
                        range_start = cdatum->s.value - 1;
1674
 
                        cdatum =
1675
 
                            (cat_datum_t *) hashtab_search(policydbp->p_cats.
1676
 
                                                           table,
1677
 
                                                           (hashtab_key_t)
1678
 
                                                           id_end);
1679
 
                        if (!cdatum) {
1680
 
                                sprintf(errormsg, "unknown category %s",
1681
 
                                        id_end);
1682
 
                                yyerror(errormsg);
1683
 
                                free(id);
1684
 
                                return -1;
1685
 
                        }
1686
 
                        range_end = cdatum->s.value - 1;
1687
 
 
1688
 
                        if (range_end < range_start) {
1689
 
                                sprintf(errormsg, "category range is invalid");
1690
 
                                yyerror(errormsg);
1691
 
                                free(id);
1692
 
                                return -1;
1693
 
                        }
1694
 
                } else {
1695
 
                        cdatum =
1696
 
                            (cat_datum_t *) hashtab_search(policydbp->p_cats.
1697
 
                                                           table,
1698
 
                                                           (hashtab_key_t) id);
1699
 
                        range_start = range_end = cdatum->s.value - 1;
1700
 
                }
1701
 
 
1702
 
                for (i = range_start; i <= range_end; i++) {
1703
 
                        if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) {
1704
 
                                yyerror("out of memory");
1705
 
                                free(id);
1706
 
                                return -1;
1707
 
                        }
1708
 
                }
1709
 
 
1710
 
                free(id);
1711
 
        }
1712
 
 
1713
 
        if (hashtab_map
1714
 
            (policydbp->p_levels.table, clone_level, levdatum->level)) {
1715
 
                yyerror("out of memory");
1716
 
                return -1;
1717
 
        }
1718
 
 
1719
 
        return 0;
1720
 
}
1721
 
 
1722
 
static int define_attrib(void)
1723
 
{
1724
 
        if (pass == 2) {
1725
 
                free(queue_remove(id_queue));
1726
 
                return 0;
1727
 
        }
1728
 
 
1729
 
        if (declare_type(TRUE, TRUE) == NULL) {
1730
 
                return -1;
1731
 
        }
1732
 
        return 0;
1733
 
}
1734
 
 
1735
 
static int add_aliases_to_type(type_datum_t * type)
1736
 
{
1737
 
        char *id;
1738
 
        type_datum_t *aliasdatum = NULL;
1739
 
        int ret;
1740
 
        while ((id = queue_remove(id_queue))) {
1741
 
                if (id_has_dot(id)) {
1742
 
                        free(id);
1743
 
                        yyerror
1744
 
                            ("type alias identifiers may not contain periods");
1745
 
                        return -1;
1746
 
                }
1747
 
                aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
1748
 
                if (!aliasdatum) {
1749
 
                        free(id);
1750
 
                        yyerror("Out of memory!");
1751
 
                        return -1;
1752
 
                }
1753
 
                memset(aliasdatum, 0, sizeof(type_datum_t));
1754
 
                aliasdatum->s.value = type->s.value;
1755
 
 
1756
 
                ret = declare_symbol(SYM_TYPES, id, aliasdatum,
1757
 
                                     NULL, &aliasdatum->s.value);
1758
 
                switch (ret) {
1759
 
                case -3:{
1760
 
                                yyerror("Out of memory!");
1761
 
                                goto cleanup;
1762
 
                        }
1763
 
                case -2:{
1764
 
                                yyerror2("duplicate declaration of alias %s",
1765
 
                                         id);
1766
 
                                goto cleanup;
1767
 
                        }
1768
 
                case -1:{
1769
 
                                yyerror("could not declare alias here");
1770
 
                                goto cleanup;
1771
 
                        }
1772
 
                case 0:
1773
 
                case 1:{
1774
 
                                break;
1775
 
                        }
1776
 
                default:{
1777
 
                                assert(0);      /* should never get here */
1778
 
                        }
1779
 
                }
1780
 
        }
1781
 
        return 0;
1782
 
      cleanup:
1783
 
        free(id);
1784
 
        type_datum_destroy(aliasdatum);
1785
 
        free(aliasdatum);
1786
 
        return -1;
1787
 
}
1788
 
 
1789
 
static int define_typealias(void)
1790
 
{
1791
 
        char *id;
1792
 
        type_datum_t *t;
1793
 
 
1794
 
        if (pass == 2) {
1795
 
                while ((id = queue_remove(id_queue)))
1796
 
                        free(id);
1797
 
                return 0;
1798
 
        }
1799
 
 
1800
 
        id = (char *)queue_remove(id_queue);
1801
 
        if (!id) {
1802
 
                yyerror("no type name for typealias definition?");
1803
 
                return -1;
1804
 
        }
1805
 
 
1806
 
        if (!is_id_in_scope(SYM_TYPES, id)) {
1807
 
                yyerror2("type %s is not within scope", id);
1808
 
                free(id);
1809
 
                return -1;
1810
 
        }
1811
 
        t = hashtab_search(policydbp->p_types.table, id);
1812
 
        if (!t || t->flavor == TYPE_ATTRIB) {
1813
 
                sprintf(errormsg,
1814
 
                        "unknown type %s, or it was already declared as an attribute",
1815
 
                        id);
1816
 
                yyerror(errormsg);
1817
 
                free(id);
1818
 
                return -1;
1819
 
        }
1820
 
        return add_aliases_to_type(t);
1821
 
}
1822
 
 
1823
 
static int define_typeattribute(void)
1824
 
{
1825
 
        char *id;
1826
 
        type_datum_t *t, *attr;
1827
 
 
1828
 
        if (pass == 2) {
1829
 
                while ((id = queue_remove(id_queue)))
1830
 
                        free(id);
1831
 
                return 0;
1832
 
        }
1833
 
 
1834
 
        id = (char *)queue_remove(id_queue);
1835
 
        if (!id) {
1836
 
                yyerror("no type name for typeattribute definition?");
1837
 
                return -1;
1838
 
        }
1839
 
 
1840
 
        if (!is_id_in_scope(SYM_TYPES, id)) {
1841
 
                yyerror2("type %s is not within scope", id);
1842
 
                free(id);
1843
 
                return -1;
1844
 
        }
1845
 
        t = hashtab_search(policydbp->p_types.table, id);
1846
 
        if (!t || t->flavor == TYPE_ATTRIB) {
1847
 
                sprintf(errormsg, "unknown type %s", id);
1848
 
                yyerror(errormsg);
1849
 
                free(id);
1850
 
                return -1;
1851
 
        }
1852
 
 
1853
 
        while ((id = queue_remove(id_queue))) {
1854
 
                if (!is_id_in_scope(SYM_TYPES, id)) {
1855
 
                        yyerror2("attribute %s is not within scope", id);
1856
 
                        free(id);
1857
 
                        return -1;
1858
 
                }
1859
 
                attr = hashtab_search(policydbp->p_types.table, id);
1860
 
                if (!attr) {
1861
 
                        sprintf(errormsg, "attribute %s is not declared", id);
1862
 
                        /* treat it as a fatal error */
1863
 
                        yyerror(errormsg);
1864
 
                        free(id);
1865
 
                        return -1;
1866
 
                }
1867
 
 
1868
 
                if (attr->flavor != TYPE_ATTRIB) {
1869
 
                        sprintf(errormsg, "%s is a type, not an attribute", id);
1870
 
                        yyerror(errormsg);
1871
 
                        free(id);
1872
 
                        return -1;
1873
 
                }
1874
 
 
1875
 
                if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1876
 
                        yyerror("Out of memory!");
1877
 
                        return -1;
1878
 
                }
1879
 
 
1880
 
                if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) {
1881
 
                        yyerror("out of memory");
1882
 
                        return -1;
1883
 
                }
1884
 
        }
1885
 
 
1886
 
        return 0;
1887
 
}
1888
 
 
1889
 
static int define_type(int alias)
1890
 
{
1891
 
        char *id;
1892
 
        type_datum_t *datum, *attr;
1893
 
        int newattr = 0;
1894
 
 
1895
 
        if (pass == 2) {
1896
 
                while ((id = queue_remove(id_queue)))
1897
 
                        free(id);
1898
 
                if (alias) {
1899
 
                        while ((id = queue_remove(id_queue)))
1900
 
                                free(id);
1901
 
                }
1902
 
                return 0;
1903
 
        }
1904
 
 
1905
 
        if ((datum = declare_type(TRUE, FALSE)) == NULL) {
1906
 
                return -1;
1907
 
        }
1908
 
 
1909
 
        if (alias) {
1910
 
                if (add_aliases_to_type(datum) == -1) {
1911
 
                        return -1;
1912
 
                }
1913
 
        }
1914
 
 
1915
 
        while ((id = queue_remove(id_queue))) {
1916
 
                if (!is_id_in_scope(SYM_TYPES, id)) {
1917
 
                        yyerror2("attribute %s is not within scope", id);
1918
 
                        free(id);
1919
 
                        return -1;
1920
 
                }
1921
 
                attr = hashtab_search(policydbp->p_types.table, id);
1922
 
                if (!attr) {
1923
 
                        sprintf(errormsg, "attribute %s is not declared", id);
1924
 
 
1925
 
                        /* treat it as a fatal error */
1926
 
                        yyerror(errormsg);
1927
 
                        return -1;
1928
 
                } else {
1929
 
                        newattr = 0;
1930
 
                }
1931
 
 
1932
 
                if (attr->flavor != TYPE_ATTRIB) {
1933
 
                        sprintf(errormsg, "%s is a type, not an attribute", id);
1934
 
                        yyerror(errormsg);
1935
 
                        return -1;
1936
 
                }
1937
 
 
1938
 
                if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1939
 
                        yyerror("Out of memory!");
1940
 
                        return -1;
1941
 
                }
1942
 
 
1943
 
                if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) {
1944
 
                        yyerror("Out of memory");
1945
 
                        return -1;
1946
 
                }
1947
 
        }
1948
 
 
1949
 
        return 0;
1950
 
}
1951
 
 
1952
 
struct val_to_name {
1953
 
        unsigned int val;
1954
 
        char *name;
1955
 
};
1956
 
 
1957
 
/* Adds a type, given by its textual name, to a typeset.  If *add is
1958
 
   0, then add the type to the negative set; otherwise if *add is 1
1959
 
   then add it to the positive side. */
1960
 
static int set_types(type_set_t * set, char *id, int *add, char starallowed)
1961
 
{
1962
 
        type_datum_t *t;
1963
 
 
1964
 
        if (strcmp(id, "*") == 0) {
1965
 
                if (!starallowed) {
1966
 
                        yyerror("* not allowed in this type of rule");
1967
 
                        return -1;
1968
 
                }
1969
 
                /* set TYPE_STAR flag */
1970
 
                set->flags = TYPE_STAR;
1971
 
                free(id);
1972
 
                *add = 1;
1973
 
                return 0;
1974
 
        }
1975
 
 
1976
 
        if (strcmp(id, "~") == 0) {
1977
 
                if (!starallowed) {
1978
 
                        yyerror("~ not allowed in this type of rule");
1979
 
                        return -1;
1980
 
                }
1981
 
                /* complement the set */
1982
 
                set->flags = TYPE_COMP;
1983
 
                free(id);
1984
 
                *add = 1;
1985
 
                return 0;
1986
 
        }
1987
 
 
1988
 
        if (strcmp(id, "-") == 0) {
1989
 
                *add = 0;
1990
 
                free(id);
1991
 
                return 0;
1992
 
        }
1993
 
 
1994
 
        if (!is_id_in_scope(SYM_TYPES, id)) {
1995
 
                yyerror2("type %s is not within scope", id);
1996
 
                free(id);
1997
 
                return -1;
1998
 
        }
1999
 
        t = hashtab_search(policydbp->p_types.table, id);
2000
 
        if (!t) {
2001
 
                snprintf(errormsg, ERRORMSG_LEN, "unknown type %s", id);
2002
 
                yyerror(errormsg);
2003
 
                free(id);
2004
 
                return -1;
2005
 
        }
2006
 
 
2007
 
        if (*add == 0) {
2008
 
                if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE))
2009
 
                        goto oom;
2010
 
        } else {
2011
 
                if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE))
2012
 
                        goto oom;
2013
 
        }
2014
 
        free(id);
2015
 
        *add = 1;
2016
 
        return 0;
2017
 
      oom:
2018
 
        yyerror("Out of memory");
2019
 
        free(id);
2020
 
        return -1;
2021
 
}
2022
 
 
2023
 
static int define_compute_type_helper(int which, avrule_t ** rule)
2024
 
{
2025
 
        char *id;
2026
 
        type_datum_t *datum;
2027
 
        class_datum_t *cladatum;
2028
 
        ebitmap_t tclasses;
2029
 
        ebitmap_node_t *node;
2030
 
        avrule_t *avrule;
2031
 
        class_perm_node_t *perm;
2032
 
        int i, add = 1;
2033
 
 
2034
 
        avrule = malloc(sizeof(avrule_t));
2035
 
        if (!avrule) {
2036
 
                yyerror("out of memory");
2037
 
                return -1;
2038
 
        }
2039
 
        avrule_init(avrule);
2040
 
        avrule->specified = which;
2041
 
        avrule->line = policydb_lineno;
2042
 
 
2043
 
        while ((id = queue_remove(id_queue))) {
2044
 
                if (set_types(&avrule->stypes, id, &add, 0))
2045
 
                        return -1;
2046
 
        }
2047
 
        add = 1;
2048
 
        while ((id = queue_remove(id_queue))) {
2049
 
                if (set_types(&avrule->ttypes, id, &add, 0))
2050
 
                        return -1;
2051
 
        }
2052
 
 
2053
 
        ebitmap_init(&tclasses);
2054
 
        while ((id = queue_remove(id_queue))) {
2055
 
                if (!is_id_in_scope(SYM_CLASSES, id)) {
2056
 
                        yyerror2("class %s is not within scope", id);
2057
 
                        free(id);
2058
 
                        goto bad;
2059
 
                }
2060
 
                cladatum = hashtab_search(policydbp->p_classes.table, id);
2061
 
                if (!cladatum) {
2062
 
                        sprintf(errormsg, "unknown class %s", id);
2063
 
                        yyerror(errormsg);
2064
 
                        goto bad;
2065
 
                }
2066
 
                if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) {
2067
 
                        yyerror("Out of memory");
2068
 
                        goto bad;
2069
 
                }
2070
 
                free(id);
2071
 
        }
2072
 
 
2073
 
        id = (char *)queue_remove(id_queue);
2074
 
        if (!id) {
2075
 
                yyerror("no newtype?");
2076
 
                goto bad;
2077
 
        }
2078
 
        if (!is_id_in_scope(SYM_TYPES, id)) {
2079
 
                yyerror2("type %s is not within scope", id);
2080
 
                free(id);
2081
 
                goto bad;
2082
 
        }
2083
 
        datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
2084
 
                                                (hashtab_key_t) id);
2085
 
        if (!datum || datum->flavor == TYPE_ATTRIB) {
2086
 
                sprintf(errormsg, "unknown type %s", id);
2087
 
                yyerror(errormsg);
2088
 
                goto bad;
2089
 
        }
2090
 
 
2091
 
        ebitmap_for_each_bit(&tclasses, node, i) {
2092
 
                if (ebitmap_node_get_bit(node, i)) {
2093
 
                        perm = malloc(sizeof(class_perm_node_t));
2094
 
                        if (!perm) {
2095
 
                                yyerror("out of memory");
2096
 
                                return -1;
2097
 
                        }
2098
 
                        class_perm_node_init(perm);
2099
 
                        perm->class = i + 1;
2100
 
                        perm->data = datum->s.value;
2101
 
                        perm->next = avrule->perms;
2102
 
                        avrule->perms = perm;
2103
 
                }
2104
 
        }
2105
 
        ebitmap_destroy(&tclasses);
2106
 
 
2107
 
        *rule = avrule;
2108
 
        return 0;
2109
 
 
2110
 
      bad:
2111
 
        avrule_destroy(avrule);
2112
 
        free(avrule);
2113
 
        return -1;
2114
 
}
2115
 
 
2116
 
static int define_compute_type(int which)
2117
 
{
2118
 
        char *id;
2119
 
        avrule_t *avrule;
2120
 
 
2121
 
        if (pass == 1) {
2122
 
                while ((id = queue_remove(id_queue)))
2123
 
                        free(id);
2124
 
                while ((id = queue_remove(id_queue)))
2125
 
                        free(id);
2126
 
                while ((id = queue_remove(id_queue)))
2127
 
                        free(id);
2128
 
                id = queue_remove(id_queue);
2129
 
                free(id);
2130
 
                return 0;
2131
 
        }
2132
 
 
2133
 
        if (define_compute_type_helper(which, &avrule))
2134
 
                return -1;
2135
 
 
2136
 
        append_avrule(avrule);
2137
 
        return 0;
2138
 
}
2139
 
 
2140
 
static avrule_t *define_cond_compute_type(int which)
2141
 
{
2142
 
        char *id;
2143
 
        avrule_t *avrule;
2144
 
 
2145
 
        if (pass == 1) {
2146
 
                while ((id = queue_remove(id_queue)))
2147
 
                        free(id);
2148
 
                while ((id = queue_remove(id_queue)))
2149
 
                        free(id);
2150
 
                while ((id = queue_remove(id_queue)))
2151
 
                        free(id);
2152
 
                id = queue_remove(id_queue);
2153
 
                free(id);
2154
 
                return (avrule_t *) 1;
2155
 
        }
2156
 
 
2157
 
        if (define_compute_type_helper(which, &avrule))
2158
 
                return COND_ERR;
2159
 
 
2160
 
        return avrule;
2161
 
}
2162
 
 
2163
 
static int define_bool(void)
2164
 
{
2165
 
        char *id, *bool_value;
2166
 
        cond_bool_datum_t *datum;
2167
 
        int ret;
2168
 
        uint32_t value;
2169
 
 
2170
 
        if (pass == 2) {
2171
 
                while ((id = queue_remove(id_queue)))
2172
 
                        free(id);
2173
 
                return 0;
2174
 
        }
2175
 
 
2176
 
        id = (char *)queue_remove(id_queue);
2177
 
        if (!id) {
2178
 
                yyerror("no identifier for bool definition?");
2179
 
                return -1;
2180
 
        }
2181
 
        if (id_has_dot(id)) {
2182
 
                free(id);
2183
 
                yyerror("boolean identifiers may not contain periods");
2184
 
                return -1;
2185
 
        }
2186
 
        datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
2187
 
        if (!datum) {
2188
 
                yyerror("out of memory");
2189
 
                free(id);
2190
 
                return -1;
2191
 
        }
2192
 
        memset(datum, 0, sizeof(cond_bool_datum_t));
2193
 
        ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
2194
 
        switch (ret) {
2195
 
        case -3:{
2196
 
                        yyerror("Out of memory!");
2197
 
                        goto cleanup;
2198
 
                }
2199
 
        case -2:{
2200
 
                        yyerror2("duplicate declaration of boolean %s", id);
2201
 
                        goto cleanup;
2202
 
                }
2203
 
        case -1:{
2204
 
                        yyerror("could not declare boolean here");
2205
 
                        goto cleanup;
2206
 
                }
2207
 
        case 0:
2208
 
        case 1:{
2209
 
                        break;
2210
 
                }
2211
 
        default:{
2212
 
                        assert(0);      /* should never get here */
2213
 
                }
2214
 
        }
2215
 
        datum->s.value = value;
2216
 
 
2217
 
        bool_value = (char *)queue_remove(id_queue);
2218
 
        if (!bool_value) {
2219
 
                yyerror("no default value for bool definition?");
2220
 
                free(id);
2221
 
                return -1;
2222
 
        }
2223
 
 
2224
 
        datum->state = (int)(bool_value[0] == 'T') ? 1 : 0;
2225
 
        return 0;
2226
 
      cleanup:
2227
 
        cond_destroy_bool(id, datum, NULL);
2228
 
        return -1;
2229
 
}
2230
 
 
2231
 
static avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
2232
 
{
2233
 
        if (pass == 1) {
2234
 
                /* return something so we get through pass 1 */
2235
 
                return (avrule_t *) 1;
2236
 
        }
2237
 
 
2238
 
        if (sl == NULL) {
2239
 
                /* This is a require block, return previous list */
2240
 
                return avlist;
2241
 
        }
2242
 
 
2243
 
        /* prepend the new avlist to the pre-existing one */
2244
 
        sl->next = avlist;
2245
 
        return sl;
2246
 
}
2247
 
 
2248
 
static int define_te_avtab_helper(int which, avrule_t ** rule)
2249
 
{
2250
 
        char *id;
2251
 
        class_datum_t *cladatum;
2252
 
        perm_datum_t *perdatum = NULL;
2253
 
        class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
2254
 
        ebitmap_t tclasses;
2255
 
        ebitmap_node_t *node;
2256
 
        avrule_t *avrule;
2257
 
        unsigned int i;
2258
 
        int add = 1, ret = 0;
2259
 
        int suppress = 0;
2260
 
 
2261
 
        avrule = (avrule_t *) malloc(sizeof(avrule_t));
2262
 
        if (!avrule) {
2263
 
                yyerror("memory error");
2264
 
                ret = -1;
2265
 
                goto out;
2266
 
        }
2267
 
        avrule_init(avrule);
2268
 
        avrule->specified = which;
2269
 
        avrule->line = policydb_lineno;
2270
 
 
2271
 
        while ((id = queue_remove(id_queue))) {
2272
 
                if (set_types
2273
 
                    (&avrule->stypes, id, &add,
2274
 
                     which == AVRULE_NEVERALLOW ? 1 : 0)) {
2275
 
                        ret = -1;
2276
 
                        goto out;
2277
 
                }
2278
 
        }
2279
 
        add = 1;
2280
 
        while ((id = queue_remove(id_queue))) {
2281
 
                if (strcmp(id, "self") == 0) {
2282
 
                        free(id);
2283
 
                        avrule->flags |= RULE_SELF;
2284
 
                        continue;
2285
 
                }
2286
 
                if (set_types
2287
 
                    (&avrule->ttypes, id, &add,
2288
 
                     which == AVRULE_NEVERALLOW ? 1 : 0)) {
2289
 
                        ret = -1;
2290
 
                        goto out;
2291
 
                }
2292
 
        }
2293
 
 
2294
 
        ebitmap_init(&tclasses);
2295
 
        while ((id = queue_remove(id_queue))) {
2296
 
                if (!is_id_in_scope(SYM_CLASSES, id)) {
2297
 
                        yyerror2("class %s is not within scope", id);
2298
 
                        ret = -1;
2299
 
                        goto out;
2300
 
                }
2301
 
                cladatum = hashtab_search(policydbp->p_classes.table, id);
2302
 
                if (!cladatum) {
2303
 
                        sprintf(errormsg, "unknown class %s used in rule", id);
2304
 
                        yyerror(errormsg);
2305
 
                        ret = -1;
2306
 
                        goto out;
2307
 
                }
2308
 
                if (ebitmap_set_bit(&tclasses, cladatum->s.value - 1, TRUE)) {
2309
 
                        yyerror("Out of memory");
2310
 
                        ret = -1;
2311
 
                        goto out;
2312
 
                }
2313
 
                free(id);
2314
 
        }
2315
 
 
2316
 
        perms = NULL;
2317
 
        ebitmap_for_each_bit(&tclasses, node, i) {
2318
 
                if (!ebitmap_node_get_bit(node, i))
2319
 
                        continue;
2320
 
                cur_perms =
2321
 
                    (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
2322
 
                if (!cur_perms) {
2323
 
                        yyerror("out of memory");
2324
 
                        ret = -1;
2325
 
                        goto out;
2326
 
                }
2327
 
                class_perm_node_init(cur_perms);
2328
 
                cur_perms->class = i + 1;
2329
 
                if (!perms)
2330
 
                        perms = cur_perms;
2331
 
                if (tail)
2332
 
                        tail->next = cur_perms;
2333
 
                tail = cur_perms;
2334
 
        }
2335
 
 
2336
 
        while ((id = queue_remove(id_queue))) {
2337
 
                cur_perms = perms;
2338
 
                ebitmap_for_each_bit(&tclasses, node, i) {
2339
 
                        if (!ebitmap_node_get_bit(node, i))
2340
 
                                continue;
2341
 
                        cladatum = policydbp->class_val_to_struct[i];
2342
 
 
2343
 
                        if (strcmp(id, "*") == 0) {
2344
 
                                /* set all permissions in the class */
2345
 
                                cur_perms->data = ~0U;
2346
 
                                goto next;
2347
 
                        }
2348
 
 
2349
 
                        if (strcmp(id, "~") == 0) {
2350
 
                                /* complement the set */
2351
 
                                if (which == AVRULE_DONTAUDIT)
2352
 
                                        yywarn("dontaudit rule with a ~?");
2353
 
                                cur_perms->data = ~cur_perms->data;
2354
 
                                goto next;
2355
 
                        }
2356
 
 
2357
 
                        perdatum =
2358
 
                            hashtab_search(cladatum->permissions.table, id);
2359
 
                        if (!perdatum) {
2360
 
                                if (cladatum->comdatum) {
2361
 
                                        perdatum =
2362
 
                                            hashtab_search(cladatum->comdatum->
2363
 
                                                           permissions.table,
2364
 
                                                           id);
2365
 
                                }
2366
 
                        }
2367
 
                        if (!perdatum) {
2368
 
                                sprintf(errormsg,
2369
 
                                        "permission %s is not defined for class %s",
2370
 
                                        id, policydbp->p_class_val_to_name[i]);
2371
 
                                if (!suppress)
2372
 
                                        yyerror(errormsg);
2373
 
                                continue;
2374
 
                        } else
2375
 
                            if (!is_perm_in_scope
2376
 
                                (id, policydbp->p_class_val_to_name[i])) {
2377
 
                                if (!suppress) {
2378
 
                                        yyerror2
2379
 
                                            ("permission %s of class %s is not within scope",
2380
 
                                             id,
2381
 
                                             policydbp->p_class_val_to_name[i]);
2382
 
                                }
2383
 
                                continue;
2384
 
                        } else {
2385
 
                                cur_perms->data |= 1U << (perdatum->s.value - 1);
2386
 
                        }
2387
 
                      next:
2388
 
                        cur_perms = cur_perms->next;
2389
 
                }
2390
 
 
2391
 
                free(id);
2392
 
        }
2393
 
 
2394
 
        ebitmap_destroy(&tclasses);
2395
 
 
2396
 
        avrule->perms = perms;
2397
 
        *rule = avrule;
2398
 
 
2399
 
      out:
2400
 
        return ret;
2401
 
 
2402
 
}
2403
 
 
2404
 
static avrule_t *define_cond_te_avtab(int which)
2405
 
{
2406
 
        char *id;
2407
 
        avrule_t *avrule;
2408
 
        int i;
2409
 
 
2410
 
        if (pass == 1) {
2411
 
                for (i = 0; i < 4; i++) {
2412
 
                        while ((id = queue_remove(id_queue)))
2413
 
                                free(id);
2414
 
                }
2415
 
                return (avrule_t *) 1;  /* any non-NULL value */
2416
 
        }
2417
 
 
2418
 
        if (define_te_avtab_helper(which, &avrule))
2419
 
                return COND_ERR;
2420
 
 
2421
 
        return avrule;
2422
 
}
2423
 
 
2424
 
static int define_te_avtab(int which)
2425
 
{
2426
 
        char *id;
2427
 
        avrule_t *avrule;
2428
 
        int i;
2429
 
 
2430
 
        if (pass == 1) {
2431
 
                for (i = 0; i < 4; i++) {
2432
 
                        while ((id = queue_remove(id_queue)))
2433
 
                                free(id);
2434
 
                }
2435
 
                return 0;
2436
 
        }
2437
 
 
2438
 
        if (define_te_avtab_helper(which, &avrule))
2439
 
                return -1;
2440
 
 
2441
 
        /* append this avrule to the end of the current rules list */
2442
 
        append_avrule(avrule);
2443
 
        return 0;
2444
 
}
2445
 
 
2446
 
static int define_role_types(void)
2447
 
{
2448
 
        role_datum_t *role;
2449
 
        char *id;
2450
 
        int add = 1;
2451
 
 
2452
 
        if (pass == 1) {
2453
 
                while ((id = queue_remove(id_queue)))
2454
 
                        free(id);
2455
 
                return 0;
2456
 
        }
2457
 
 
2458
 
        if ((role = declare_role()) == NULL) {
2459
 
                return -1;
2460
 
        }
2461
 
        while ((id = queue_remove(id_queue))) {
2462
 
                if (set_types(&role->types, id, &add, 0))
2463
 
                        return -1;
2464
 
        }
2465
 
 
2466
 
        return 0;
2467
 
}
2468
 
 
2469
 
static role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
2470
 
{
2471
 
        role_datum_t *new;
2472
 
 
2473
 
        if (pass == 1) {
2474
 
                return (role_datum_t *) 1;      /* any non-NULL value */
2475
 
        }
2476
 
 
2477
 
        new = malloc(sizeof(role_datum_t));
2478
 
        if (!new) {
2479
 
                yyerror("out of memory");
2480
 
                return NULL;
2481
 
        }
2482
 
        memset(new, 0, sizeof(role_datum_t));
2483
 
        new->s.value = 0;               /* temporary role */
2484
 
        if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
2485
 
                yyerror("out of memory");
2486
 
                return NULL;
2487
 
        }
2488
 
        if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
2489
 
                yyerror("out of memory");
2490
 
                return NULL;
2491
 
        }
2492
 
        if (!r1->s.value) {
2493
 
                /* free intermediate result */
2494
 
                type_set_destroy(&r1->types);
2495
 
                ebitmap_destroy(&r1->dominates);
2496
 
                free(r1);
2497
 
        }
2498
 
        if (!r2->s.value) {
2499
 
                /* free intermediate result */
2500
 
                yyerror("right hand role is temporary?");
2501
 
                type_set_destroy(&r2->types);
2502
 
                ebitmap_destroy(&r2->dominates);
2503
 
                free(r2);
2504
 
        }
2505
 
        return new;
2506
 
}
2507
 
 
2508
 
/* This function eliminates the ordering dependency of role dominance rule */
2509
 
static int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum,
2510
 
                                 void *arg)
2511
 
{
2512
 
        role_datum_t *rdp = (role_datum_t *) arg;
2513
 
        role_datum_t *rdatum = (role_datum_t *) datum;
2514
 
        ebitmap_node_t *node;
2515
 
        int i;
2516
 
 
2517
 
        /* Don't bother to process against self role */
2518
 
        if (rdatum->s.value == rdp->s.value)
2519
 
                return 0;
2520
 
 
2521
 
        /* If a dominating role found */
2522
 
        if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) {
2523
 
                ebitmap_t types;
2524
 
                ebitmap_init(&types);
2525
 
                if (type_set_expand(&rdp->types, &types, policydbp, 1)) {
2526
 
                        ebitmap_destroy(&types);
2527
 
                        return -1;
2528
 
                }
2529
 
                /* raise types and dominates from dominated role */
2530
 
                ebitmap_for_each_bit(&rdp->dominates, node, i) {
2531
 
                        if (ebitmap_node_get_bit(node, i))
2532
 
                                if (ebitmap_set_bit
2533
 
                                    (&rdatum->dominates, i, TRUE))
2534
 
                                        goto oom;
2535
 
                }
2536
 
                ebitmap_for_each_bit(&types, node, i) {
2537
 
                        if (ebitmap_node_get_bit(node, i))
2538
 
                                if (ebitmap_set_bit
2539
 
                                    (&rdatum->types.types, i, TRUE))
2540
 
                                        goto oom;
2541
 
                }
2542
 
                ebitmap_destroy(&types);
2543
 
        }
2544
 
 
2545
 
        /* go through all the roles */
2546
 
        return 0;
2547
 
      oom:
2548
 
        yyerror("Out of memory");
2549
 
        return -1;
2550
 
}
2551
 
 
2552
 
static role_datum_t *define_role_dom(role_datum_t * r)
2553
 
{
2554
 
        role_datum_t *role;
2555
 
        char *role_id;
2556
 
        ebitmap_node_t *node;
2557
 
        unsigned int i;
2558
 
        int ret;
2559
 
 
2560
 
        if (pass == 1) {
2561
 
                role_id = queue_remove(id_queue);
2562
 
                free(role_id);
2563
 
                return (role_datum_t *) 1;      /* any non-NULL value */
2564
 
        }
2565
 
 
2566
 
        yywarn("Role dominance has been deprecated");
2567
 
 
2568
 
        role_id = queue_remove(id_queue);
2569
 
        if (!is_id_in_scope(SYM_ROLES, role_id)) {
2570
 
                yyerror2("role %s is not within scope", role_id);
2571
 
                free(role_id);
2572
 
                return NULL;
2573
 
        }
2574
 
        role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
2575
 
                                               role_id);
2576
 
        if (!role) {
2577
 
                role = (role_datum_t *) malloc(sizeof(role_datum_t));
2578
 
                if (!role) {
2579
 
                        yyerror("out of memory");
2580
 
                        free(role_id);
2581
 
                        return NULL;
2582
 
                }
2583
 
                memset(role, 0, sizeof(role_datum_t));
2584
 
                ret =
2585
 
                    declare_symbol(SYM_ROLES, (hashtab_key_t) role_id,
2586
 
                                   (hashtab_datum_t) role, &role->s.value,
2587
 
                                   &role->s.value);
2588
 
                switch (ret) {
2589
 
                case -3:{
2590
 
                                yyerror("Out of memory!");
2591
 
                                goto cleanup;
2592
 
                        }
2593
 
                case -2:{
2594
 
                                yyerror2("duplicate declaration of role %s",
2595
 
                                         role_id);
2596
 
                                goto cleanup;
2597
 
                        }
2598
 
                case -1:{
2599
 
                                yyerror("could not declare role here");
2600
 
                                goto cleanup;
2601
 
                        }
2602
 
                case 0:
2603
 
                case 1:{
2604
 
                                break;
2605
 
                        }
2606
 
                default:{
2607
 
                                assert(0);      /* should never get here */
2608
 
                        }
2609
 
                }
2610
 
                if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) {
2611
 
                        yyerror("Out of memory!");
2612
 
                        goto cleanup;
2613
 
                }
2614
 
        }
2615
 
        if (r) {
2616
 
                ebitmap_t types;
2617
 
                ebitmap_init(&types);
2618
 
                ebitmap_for_each_bit(&r->dominates, node, i) {
2619
 
                        if (ebitmap_node_get_bit(node, i))
2620
 
                                if (ebitmap_set_bit(&role->dominates, i, TRUE))
2621
 
                                        goto oom;
2622
 
                }
2623
 
                if (type_set_expand(&r->types, &types, policydbp, 1)) {
2624
 
                        ebitmap_destroy(&types);
2625
 
                        return NULL;
2626
 
                }
2627
 
                ebitmap_for_each_bit(&types, node, i) {
2628
 
                        if (ebitmap_node_get_bit(node, i))
2629
 
                                if (ebitmap_set_bit
2630
 
                                    (&role->types.types, i, TRUE))
2631
 
                                        goto oom;
2632
 
                }
2633
 
                ebitmap_destroy(&types);
2634
 
                if (!r->s.value) {
2635
 
                        /* free intermediate result */
2636
 
                        type_set_destroy(&r->types);
2637
 
                        ebitmap_destroy(&r->dominates);
2638
 
                        free(r);
2639
 
                }
2640
 
                /*
2641
 
                 * Now go through all the roles and escalate this role's
2642
 
                 * dominates and types if a role dominates this role.
2643
 
                 */
2644
 
                hashtab_map(policydbp->p_roles.table,
2645
 
                            dominate_role_recheck, role);
2646
 
        }
2647
 
        return role;
2648
 
      cleanup:
2649
 
        free(role_id);
2650
 
        role_datum_destroy(role);
2651
 
        free(role);
2652
 
        return NULL;
2653
 
      oom:
2654
 
        yyerror("Out of memory");
2655
 
        goto cleanup;
2656
 
}
2657
 
 
2658
 
static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum,
2659
 
                                   void *p)
2660
 
{
2661
 
        struct val_to_name *v = p;
2662
 
        role_datum_t *roldatum;
2663
 
 
2664
 
        roldatum = (role_datum_t *) datum;
2665
 
 
2666
 
        if (v->val == roldatum->s.value) {
2667
 
                v->name = key;
2668
 
                return 1;
2669
 
        }
2670
 
 
2671
 
        return 0;
2672
 
}
2673
 
 
2674
 
static char *role_val_to_name(unsigned int val)
2675
 
{
2676
 
        struct val_to_name v;
2677
 
        int rc;
2678
 
 
2679
 
        v.val = val;
2680
 
        rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
2681
 
        if (rc)
2682
 
                return v.name;
2683
 
        return NULL;
2684
 
}
2685
 
 
2686
 
static int set_roles(role_set_t * set, char *id)
2687
 
{
2688
 
        role_datum_t *r;
2689
 
 
2690
 
        if (strcmp(id, "*") == 0) {
2691
 
                free(id);
2692
 
                yyerror("* is not allowed for role sets");
2693
 
                return -1;
2694
 
        }
2695
 
 
2696
 
        if (strcmp(id, "~") == 0) {
2697
 
                free(id);
2698
 
                yyerror("~ is not allowed for role sets");
2699
 
                return -1;
2700
 
        }
2701
 
        if (!is_id_in_scope(SYM_ROLES, id)) {
2702
 
                yyerror2("role %s is not within scope", id);
2703
 
                free(id);
2704
 
                return -1;
2705
 
        }
2706
 
        r = hashtab_search(policydbp->p_roles.table, id);
2707
 
        if (!r) {
2708
 
                yyerror2("unknown role %s", id);
2709
 
                free(id);
2710
 
                return -1;
2711
 
        }
2712
 
 
2713
 
        if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
2714
 
                yyerror("out of memory");
2715
 
                free(id);
2716
 
                return -1;
2717
 
        }
2718
 
        free(id);
2719
 
        return 0;
2720
 
}
2721
 
 
2722
 
static int define_role_trans(void)
2723
 
{
2724
 
        char *id;
2725
 
        role_datum_t *role;
2726
 
        role_set_t roles;
2727
 
        type_set_t types;
2728
 
        ebitmap_t e_types, e_roles;
2729
 
        ebitmap_node_t *tnode, *rnode;
2730
 
        struct role_trans *tr = NULL;
2731
 
        struct role_trans_rule *rule = NULL;
2732
 
        unsigned int i, j;
2733
 
        int add = 1;
2734
 
 
2735
 
        if (pass == 1) {
2736
 
                while ((id = queue_remove(id_queue)))
2737
 
                        free(id);
2738
 
                while ((id = queue_remove(id_queue)))
2739
 
                        free(id);
2740
 
                id = queue_remove(id_queue);
2741
 
                free(id);
2742
 
                return 0;
2743
 
        }
2744
 
 
2745
 
        role_set_init(&roles);
2746
 
        ebitmap_init(&e_roles);
2747
 
        type_set_init(&types);
2748
 
        ebitmap_init(&e_types);
2749
 
 
2750
 
        while ((id = queue_remove(id_queue))) {
2751
 
                if (set_roles(&roles, id))
2752
 
                        return -1;
2753
 
        }
2754
 
        add = 1;
2755
 
        while ((id = queue_remove(id_queue))) {
2756
 
                if (set_types(&types, id, &add, 0))
2757
 
                        return -1;
2758
 
        }
2759
 
 
2760
 
        id = (char *)queue_remove(id_queue);
2761
 
        if (!id) {
2762
 
                yyerror("no new role in transition definition?");
2763
 
                goto bad;
2764
 
        }
2765
 
        if (!is_id_in_scope(SYM_ROLES, id)) {
2766
 
                yyerror2("role %s is not within scope", id);
2767
 
                free(id);
2768
 
                goto bad;
2769
 
        }
2770
 
        role = hashtab_search(policydbp->p_roles.table, id);
2771
 
        if (!role) {
2772
 
                sprintf(errormsg,
2773
 
                        "unknown role %s used in transition definition", id);
2774
 
                yyerror(errormsg);
2775
 
                goto bad;
2776
 
        }
2777
 
 
2778
 
        /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
2779
 
        if (role_set_expand(&roles, &e_roles, policydbp))
2780
 
                goto bad;
2781
 
 
2782
 
        if (type_set_expand(&types, &e_types, policydbp, 1))
2783
 
                goto bad;
2784
 
 
2785
 
        ebitmap_for_each_bit(&e_roles, rnode, i) {
2786
 
                if (!ebitmap_node_get_bit(rnode, i))
2787
 
                        continue;
2788
 
                ebitmap_for_each_bit(&e_types, tnode, j) {
2789
 
                        if (!ebitmap_node_get_bit(tnode, j))
2790
 
                                continue;
2791
 
 
2792
 
                        for (tr = policydbp->role_tr; tr; tr = tr->next) {
2793
 
                                if (tr->role == (i + 1) && tr->type == (j + 1)) {
2794
 
                                        sprintf(errormsg,
2795
 
                                                "duplicate role transition for (%s,%s)",
2796
 
                                                role_val_to_name(i + 1),
2797
 
                                                policydbp->
2798
 
                                                p_type_val_to_name[j]);
2799
 
                                        yyerror(errormsg);
2800
 
                                        goto bad;
2801
 
                                }
2802
 
                        }
2803
 
 
2804
 
                        tr = malloc(sizeof(struct role_trans));
2805
 
                        if (!tr) {
2806
 
                                yyerror("out of memory");
2807
 
                                return -1;
2808
 
                        }
2809
 
                        memset(tr, 0, sizeof(struct role_trans));
2810
 
                        tr->role = i + 1;
2811
 
                        tr->type = j + 1;
2812
 
                        tr->new_role = role->s.value;
2813
 
                        tr->next = policydbp->role_tr;
2814
 
                        policydbp->role_tr = tr;
2815
 
                }
2816
 
        }
2817
 
        /* Now add the real rule */
2818
 
        rule = malloc(sizeof(struct role_trans_rule));
2819
 
        if (!rule) {
2820
 
                yyerror("out of memory");
2821
 
                return -1;
2822
 
        }
2823
 
        memset(rule, 0, sizeof(struct role_trans_rule));
2824
 
        rule->roles = roles;
2825
 
        rule->types = types;
2826
 
        rule->new_role = role->s.value;
2827
 
 
2828
 
        append_role_trans(rule);
2829
 
 
2830
 
        ebitmap_destroy(&e_roles);
2831
 
        ebitmap_destroy(&e_types);
2832
 
 
2833
 
        return 0;
2834
 
 
2835
 
      bad:
2836
 
        return -1;
2837
 
}
2838
 
 
2839
 
static int define_role_allow(void)
2840
 
{
2841
 
        char *id;
2842
 
        struct role_allow_rule *ra = 0;
2843
 
 
2844
 
        if (pass == 1) {
2845
 
                while ((id = queue_remove(id_queue)))
2846
 
                        free(id);
2847
 
                while ((id = queue_remove(id_queue)))
2848
 
                        free(id);
2849
 
                return 0;
2850
 
        }
2851
 
 
2852
 
        ra = malloc(sizeof(role_allow_rule_t));
2853
 
        if (!ra) {
2854
 
                yyerror("out of memory");
2855
 
                return -1;
2856
 
        }
2857
 
        role_allow_rule_init(ra);
2858
 
 
2859
 
        while ((id = queue_remove(id_queue))) {
2860
 
                if (set_roles(&ra->roles, id))
2861
 
                        return -1;
2862
 
        }
2863
 
 
2864
 
        while ((id = queue_remove(id_queue))) {
2865
 
                if (set_roles(&ra->new_roles, id))
2866
 
                        return -1;
2867
 
        }
2868
 
 
2869
 
        append_role_allow(ra);
2870
 
        return 0;
2871
 
}
2872
 
 
2873
 
static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
2874
 
{
2875
 
        constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
2876
 
        for (e = expr; e; e = e->next) {
2877
 
                newe = malloc(sizeof(*newe));
2878
 
                if (!newe)
2879
 
                        goto oom;
2880
 
                if (constraint_expr_init(newe) == -1) {
2881
 
                        free(newe);
2882
 
                        goto oom;
2883
 
                }
2884
 
                if (l)
2885
 
                        l->next = newe;
2886
 
                else
2887
 
                        h = newe;
2888
 
                l = newe;
2889
 
                newe->expr_type = e->expr_type;
2890
 
                newe->attr = e->attr;
2891
 
                newe->op = e->op;
2892
 
                if (newe->expr_type == CEXPR_NAMES) {
2893
 
                        if (newe->attr & CEXPR_TYPE) {
2894
 
                                if (type_set_cpy
2895
 
                                    (newe->type_names, e->type_names))
2896
 
                                        goto oom;
2897
 
                        } else {
2898
 
                                if (ebitmap_cpy(&newe->names, &e->names))
2899
 
                                        goto oom;
2900
 
                        }
2901
 
                }
2902
 
        }
2903
 
 
2904
 
        return h;
2905
 
      oom:
2906
 
        e = h;
2907
 
        while (e) {
2908
 
                l = e;
2909
 
                e = e->next;
2910
 
                constraint_expr_destroy(l);
2911
 
        }
2912
 
        return NULL;
2913
 
}
2914
 
 
2915
 
static int define_constraint(constraint_expr_t * expr)
2916
 
{
2917
 
        struct constraint_node *node;
2918
 
        char *id;
2919
 
        class_datum_t *cladatum;
2920
 
        perm_datum_t *perdatum;
2921
 
        ebitmap_t classmap;
2922
 
        ebitmap_node_t *enode;
2923
 
        constraint_expr_t *e;
2924
 
        unsigned int i;
2925
 
        int depth;
2926
 
        unsigned char useexpr = 1;
2927
 
 
2928
 
        if (pass == 1) {
2929
 
                while ((id = queue_remove(id_queue)))
2930
 
                        free(id);
2931
 
                while ((id = queue_remove(id_queue)))
2932
 
                        free(id);
2933
 
                return 0;
2934
 
        }
2935
 
 
2936
 
        depth = -1;
2937
 
        for (e = expr; e; e = e->next) {
2938
 
                switch (e->expr_type) {
2939
 
                case CEXPR_NOT:
2940
 
                        if (depth < 0) {
2941
 
                                yyerror("illegal constraint expression");
2942
 
                                return -1;
2943
 
                        }
2944
 
                        break;
2945
 
                case CEXPR_AND:
2946
 
                case CEXPR_OR:
2947
 
                        if (depth < 1) {
2948
 
                                yyerror("illegal constraint expression");
2949
 
                                return -1;
2950
 
                        }
2951
 
                        depth--;
2952
 
                        break;
2953
 
                case CEXPR_ATTR:
2954
 
                case CEXPR_NAMES:
2955
 
                        if (e->attr & CEXPR_XTARGET) {
2956
 
                                yyerror("illegal constraint expression");
2957
 
                                return -1;      /* only for validatetrans rules */
2958
 
                        }
2959
 
                        if (depth == (CEXPR_MAXDEPTH - 1)) {
2960
 
                                yyerror("constraint expression is too deep");
2961
 
                                return -1;
2962
 
                        }
2963
 
                        depth++;
2964
 
                        break;
2965
 
                default:
2966
 
                        yyerror("illegal constraint expression");
2967
 
                        return -1;
2968
 
                }
2969
 
        }
2970
 
        if (depth != 0) {
2971
 
                yyerror("illegal constraint expression");
2972
 
                return -1;
2973
 
        }
2974
 
 
2975
 
        ebitmap_init(&classmap);
2976
 
        while ((id = queue_remove(id_queue))) {
2977
 
                if (!is_id_in_scope(SYM_CLASSES, id)) {
2978
 
                        yyerror2("class %s is not within scope", id);
2979
 
                        free(id);
2980
 
                        return -1;
2981
 
                }
2982
 
                cladatum =
2983
 
                    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
2984
 
                                                     (hashtab_key_t) id);
2985
 
                if (!cladatum) {
2986
 
                        sprintf(errormsg, "class %s is not defined", id);
2987
 
                        ebitmap_destroy(&classmap);
2988
 
                        yyerror(errormsg);
2989
 
                        free(id);
2990
 
                        return -1;
2991
 
                }
2992
 
                if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
2993
 
                        yyerror("out of memory");
2994
 
                        ebitmap_destroy(&classmap);
2995
 
                        free(id);
2996
 
                        return -1;
2997
 
                }
2998
 
                node = malloc(sizeof(struct constraint_node));
2999
 
                if (!node) {
3000
 
                        yyerror("out of memory");
3001
 
                        return -1;
3002
 
                }
3003
 
                memset(node, 0, sizeof(constraint_node_t));
3004
 
                if (useexpr) {
3005
 
                        node->expr = expr;
3006
 
                        useexpr = 0;
3007
 
                } else {
3008
 
                        node->expr = constraint_expr_clone(expr);
3009
 
                }
3010
 
                if (!node->expr) {
3011
 
                        yyerror("out of memory");
3012
 
                        return -1;
3013
 
                }
3014
 
                node->permissions = 0;
3015
 
 
3016
 
                node->next = cladatum->constraints;
3017
 
                cladatum->constraints = node;
3018
 
 
3019
 
                free(id);
3020
 
        }
3021
 
 
3022
 
        while ((id = queue_remove(id_queue))) {
3023
 
                ebitmap_for_each_bit(&classmap, enode, i) {
3024
 
                        if (ebitmap_node_get_bit(enode, i)) {
3025
 
                                cladatum = policydbp->class_val_to_struct[i];
3026
 
                                node = cladatum->constraints;
3027
 
 
3028
 
                                perdatum =
3029
 
                                    (perm_datum_t *) hashtab_search(cladatum->
3030
 
                                                                    permissions.
3031
 
                                                                    table,
3032
 
                                                                    (hashtab_key_t)
3033
 
                                                                    id);
3034
 
                                if (!perdatum) {
3035
 
                                        if (cladatum->comdatum) {
3036
 
                                                perdatum =
3037
 
                                                    (perm_datum_t *)
3038
 
                                                    hashtab_search(cladatum->
3039
 
                                                                   comdatum->
3040
 
                                                                   permissions.
3041
 
                                                                   table,
3042
 
                                                                   (hashtab_key_t)
3043
 
                                                                   id);
3044
 
                                        }
3045
 
                                        if (!perdatum) {
3046
 
                                                sprintf(errormsg,
3047
 
                                                        "permission %s is not defined",
3048
 
                                                        id);
3049
 
                                                yyerror(errormsg);
3050
 
                                                free(id);
3051
 
                                                ebitmap_destroy(&classmap);
3052
 
                                                return -1;
3053
 
                                        }
3054
 
                                }
3055
 
                                node->permissions |=
3056
 
                                    (1 << (perdatum->s.value - 1));
3057
 
                        }
3058
 
                }
3059
 
                free(id);
3060
 
        }
3061
 
 
3062
 
        ebitmap_destroy(&classmap);
3063
 
 
3064
 
        return 0;
3065
 
}
3066
 
 
3067
 
static int define_validatetrans(constraint_expr_t * expr)
3068
 
{
3069
 
        struct constraint_node *node;
3070
 
        char *id;
3071
 
        class_datum_t *cladatum;
3072
 
        ebitmap_t classmap;
3073
 
        constraint_expr_t *e;
3074
 
        int depth;
3075
 
        unsigned char useexpr = 1;
3076
 
 
3077
 
        if (pass == 1) {
3078
 
                while ((id = queue_remove(id_queue)))
3079
 
                        free(id);
3080
 
                return 0;
3081
 
        }
3082
 
 
3083
 
        depth = -1;
3084
 
        for (e = expr; e; e = e->next) {
3085
 
                switch (e->expr_type) {
3086
 
                case CEXPR_NOT:
3087
 
                        if (depth < 0) {
3088
 
                                yyerror("illegal validatetrans expression");
3089
 
                                return -1;
3090
 
                        }
3091
 
                        break;
3092
 
                case CEXPR_AND:
3093
 
                case CEXPR_OR:
3094
 
                        if (depth < 1) {
3095
 
                                yyerror("illegal validatetrans expression");
3096
 
                                return -1;
3097
 
                        }
3098
 
                        depth--;
3099
 
                        break;
3100
 
                case CEXPR_ATTR:
3101
 
                case CEXPR_NAMES:
3102
 
                        if (depth == (CEXPR_MAXDEPTH - 1)) {
3103
 
                                yyerror("validatetrans expression is too deep");
3104
 
                                return -1;
3105
 
                        }
3106
 
                        depth++;
3107
 
                        break;
3108
 
                default:
3109
 
                        yyerror("illegal validatetrans expression");
3110
 
                        return -1;
3111
 
                }
3112
 
        }
3113
 
        if (depth != 0) {
3114
 
                yyerror("illegal validatetrans expression");
3115
 
                return -1;
3116
 
        }
3117
 
 
3118
 
        ebitmap_init(&classmap);
3119
 
        while ((id = queue_remove(id_queue))) {
3120
 
                if (!is_id_in_scope(SYM_CLASSES, id)) {
3121
 
                        yyerror2("class %s is not within scope", id);
3122
 
                        free(id);
3123
 
                        return -1;
3124
 
                }
3125
 
                cladatum =
3126
 
                    (class_datum_t *) hashtab_search(policydbp->p_classes.table,
3127
 
                                                     (hashtab_key_t) id);
3128
 
                if (!cladatum) {
3129
 
                        sprintf(errormsg, "class %s is not defined", id);
3130
 
                        ebitmap_destroy(&classmap);
3131
 
                        yyerror(errormsg);
3132
 
                        free(id);
3133
 
                        return -1;
3134
 
                }
3135
 
                if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
3136
 
                        yyerror("out of memory");
3137
 
                        ebitmap_destroy(&classmap);
3138
 
                        free(id);
3139
 
                        return -1;
3140
 
                }
3141
 
 
3142
 
                node = malloc(sizeof(struct constraint_node));
3143
 
                if (!node) {
3144
 
                        yyerror("out of memory");
3145
 
                        return -1;
3146
 
                }
3147
 
                memset(node, 0, sizeof(constraint_node_t));
3148
 
                if (useexpr) {
3149
 
                        node->expr = expr;
3150
 
                        useexpr = 0;
3151
 
                } else {
3152
 
                        node->expr = constraint_expr_clone(expr);
3153
 
                }
3154
 
                node->permissions = 0;
3155
 
 
3156
 
                node->next = cladatum->validatetrans;
3157
 
                cladatum->validatetrans = node;
3158
 
 
3159
 
                free(id);
3160
 
        }
3161
 
 
3162
 
        ebitmap_destroy(&classmap);
3163
 
 
3164
 
        return 0;
3165
 
}
3166
 
 
3167
 
static uintptr_t
3168
 
define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
3169
 
{
3170
 
        struct constraint_expr *expr, *e1 = NULL, *e2;
3171
 
        user_datum_t *user;
3172
 
        role_datum_t *role;
3173
 
        ebitmap_t negset;
3174
 
        char *id;
3175
 
        uint32_t val;
3176
 
        int add = 1;
3177
 
 
3178
 
        if (pass == 1) {
3179
 
                if (expr_type == CEXPR_NAMES) {
3180
 
                        while ((id = queue_remove(id_queue)))
3181
 
                                free(id);
3182
 
                }
3183
 
                return 1;       /* any non-NULL value */
3184
 
        }
3185
 
 
3186
 
        if ((expr = malloc(sizeof(*expr))) == NULL ||
3187
 
            constraint_expr_init(expr) == -1) {
3188
 
                yyerror("out of memory");
3189
 
                free(expr);
3190
 
                return 0;
3191
 
        }
3192
 
        expr->expr_type = expr_type;
3193
 
 
3194
 
        switch (expr_type) {
3195
 
        case CEXPR_NOT:
3196
 
                e1 = NULL;
3197
 
                e2 = (struct constraint_expr *)arg1;
3198
 
                while (e2) {
3199
 
                        e1 = e2;
3200
 
                        e2 = e2->next;
3201
 
                }
3202
 
                if (!e1 || e1->next) {
3203
 
                        yyerror("illegal constraint expression");
3204
 
                        constraint_expr_destroy(expr);
3205
 
                        return 0;
3206
 
                }
3207
 
                e1->next = expr;
3208
 
                return arg1;
3209
 
        case CEXPR_AND:
3210
 
        case CEXPR_OR:
3211
 
                e1 = NULL;
3212
 
                e2 = (struct constraint_expr *)arg1;
3213
 
                while (e2) {
3214
 
                        e1 = e2;
3215
 
                        e2 = e2->next;
3216
 
                }
3217
 
                if (!e1 || e1->next) {
3218
 
                        yyerror("illegal constraint expression");
3219
 
                        constraint_expr_destroy(expr);
3220
 
                        return 0;
3221
 
                }
3222
 
                e1->next = (struct constraint_expr *)arg2;
3223
 
 
3224
 
                e1 = NULL;
3225
 
                e2 = (struct constraint_expr *)arg2;
3226
 
                while (e2) {
3227
 
                        e1 = e2;
3228
 
                        e2 = e2->next;
3229
 
                }
3230
 
                if (!e1 || e1->next) {
3231
 
                        yyerror("illegal constraint expression");
3232
 
                        constraint_expr_destroy(expr);
3233
 
                        return 0;
3234
 
                }
3235
 
                e1->next = expr;
3236
 
                return arg1;
3237
 
        case CEXPR_ATTR:
3238
 
                expr->attr = arg1;
3239
 
                expr->op = arg2;
3240
 
                return (uintptr_t) expr;
3241
 
        case CEXPR_NAMES:
3242
 
                add = 1;
3243
 
                expr->attr = arg1;
3244
 
                expr->op = arg2;
3245
 
                ebitmap_init(&negset);
3246
 
                while ((id = (char *)queue_remove(id_queue))) {
3247
 
                        if (expr->attr & CEXPR_USER) {
3248
 
                                if (!is_id_in_scope(SYM_USERS, id)) {
3249
 
                                        yyerror2("user %s is not within scope",
3250
 
                                                 id);
3251
 
                                        constraint_expr_destroy(expr);
3252
 
                                        return 0;
3253
 
                                }
3254
 
                                user =
3255
 
                                    (user_datum_t *) hashtab_search(policydbp->
3256
 
                                                                    p_users.
3257
 
                                                                    table,
3258
 
                                                                    (hashtab_key_t)
3259
 
                                                                    id);
3260
 
                                if (!user) {
3261
 
                                        sprintf(errormsg, "unknown user %s",
3262
 
                                                id);
3263
 
                                        yyerror(errormsg);
3264
 
                                        constraint_expr_destroy(expr);
3265
 
                                        return 0;
3266
 
                                }
3267
 
                                val = user->s.value;
3268
 
                        } else if (expr->attr & CEXPR_ROLE) {
3269
 
                                if (!is_id_in_scope(SYM_ROLES, id)) {
3270
 
                                        yyerror2("role %s is not within scope",
3271
 
                                                 id);
3272
 
                                        constraint_expr_destroy(expr);
3273
 
                                        return 0;
3274
 
                                }
3275
 
                                role =
3276
 
                                    (role_datum_t *) hashtab_search(policydbp->
3277
 
                                                                    p_roles.
3278
 
                                                                    table,
3279
 
                                                                    (hashtab_key_t)
3280
 
                                                                    id);
3281
 
                                if (!role) {
3282
 
                                        sprintf(errormsg, "unknown role %s",
3283
 
                                                id);
3284
 
                                        yyerror(errormsg);
3285
 
                                        constraint_expr_destroy(expr);
3286
 
                                        return 0;
3287
 
                                }
3288
 
                                val = role->s.value;
3289
 
                        } else if (expr->attr & CEXPR_TYPE) {
3290
 
                                if (set_types(expr->type_names, id, &add, 0)) {
3291
 
                                        constraint_expr_destroy(expr);
3292
 
                                        return 0;
3293
 
                                }
3294
 
                                continue;
3295
 
                        } else {
3296
 
                                yyerror("invalid constraint expression");
3297
 
                                constraint_expr_destroy(expr);
3298
 
                                return 0;
3299
 
                        }
3300
 
                        if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
3301
 
                                yyerror("out of memory");
3302
 
                                ebitmap_destroy(&expr->names);
3303
 
                                constraint_expr_destroy(expr);
3304
 
                                return 0;
3305
 
                        }
3306
 
                        free(id);
3307
 
                }
3308
 
                ebitmap_destroy(&negset);
3309
 
                return (uintptr_t) expr;
3310
 
        default:
3311
 
                yyerror("invalid constraint expression");
3312
 
                constraint_expr_destroy(expr);
3313
 
                return 0;
3314
 
        }
3315
 
 
3316
 
        yyerror("invalid constraint expression");
3317
 
        free(expr);
3318
 
        return 0;
3319
 
}
3320
 
 
3321
 
static int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f)
3322
 
{
3323
 
        cond_expr_t *e;
3324
 
        int depth;
3325
 
        cond_node_t cn, *cn_old;
3326
 
 
3327
 
        /* expression cannot be NULL */
3328
 
        if (!expr) {
3329
 
                yyerror("illegal conditional expression");
3330
 
                return -1;
3331
 
        }
3332
 
        if (!t) {
3333
 
                if (!f) {
3334
 
                        /* empty is fine, destroy expression and return */
3335
 
                        cond_expr_destroy(expr);
3336
 
                        return 0;
3337
 
                }
3338
 
                /* Invert */
3339
 
                t = f;
3340
 
                f = 0;
3341
 
                expr = define_cond_expr(COND_NOT, expr, 0);
3342
 
                if (!expr) {
3343
 
                        yyerror("unable to invert");
3344
 
                        return -1;
3345
 
                }
3346
 
        }
3347
 
 
3348
 
        /* verify expression */
3349
 
        depth = -1;
3350
 
        for (e = expr; e; e = e->next) {
3351
 
                switch (e->expr_type) {
3352
 
                case COND_NOT:
3353
 
                        if (depth < 0) {
3354
 
                                yyerror
3355
 
                                    ("illegal conditional expression; Bad NOT");
3356
 
                                return -1;
3357
 
                        }
3358
 
                        break;
3359
 
                case COND_AND:
3360
 
                case COND_OR:
3361
 
                case COND_XOR:
3362
 
                case COND_EQ:
3363
 
                case COND_NEQ:
3364
 
                        if (depth < 1) {
3365
 
                                yyerror
3366
 
                                    ("illegal conditional expression; Bad binary op");
3367
 
                                return -1;
3368
 
                        }
3369
 
                        depth--;
3370
 
                        break;
3371
 
                case COND_BOOL:
3372
 
                        if (depth == (COND_EXPR_MAXDEPTH - 1)) {
3373
 
                                yyerror
3374
 
                                    ("conditional expression is like totally too deep");
3375
 
                                return -1;
3376
 
                        }
3377
 
                        depth++;
3378
 
                        break;
3379
 
                default:
3380
 
                        yyerror("illegal conditional expression");
3381
 
                        return -1;
3382
 
                }
3383
 
        }
3384
 
        if (depth != 0) {
3385
 
                yyerror("illegal conditional expression");
3386
 
                return -1;
3387
 
        }
3388
 
 
3389
 
        /*  use tmp conditional node to partially build new node */
3390
 
        memset(&cn, 0, sizeof(cn));
3391
 
        cn.expr = expr;
3392
 
        cn.avtrue_list = t;
3393
 
        cn.avfalse_list = f;
3394
 
 
3395
 
        /* normalize/precompute expression */
3396
 
        if (cond_normalize_expr(policydbp, &cn) < 0) {
3397
 
                yyerror("problem normalizing conditional expression");
3398
 
                return -1;
3399
 
        }
3400
 
 
3401
 
        /* get the existing conditional node, or create a new one */
3402
 
        cn_old = get_current_cond_list(&cn);
3403
 
        if (!cn_old) {
3404
 
                return -1;
3405
 
        }
3406
 
 
3407
 
        append_cond_list(&cn);
3408
 
 
3409
 
        /* note that there is no check here for duplicate rules, nor
3410
 
         * check that rule already exists in base -- that will be
3411
 
         * handled during conditional expansion, in expand.c */
3412
 
 
3413
 
        cn.avtrue_list = NULL;
3414
 
        cn.avfalse_list = NULL;
3415
 
        cond_node_destroy(&cn);
3416
 
 
3417
 
        return 0;
3418
 
}
3419
 
 
3420
 
static cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
3421
 
{
3422
 
        struct cond_expr *expr, *e1 = NULL, *e2;
3423
 
        cond_bool_datum_t *bool_var;
3424
 
        char *id;
3425
 
 
3426
 
        /* expressions are handled in the second pass */
3427
 
        if (pass == 1) {
3428
 
                if (expr_type == COND_BOOL) {
3429
 
                        while ((id = queue_remove(id_queue))) {
3430
 
                                free(id);
3431
 
                        }
3432
 
                }
3433
 
                return (cond_expr_t *) 1;       /* any non-NULL value */
3434
 
        }
3435
 
 
3436
 
        /* create a new expression struct */
3437
 
        expr = malloc(sizeof(struct cond_expr));
3438
 
        if (!expr) {
3439
 
                yyerror("out of memory");
3440
 
                return NULL;
3441
 
        }
3442
 
        memset(expr, 0, sizeof(cond_expr_t));
3443
 
        expr->expr_type = expr_type;
3444
 
 
3445
 
        /* create the type asked for */
3446
 
        switch (expr_type) {
3447
 
        case COND_NOT:
3448
 
                e1 = NULL;
3449
 
                e2 = (struct cond_expr *)arg1;
3450
 
                while (e2) {
3451
 
                        e1 = e2;
3452
 
                        e2 = e2->next;
3453
 
                }
3454
 
                if (!e1 || e1->next) {
3455
 
                        yyerror("illegal conditional NOT expression");
3456
 
                        free(expr);
3457
 
                        return NULL;
3458
 
                }
3459
 
                e1->next = expr;
3460
 
                return (struct cond_expr *)arg1;
3461
 
        case COND_AND:
3462
 
        case COND_OR:
3463
 
        case COND_XOR:
3464
 
        case COND_EQ:
3465
 
        case COND_NEQ:
3466
 
                e1 = NULL;
3467
 
                e2 = (struct cond_expr *)arg1;
3468
 
                while (e2) {
3469
 
                        e1 = e2;
3470
 
                        e2 = e2->next;
3471
 
                }
3472
 
                if (!e1 || e1->next) {
3473
 
                        yyerror
3474
 
                            ("illegal left side of conditional binary op expression");
3475
 
                        free(expr);
3476
 
                        return NULL;
3477
 
                }
3478
 
                e1->next = (struct cond_expr *)arg2;
3479
 
 
3480
 
                e1 = NULL;
3481
 
                e2 = (struct cond_expr *)arg2;
3482
 
                while (e2) {
3483
 
                        e1 = e2;
3484
 
                        e2 = e2->next;
3485
 
                }
3486
 
                if (!e1 || e1->next) {
3487
 
                        yyerror
3488
 
                            ("illegal right side of conditional binary op expression");
3489
 
                        free(expr);
3490
 
                        return NULL;
3491
 
                }
3492
 
                e1->next = expr;
3493
 
                return (struct cond_expr *)arg1;
3494
 
        case COND_BOOL:
3495
 
                id = (char *)queue_remove(id_queue);
3496
 
                if (!id) {
3497
 
                        yyerror("bad conditional; expected boolean id");
3498
 
                        free(id);
3499
 
                        free(expr);
3500
 
                        return NULL;
3501
 
                }
3502
 
                if (!is_id_in_scope(SYM_BOOLS, id)) {
3503
 
                        yyerror2("boolean %s is not within scope", id);
3504
 
                        free(id);
3505
 
                        free(expr);
3506
 
                        return NULL;
3507
 
                }
3508
 
                bool_var =
3509
 
                    (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.
3510
 
                                                         table,
3511
 
                                                         (hashtab_key_t) id);
3512
 
                if (!bool_var) {
3513
 
                        sprintf(errormsg,
3514
 
                                "unknown boolean %s in conditional expression",
3515
 
                                id);
3516
 
                        yyerror(errormsg);
3517
 
                        free(expr);
3518
 
                        free(id);
3519
 
                        return NULL;
3520
 
                }
3521
 
                expr->bool = bool_var->s.value;
3522
 
                free(id);
3523
 
                return expr;
3524
 
        default:
3525
 
                yyerror("illegal conditional expression");
3526
 
                return NULL;
3527
 
        }
3528
 
}
3529
 
 
3530
 
static int set_user_roles(role_set_t * set, char *id)
3531
 
{
3532
 
        role_datum_t *r;
3533
 
        unsigned int i;
3534
 
        ebitmap_node_t *node;
3535
 
 
3536
 
        if (strcmp(id, "*") == 0) {
3537
 
                free(id);
3538
 
                yyerror("* is not allowed in user declarations");
3539
 
                return -1;
3540
 
        }
3541
 
 
3542
 
        if (strcmp(id, "~") == 0) {
3543
 
                free(id);
3544
 
                yyerror("~ is not allowed in user declarations");
3545
 
                return -1;
3546
 
        }
3547
 
 
3548
 
        if (!is_id_in_scope(SYM_ROLES, id)) {
3549
 
                yyerror2("role %s is not within scope", id);
3550
 
                free(id);
3551
 
                return -1;
3552
 
        }
3553
 
        r = hashtab_search(policydbp->p_roles.table, id);
3554
 
        if (!r) {
3555
 
                sprintf(errormsg, "unknown role %s", id);
3556
 
                yyerror(errormsg);
3557
 
                free(id);
3558
 
                return -1;
3559
 
        }
3560
 
 
3561
 
        /* set the role and every role it dominates */
3562
 
        ebitmap_for_each_bit(&r->dominates, node, i) {
3563
 
                if (ebitmap_node_get_bit(node, i))
3564
 
                        if (ebitmap_set_bit(&set->roles, i, TRUE))
3565
 
                                goto oom;
3566
 
        }
3567
 
        free(id);
3568
 
        return 0;
3569
 
      oom:
3570
 
        yyerror("out of memory");
3571
 
        return -1;
3572
 
}
3573
 
 
3574
 
static int
3575
 
parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
3576
 
{
3577
 
        cat_datum_t *cdatum;
3578
 
        int range_start, range_end, i;
3579
 
 
3580
 
        if (id_has_dot(id)) {
3581
 
                char *id_start = id;
3582
 
                char *id_end = strchr(id, '.');
3583
 
 
3584
 
                *(id_end++) = '\0';
3585
 
 
3586
 
                cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3587
 
                                                        (hashtab_key_t)
3588
 
                                                        id_start);
3589
 
                if (!cdatum) {
3590
 
                        sprintf(errormsg, "unknown category %s", id_start);
3591
 
                        yyerror(errormsg);
3592
 
                        return -1;
3593
 
                }
3594
 
                range_start = cdatum->s.value - 1;
3595
 
                cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3596
 
                                                        (hashtab_key_t) id_end);
3597
 
                if (!cdatum) {
3598
 
                        sprintf(errormsg, "unknown category %s", id_end);
3599
 
                        yyerror(errormsg);
3600
 
                        return -1;
3601
 
                }
3602
 
                range_end = cdatum->s.value - 1;
3603
 
 
3604
 
                if (range_end < range_start) {
3605
 
                        sprintf(errormsg, "category range is invalid");
3606
 
                        yyerror(errormsg);
3607
 
                        return -1;
3608
 
                }
3609
 
        } else {
3610
 
                cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3611
 
                                                        (hashtab_key_t) id);
3612
 
                if (!cdatum) {
3613
 
                        sprintf(errormsg, "unknown category %s", id);
3614
 
                        yyerror(errormsg);
3615
 
                        return -1;
3616
 
                }
3617
 
                range_start = range_end = cdatum->s.value - 1;
3618
 
        }
3619
 
 
3620
 
        for (i = range_start; i <= range_end; i++) {
3621
 
                if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
3622
 
                        uint32_t level_value = levdatum->level->sens - 1;
3623
 
                        policydb_index_others(NULL, policydbp, 0);
3624
 
                        sprintf(errormsg, "category %s can not be associated "
3625
 
                                "with level %s",
3626
 
                                policydbp->p_cat_val_to_name[i],
3627
 
                                policydbp->p_sens_val_to_name[level_value]);
3628
 
                        yyerror(errormsg);
3629
 
                        return -1;
3630
 
                }
3631
 
                if (ebitmap_set_bit(cats, i, TRUE)) {
3632
 
                        yyerror("out of memory");
3633
 
                        return -1;
3634
 
                }
3635
 
        }
3636
 
 
3637
 
        return 0;
3638
 
}
3639
 
 
3640
 
static int
3641
 
parse_semantic_categories(char *id, level_datum_t * levdatum,
3642
 
                          mls_semantic_cat_t ** cats)
3643
 
{
3644
 
        cat_datum_t *cdatum;
3645
 
        mls_semantic_cat_t *newcat;
3646
 
        unsigned int range_start, range_end;
3647
 
 
3648
 
        if (id_has_dot(id)) {
3649
 
                char *id_start = id;
3650
 
                char *id_end = strchr(id, '.');
3651
 
 
3652
 
                *(id_end++) = '\0';
3653
 
 
3654
 
                cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3655
 
                                                        (hashtab_key_t)
3656
 
                                                        id_start);
3657
 
                if (!cdatum) {
3658
 
                        sprintf(errormsg, "unknown category %s", id_start);
3659
 
                        yyerror(errormsg);
3660
 
                        return -1;
3661
 
                }
3662
 
                range_start = cdatum->s.value;
3663
 
 
3664
 
                cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3665
 
                                                        (hashtab_key_t) id_end);
3666
 
                if (!cdatum) {
3667
 
                        sprintf(errormsg, "unknown category %s", id_end);
3668
 
                        yyerror(errormsg);
3669
 
                        return -1;
3670
 
                }
3671
 
                range_end = cdatum->s.value;
3672
 
        } else {
3673
 
                cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3674
 
                                                        (hashtab_key_t) id);
3675
 
                if (!cdatum) {
3676
 
                        sprintf(errormsg, "unknown category %s", id);
3677
 
                        yyerror(errormsg);
3678
 
                        return -1;
3679
 
                }
3680
 
                range_start = range_end = cdatum->s.value;
3681
 
        }
3682
 
 
3683
 
        newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
3684
 
        if (!newcat) {
3685
 
                yyerror("out of memory");
3686
 
                return -1;
3687
 
        }
3688
 
 
3689
 
        mls_semantic_cat_init(newcat);
3690
 
        newcat->next = *cats;
3691
 
        newcat->low = range_start;
3692
 
        newcat->high = range_end;
3693
 
 
3694
 
        *cats = newcat;
3695
 
 
3696
 
        return 0;
3697
 
}
3698
 
 
3699
 
static int define_user(void)
3700
 
{
3701
 
        char *id;
3702
 
        user_datum_t *usrdatum;
3703
 
        level_datum_t *levdatum;
3704
 
        int l;
3705
 
 
3706
 
        if (pass == 1) {
3707
 
                while ((id = queue_remove(id_queue)))
3708
 
                        free(id);
3709
 
                if (mlspol) {
3710
 
                        while ((id = queue_remove(id_queue)))
3711
 
                                free(id);
3712
 
                        id = queue_remove(id_queue);
3713
 
                        free(id);
3714
 
                        for (l = 0; l < 2; l++) {
3715
 
                                while ((id = queue_remove(id_queue))) {
3716
 
                                        free(id);
3717
 
                                }
3718
 
                                id = queue_remove(id_queue);
3719
 
                                if (!id)
3720
 
                                        break;
3721
 
                                free(id);
3722
 
                        }
3723
 
                }
3724
 
                return 0;
3725
 
        }
3726
 
 
3727
 
        if ((usrdatum = declare_user()) == NULL) {
3728
 
                return -1;
3729
 
        }
3730
 
 
3731
 
        while ((id = queue_remove(id_queue))) {
3732
 
                if (set_user_roles(&usrdatum->roles, id))
3733
 
                        continue;
3734
 
        }
3735
 
 
3736
 
        if (mlspol) {
3737
 
                id = queue_remove(id_queue);
3738
 
                if (!id) {
3739
 
                        yyerror("no default level specified for user");
3740
 
                        return -1;
3741
 
                }
3742
 
 
3743
 
                levdatum = (level_datum_t *)
3744
 
                    hashtab_search(policydbp->p_levels.table,
3745
 
                                   (hashtab_key_t) id);
3746
 
                if (!levdatum) {
3747
 
                        sprintf(errormsg, "unknown sensitivity %s used in user"
3748
 
                                " level definition", id);
3749
 
                        yyerror(errormsg);
3750
 
                        free(id);
3751
 
                        return -1;
3752
 
                }
3753
 
                free(id);
3754
 
 
3755
 
                usrdatum->dfltlevel.sens = levdatum->level->sens;
3756
 
 
3757
 
                while ((id = queue_remove(id_queue))) {
3758
 
                        if (parse_semantic_categories(id, levdatum,
3759
 
                                                    &usrdatum->dfltlevel.cat)) {
3760
 
                                free(id);
3761
 
                                return -1;
3762
 
                        }
3763
 
                        free(id);
3764
 
                }
3765
 
 
3766
 
                id = queue_remove(id_queue);
3767
 
 
3768
 
                for (l = 0; l < 2; l++) {
3769
 
                        levdatum = (level_datum_t *)
3770
 
                            hashtab_search(policydbp->p_levels.table,
3771
 
                                           (hashtab_key_t) id);
3772
 
                        if (!levdatum) {
3773
 
                                sprintf(errormsg,
3774
 
                                        "unknown sensitivity %s used in user range definition",
3775
 
                                        id);
3776
 
                                yyerror(errormsg);
3777
 
                                free(id);
3778
 
                                return -1;
3779
 
                        }
3780
 
                        free(id);
3781
 
 
3782
 
                        usrdatum->range.level[l].sens = levdatum->level->sens;
3783
 
 
3784
 
                        while ((id = queue_remove(id_queue))) {
3785
 
                                if (parse_semantic_categories(id, levdatum,
3786
 
                                               &usrdatum->range.level[l].cat)) {
3787
 
                                        free(id);
3788
 
                                        return -1;
3789
 
                                }
3790
 
                                free(id);
3791
 
                        }
3792
 
 
3793
 
                        id = queue_remove(id_queue);
3794
 
                        if (!id)
3795
 
                                break;
3796
 
                }
3797
 
 
3798
 
                if (l == 0) {
3799
 
                        if (mls_semantic_level_cpy(&usrdatum->range.level[1],
3800
 
                                                   &usrdatum->range.level[0])) {
3801
 
                                yyerror("out of memory");
3802
 
                                return -1;
3803
 
                        }
3804
 
                }
3805
 
        }
3806
 
        return 0;
3807
 
}
3808
 
 
3809
 
static int parse_security_context(context_struct_t * c)
3810
 
{
3811
 
        char *id;
3812
 
        role_datum_t *role;
3813
 
        type_datum_t *typdatum;
3814
 
        user_datum_t *usrdatum;
3815
 
        level_datum_t *levdatum;
3816
 
        int l;
3817
 
 
3818
 
        if (pass == 1) {
3819
 
                id = queue_remove(id_queue);
3820
 
                free(id);       /* user  */
3821
 
                id = queue_remove(id_queue);
3822
 
                free(id);       /* role  */
3823
 
                id = queue_remove(id_queue);
3824
 
                free(id);       /* type  */
3825
 
                if (mlspol) {
3826
 
                        id = queue_remove(id_queue);
3827
 
                        free(id);
3828
 
                        for (l = 0; l < 2; l++) {
3829
 
                                while ((id = queue_remove(id_queue))) {
3830
 
                                        free(id);
3831
 
                                }
3832
 
                                id = queue_remove(id_queue);
3833
 
                                if (!id)
3834
 
                                        break;
3835
 
                                free(id);
3836
 
                        }
3837
 
                }
3838
 
                return 0;
3839
 
        }
3840
 
 
3841
 
        context_init(c);
3842
 
 
3843
 
        /* extract the user */
3844
 
        id = queue_remove(id_queue);
3845
 
        if (!id) {
3846
 
                yyerror("no effective user?");
3847
 
                goto bad;
3848
 
        }
3849
 
        if (!is_id_in_scope(SYM_USERS, id)) {
3850
 
                yyerror2("user %s is not within scope", id);
3851
 
                free(id);
3852
 
                goto bad;
3853
 
        }
3854
 
        usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
3855
 
                                                   (hashtab_key_t) id);
3856
 
        if (!usrdatum) {
3857
 
                sprintf(errormsg, "user %s is not defined", id);
3858
 
                yyerror(errormsg);
3859
 
                free(id);
3860
 
                goto bad;
3861
 
        }
3862
 
        c->user = usrdatum->s.value;
3863
 
 
3864
 
        /* no need to keep the user name */
3865
 
        free(id);
3866
 
 
3867
 
        /* extract the role */
3868
 
        id = (char *)queue_remove(id_queue);
3869
 
        if (!id) {
3870
 
                yyerror("no role name for sid context definition?");
3871
 
                return -1;
3872
 
        }
3873
 
        if (!is_id_in_scope(SYM_ROLES, id)) {
3874
 
                yyerror2("role %s is not within scope", id);
3875
 
                free(id);
3876
 
                return -1;
3877
 
        }
3878
 
        role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
3879
 
                                               (hashtab_key_t) id);
3880
 
        if (!role) {
3881
 
                sprintf(errormsg, "role %s is not defined", id);
3882
 
                yyerror(errormsg);
3883
 
                free(id);
3884
 
                return -1;
3885
 
        }
3886
 
        c->role = role->s.value;
3887
 
 
3888
 
        /* no need to keep the role name */
3889
 
        free(id);
3890
 
 
3891
 
        /* extract the type */
3892
 
        id = (char *)queue_remove(id_queue);
3893
 
        if (!id) {
3894
 
                yyerror("no type name for sid context definition?");
3895
 
                return -1;
3896
 
        }
3897
 
        if (!is_id_in_scope(SYM_TYPES, id)) {
3898
 
                yyerror2("type %s is not within scope", id);
3899
 
                free(id);
3900
 
                return -1;
3901
 
        }
3902
 
        typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
3903
 
                                                   (hashtab_key_t) id);
3904
 
        if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
3905
 
                sprintf(errormsg, "type %s is not defined or is an attribute",
3906
 
                        id);
3907
 
                yyerror(errormsg);
3908
 
                free(id);
3909
 
                return -1;
3910
 
        }
3911
 
        c->type = typdatum->s.value;
3912
 
 
3913
 
        /* no need to keep the type name */
3914
 
        free(id);
3915
 
 
3916
 
        if (mlspol) {
3917
 
                /* extract the low sensitivity */
3918
 
                id = (char *)queue_head(id_queue);
3919
 
                if (!id) {
3920
 
                        yyerror("no sensitivity name for sid context"
3921
 
                                " definition?");
3922
 
                        return -1;
3923
 
                }
3924
 
 
3925
 
                id = (char *)queue_remove(id_queue);
3926
 
                for (l = 0; l < 2; l++) {
3927
 
                        levdatum = (level_datum_t *)
3928
 
                            hashtab_search(policydbp->p_levels.table,
3929
 
                                           (hashtab_key_t) id);
3930
 
                        if (!levdatum) {
3931
 
                                sprintf(errormsg, "Sensitivity %s is not "
3932
 
                                        "defined", id);
3933
 
                                yyerror(errormsg);
3934
 
                                free(id);
3935
 
                                return -1;
3936
 
                        }
3937
 
                        free(id);
3938
 
                        c->range.level[l].sens = levdatum->level->sens;
3939
 
 
3940
 
                        /* extract low category set */
3941
 
                        while ((id = queue_remove(id_queue))) {
3942
 
                                if (parse_categories(id, levdatum,
3943
 
                                                     &c->range.level[l].cat)) {
3944
 
                                        free(id);
3945
 
                                        return -1;
3946
 
                                }
3947
 
                                free(id);
3948
 
                        }
3949
 
 
3950
 
                        /* extract high sensitivity */
3951
 
                        id = (char *)queue_remove(id_queue);
3952
 
                        if (!id)
3953
 
                                break;
3954
 
                }
3955
 
 
3956
 
                if (l == 0) {
3957
 
                        c->range.level[1].sens = c->range.level[0].sens;
3958
 
                        if (ebitmap_cpy(&c->range.level[1].cat,
3959
 
                                        &c->range.level[0].cat)) {
3960
 
 
3961
 
                                yyerror("out of memory");
3962
 
                                goto bad;
3963
 
                        }
3964
 
                }
3965
 
        }
3966
 
 
3967
 
        if (!policydb_context_isvalid(policydbp, c)) {
3968
 
                yyerror("invalid security context");
3969
 
                goto bad;
3970
 
        }
3971
 
        return 0;
3972
 
 
3973
 
      bad:
3974
 
        context_destroy(c);
3975
 
 
3976
 
        return -1;
3977
 
}
3978
 
 
3979
 
static int define_initial_sid_context(void)
3980
 
{
3981
 
        char *id;
3982
 
        ocontext_t *c, *head;
3983
 
 
3984
 
        if (pass == 1) {
3985
 
                id = (char *)queue_remove(id_queue);
3986
 
                free(id);
3987
 
                parse_security_context(NULL);
3988
 
                return 0;
3989
 
        }
3990
 
 
3991
 
        id = (char *)queue_remove(id_queue);
3992
 
        if (!id) {
3993
 
                yyerror("no sid name for SID context definition?");
3994
 
                return -1;
3995
 
        }
3996
 
        head = policydbp->ocontexts[OCON_ISID];
3997
 
        for (c = head; c; c = c->next) {
3998
 
                if (!strcmp(id, c->u.name))
3999
 
                        break;
4000
 
        }
4001
 
 
4002
 
        if (!c) {
4003
 
                sprintf(errormsg, "SID %s is not defined", id);
4004
 
                yyerror(errormsg);
4005
 
                free(id);
4006
 
                return -1;
4007
 
        }
4008
 
        if (c->context[0].user) {
4009
 
                sprintf(errormsg, "The context for SID %s is multiply defined",
4010
 
                        id);
4011
 
                yyerror(errormsg);
4012
 
                free(id);
4013
 
                return -1;
4014
 
        }
4015
 
        /* no need to keep the sid name */
4016
 
        free(id);
4017
 
 
4018
 
        if (parse_security_context(&c->context[0]))
4019
 
                return -1;
4020
 
 
4021
 
        return 0;
4022
 
}
4023
 
 
4024
 
static int define_fs_context(unsigned int major, unsigned int minor)
4025
 
{
4026
 
        ocontext_t *newc, *c, *head;
4027
 
 
4028
 
        if (pass == 1) {
4029
 
                parse_security_context(NULL);
4030
 
                parse_security_context(NULL);
4031
 
                return 0;
4032
 
        }
4033
 
 
4034
 
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4035
 
        if (!newc) {
4036
 
                yyerror("out of memory");
4037
 
                return -1;
4038
 
        }
4039
 
        memset(newc, 0, sizeof(ocontext_t));
4040
 
 
4041
 
        newc->u.name = (char *)malloc(6);
4042
 
        if (!newc->u.name) {
4043
 
                yyerror("out of memory");
4044
 
                free(newc);
4045
 
                return -1;
4046
 
        }
4047
 
        sprintf(newc->u.name, "%02x:%02x", major, minor);
4048
 
 
4049
 
        if (parse_security_context(&newc->context[0])) {
4050
 
                free(newc->u.name);
4051
 
                free(newc);
4052
 
                return -1;
4053
 
        }
4054
 
        if (parse_security_context(&newc->context[1])) {
4055
 
                context_destroy(&newc->context[0]);
4056
 
                free(newc->u.name);
4057
 
                free(newc);
4058
 
                return -1;
4059
 
        }
4060
 
        head = policydbp->ocontexts[OCON_FS];
4061
 
 
4062
 
        for (c = head; c; c = c->next) {
4063
 
                if (!strcmp(newc->u.name, c->u.name)) {
4064
 
                        sprintf(errormsg, "duplicate entry for file system %s",
4065
 
                                newc->u.name);
4066
 
                        yyerror(errormsg);
4067
 
                        context_destroy(&newc->context[0]);
4068
 
                        context_destroy(&newc->context[1]);
4069
 
                        free(newc->u.name);
4070
 
                        free(newc);
4071
 
                        return -1;
4072
 
                }
4073
 
        }
4074
 
 
4075
 
        newc->next = head;
4076
 
        policydbp->ocontexts[OCON_FS] = newc;
4077
 
 
4078
 
        return 0;
4079
 
}
4080
 
 
4081
 
static int define_port_context(unsigned int low, unsigned int high)
4082
 
{
4083
 
        ocontext_t *newc, *c, *l, *head;
4084
 
        unsigned int protocol;
4085
 
        char *id;
4086
 
 
4087
 
        if (pass == 1) {
4088
 
                id = (char *)queue_remove(id_queue);
4089
 
                free(id);
4090
 
                parse_security_context(NULL);
4091
 
                return 0;
4092
 
        }
4093
 
 
4094
 
        newc = malloc(sizeof(ocontext_t));
4095
 
        if (!newc) {
4096
 
                yyerror("out of memory");
4097
 
                return -1;
4098
 
        }
4099
 
        memset(newc, 0, sizeof(ocontext_t));
4100
 
 
4101
 
        id = (char *)queue_remove(id_queue);
4102
 
        if (!id) {
4103
 
                free(newc);
4104
 
                return -1;
4105
 
        }
4106
 
        if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
4107
 
                protocol = IPPROTO_TCP;
4108
 
        } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
4109
 
                protocol = IPPROTO_UDP;
4110
 
        } else {
4111
 
                sprintf(errormsg, "unrecognized protocol %s", id);
4112
 
                yyerror(errormsg);
4113
 
                free(newc);
4114
 
                return -1;
4115
 
        }
4116
 
 
4117
 
        newc->u.port.protocol = protocol;
4118
 
        newc->u.port.low_port = low;
4119
 
        newc->u.port.high_port = high;
4120
 
 
4121
 
        if (low > high) {
4122
 
                sprintf(errormsg, "low port %d exceeds high port %d", low,
4123
 
                        high);
4124
 
                yyerror(errormsg);
4125
 
                free(newc);
4126
 
                return -1;
4127
 
        }
4128
 
 
4129
 
        if (parse_security_context(&newc->context[0])) {
4130
 
                free(newc);
4131
 
                return -1;
4132
 
        }
4133
 
 
4134
 
        /* Preserve the matching order specified in the configuration. */
4135
 
        head = policydbp->ocontexts[OCON_PORT];
4136
 
        for (l = NULL, c = head; c; l = c, c = c->next) {
4137
 
                unsigned int prot2, low2, high2;
4138
 
 
4139
 
                prot2 = c->u.port.protocol;
4140
 
                low2 = c->u.port.low_port;
4141
 
                high2 = c->u.port.high_port;
4142
 
                if (protocol != prot2)
4143
 
                        continue;
4144
 
                if (low == low2 && high == high2) {
4145
 
                        sprintf(errormsg,
4146
 
                                "duplicate portcon entry for %s %d-%d ", id,
4147
 
                                low, high);
4148
 
                        goto bad;
4149
 
                }
4150
 
                if (low2 <= low && high2 >= high) {
4151
 
                        sprintf(errormsg,
4152
 
                                "portcon entry for %s %d-%d hidden by earlier entry for %d-%d",
4153
 
                                id, low, high, low2, high2);
4154
 
                        goto bad;
4155
 
                }
4156
 
        }
4157
 
 
4158
 
        if (l)
4159
 
                l->next = newc;
4160
 
        else
4161
 
                policydbp->ocontexts[OCON_PORT] = newc;
4162
 
 
4163
 
        return 0;
4164
 
 
4165
 
      bad:
4166
 
        yyerror(errormsg);
4167
 
        free(newc);
4168
 
        return -1;
4169
 
}
4170
 
 
4171
 
static int define_netif_context(void)
4172
 
{
4173
 
        ocontext_t *newc, *c, *head;
4174
 
 
4175
 
        if (pass == 1) {
4176
 
                free(queue_remove(id_queue));
4177
 
                parse_security_context(NULL);
4178
 
                parse_security_context(NULL);
4179
 
                return 0;
4180
 
        }
4181
 
 
4182
 
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4183
 
        if (!newc) {
4184
 
                yyerror("out of memory");
4185
 
                return -1;
4186
 
        }
4187
 
        memset(newc, 0, sizeof(ocontext_t));
4188
 
 
4189
 
        newc->u.name = (char *)queue_remove(id_queue);
4190
 
        if (!newc->u.name) {
4191
 
                free(newc);
4192
 
                return -1;
4193
 
        }
4194
 
        if (parse_security_context(&newc->context[0])) {
4195
 
                free(newc->u.name);
4196
 
                free(newc);
4197
 
                return -1;
4198
 
        }
4199
 
        if (parse_security_context(&newc->context[1])) {
4200
 
                context_destroy(&newc->context[0]);
4201
 
                free(newc->u.name);
4202
 
                free(newc);
4203
 
                return -1;
4204
 
        }
4205
 
        head = policydbp->ocontexts[OCON_NETIF];
4206
 
 
4207
 
        for (c = head; c; c = c->next) {
4208
 
                if (!strcmp(newc->u.name, c->u.name)) {
4209
 
                        sprintf(errormsg,
4210
 
                                "duplicate entry for network interface %s",
4211
 
                                newc->u.name);
4212
 
                        yyerror(errormsg);
4213
 
                        context_destroy(&newc->context[0]);
4214
 
                        context_destroy(&newc->context[1]);
4215
 
                        free(newc->u.name);
4216
 
                        free(newc);
4217
 
                        return -1;
4218
 
                }
4219
 
        }
4220
 
 
4221
 
        newc->next = head;
4222
 
        policydbp->ocontexts[OCON_NETIF] = newc;
4223
 
        return 0;
4224
 
}
4225
 
 
4226
 
static int define_ipv4_node_context()
4227
 
{       
4228
 
        char *id;
4229
 
        int rc = 0;
4230
 
        struct in_addr addr, mask;
4231
 
        ocontext_t *newc, *c, *l, *head;
4232
 
 
4233
 
        if (pass == 1) {
4234
 
                free(queue_remove(id_queue));
4235
 
                free(queue_remove(id_queue));
4236
 
                parse_security_context(NULL);
4237
 
                goto out;
4238
 
        }
4239
 
 
4240
 
        id = queue_remove(id_queue);
4241
 
        if (!id) {
4242
 
                yyerror("failed to read ipv4 address");
4243
 
                rc = -1;
4244
 
                goto out;
4245
 
        }
4246
 
 
4247
 
        rc = inet_pton(AF_INET, id, &addr);
4248
 
        free(id);
4249
 
        if (rc < 1) {
4250
 
                yyerror("failed to parse ipv4 address");
4251
 
                if (rc == 0)
4252
 
                        rc = -1;
4253
 
                goto out;
4254
 
        }
4255
 
 
4256
 
        id = queue_remove(id_queue);
4257
 
        if (!id) {
4258
 
                yyerror("failed to read ipv4 address");
4259
 
                rc = -1;
4260
 
                goto out;
4261
 
        }
4262
 
 
4263
 
        rc = inet_pton(AF_INET, id, &mask);
4264
 
        free(id);
4265
 
        if (rc < 1) {
4266
 
                yyerror("failed to parse ipv4 mask");
4267
 
                if (rc == 0)
4268
 
                        rc = -1;
4269
 
                goto out;
4270
 
        }
4271
 
 
4272
 
        newc = malloc(sizeof(ocontext_t));
4273
 
        if (!newc) {
4274
 
                yyerror("out of memory");
4275
 
                rc = -1;
4276
 
                goto out;
4277
 
        }
4278
 
 
4279
 
        memset(newc, 0, sizeof(ocontext_t));
4280
 
        newc->u.node.addr = addr.s_addr;
4281
 
        newc->u.node.mask = mask.s_addr;
4282
 
 
4283
 
        if (parse_security_context(&newc->context[0])) {
4284
 
                free(newc);
4285
 
                return -1;
4286
 
        }
4287
 
 
4288
 
        /* Create order of most specific to least retaining
4289
 
           the order specified in the configuration. */
4290
 
        head = policydbp->ocontexts[OCON_NODE];
4291
 
        for (l = NULL, c = head; c; l = c, c = c->next) {
4292
 
                if (newc->u.node.mask > c->u.node.mask)
4293
 
                        break;
4294
 
        }
4295
 
 
4296
 
        newc->next = c;
4297
 
 
4298
 
        if (l)
4299
 
                l->next = newc;
4300
 
        else
4301
 
                policydbp->ocontexts[OCON_NODE] = newc;
4302
 
        rc = 0;
4303
 
out:
4304
 
        return rc;
4305
 
}
4306
 
 
4307
 
static int define_ipv6_node_context(void)
4308
 
{
4309
 
        char *id;
4310
 
        int rc = 0;
4311
 
        struct in6_addr addr, mask;
4312
 
        ocontext_t *newc, *c, *l, *head;
4313
 
 
4314
 
        if (pass == 1) {
4315
 
                free(queue_remove(id_queue));
4316
 
                free(queue_remove(id_queue));
4317
 
                parse_security_context(NULL);
4318
 
                goto out;
4319
 
        }
4320
 
 
4321
 
        id = queue_remove(id_queue);
4322
 
        if (!id) {
4323
 
                yyerror("failed to read ipv6 address");
4324
 
                rc = -1;
4325
 
                goto out;
4326
 
        }
4327
 
 
4328
 
        rc = inet_pton(AF_INET6, id, &addr);
4329
 
        free(id);
4330
 
        if (rc < 1) {
4331
 
                yyerror("failed to parse ipv6 address");
4332
 
                if (rc == 0)
4333
 
                        rc = -1;
4334
 
                goto out;
4335
 
        }
4336
 
 
4337
 
        id = queue_remove(id_queue);
4338
 
        if (!id) {
4339
 
                yyerror("failed to read ipv6 address");
4340
 
                rc = -1;
4341
 
                goto out;
4342
 
        }
4343
 
 
4344
 
        rc = inet_pton(AF_INET6, id, &mask);
4345
 
        free(id);
4346
 
        if (rc < 1) {
4347
 
                yyerror("failed to parse ipv6 mask");
4348
 
                if (rc == 0)
4349
 
                        rc = -1;
4350
 
                goto out;
4351
 
        }
4352
 
 
4353
 
        newc = malloc(sizeof(ocontext_t));
4354
 
        if (!newc) {
4355
 
                yyerror("out of memory");
4356
 
                rc = -1;
4357
 
                goto out;
4358
 
        }
4359
 
 
4360
 
        memset(newc, 0, sizeof(ocontext_t));
4361
 
        memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
4362
 
        memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
4363
 
 
4364
 
        if (parse_security_context(&newc->context[0])) {
4365
 
                free(newc);
4366
 
                rc = -1;
4367
 
                goto out;
4368
 
        }
4369
 
 
4370
 
        /* Create order of most specific to least retaining
4371
 
           the order specified in the configuration. */
4372
 
        head = policydbp->ocontexts[OCON_NODE6];
4373
 
        for (l = NULL, c = head; c; l = c, c = c->next) {
4374
 
                if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
4375
 
                        break;
4376
 
        }
4377
 
 
4378
 
        newc->next = c;
4379
 
 
4380
 
        if (l)
4381
 
                l->next = newc;
4382
 
        else
4383
 
                policydbp->ocontexts[OCON_NODE6] = newc;
4384
 
 
4385
 
        rc = 0;
4386
 
      out:
4387
 
        return rc;
4388
 
}
4389
 
 
4390
 
static int define_fs_use(int behavior)
4391
 
{
4392
 
        ocontext_t *newc, *c, *head;
4393
 
 
4394
 
        if (pass == 1) {
4395
 
                free(queue_remove(id_queue));
4396
 
                parse_security_context(NULL);
4397
 
                return 0;
4398
 
        }
4399
 
 
4400
 
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4401
 
        if (!newc) {
4402
 
                yyerror("out of memory");
4403
 
                return -1;
4404
 
        }
4405
 
        memset(newc, 0, sizeof(ocontext_t));
4406
 
 
4407
 
        newc->u.name = (char *)queue_remove(id_queue);
4408
 
        if (!newc->u.name) {
4409
 
                free(newc);
4410
 
                return -1;
4411
 
        }
4412
 
        newc->v.behavior = behavior;
4413
 
        if (parse_security_context(&newc->context[0])) {
4414
 
                free(newc->u.name);
4415
 
                free(newc);
4416
 
                return -1;
4417
 
        }
4418
 
 
4419
 
        head = policydbp->ocontexts[OCON_FSUSE];
4420
 
 
4421
 
        for (c = head; c; c = c->next) {
4422
 
                if (!strcmp(newc->u.name, c->u.name)) {
4423
 
                        sprintf(errormsg,
4424
 
                                "duplicate fs_use entry for filesystem type %s",
4425
 
                                newc->u.name);
4426
 
                        yyerror(errormsg);
4427
 
                        context_destroy(&newc->context[0]);
4428
 
                        free(newc->u.name);
4429
 
                        free(newc);
4430
 
                        return -1;
4431
 
                }
4432
 
        }
4433
 
 
4434
 
        newc->next = head;
4435
 
        policydbp->ocontexts[OCON_FSUSE] = newc;
4436
 
        return 0;
4437
 
}
4438
 
 
4439
 
static int define_genfs_context_helper(char *fstype, int has_type)
4440
 
{
4441
 
        struct genfs *genfs_p, *genfs, *newgenfs;
4442
 
        ocontext_t *newc, *c, *head, *p;
4443
 
        char *type = NULL;
4444
 
        int len, len2;
4445
 
 
4446
 
        if (pass == 1) {
4447
 
                free(fstype);
4448
 
                free(queue_remove(id_queue));
4449
 
                if (has_type)
4450
 
                        free(queue_remove(id_queue));
4451
 
                parse_security_context(NULL);
4452
 
                return 0;
4453
 
        }
4454
 
 
4455
 
        for (genfs_p = NULL, genfs = policydbp->genfs;
4456
 
             genfs; genfs_p = genfs, genfs = genfs->next) {
4457
 
                if (strcmp(fstype, genfs->fstype) <= 0)
4458
 
                        break;
4459
 
        }
4460
 
 
4461
 
        if (!genfs || strcmp(fstype, genfs->fstype)) {
4462
 
                newgenfs = malloc(sizeof(struct genfs));
4463
 
                if (!newgenfs) {
4464
 
                        yyerror("out of memory");
4465
 
                        return -1;
4466
 
                }
4467
 
                memset(newgenfs, 0, sizeof(struct genfs));
4468
 
                newgenfs->fstype = fstype;
4469
 
                newgenfs->next = genfs;
4470
 
                if (genfs_p)
4471
 
                        genfs_p->next = newgenfs;
4472
 
                else
4473
 
                        policydbp->genfs = newgenfs;
4474
 
                genfs = newgenfs;
4475
 
        }
4476
 
 
4477
 
        newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4478
 
        if (!newc) {
4479
 
                yyerror("out of memory");
4480
 
                return -1;
4481
 
        }
4482
 
        memset(newc, 0, sizeof(ocontext_t));
4483
 
 
4484
 
        newc->u.name = (char *)queue_remove(id_queue);
4485
 
        if (!newc->u.name)
4486
 
                goto fail;
4487
 
        if (has_type) {
4488
 
                type = (char *)queue_remove(id_queue);
4489
 
                if (!type)
4490
 
                        goto fail;
4491
 
                if (type[1] != 0) {
4492
 
                        sprintf(errormsg, "invalid type %s", type);
4493
 
                        yyerror(errormsg);
4494
 
                        goto fail;
4495
 
                }
4496
 
                switch (type[0]) {
4497
 
                case 'b':
4498
 
                        newc->v.sclass = SECCLASS_BLK_FILE;
4499
 
                        break;
4500
 
                case 'c':
4501
 
                        newc->v.sclass = SECCLASS_CHR_FILE;
4502
 
                        break;
4503
 
                case 'd':
4504
 
                        newc->v.sclass = SECCLASS_DIR;
4505
 
                        break;
4506
 
                case 'p':
4507
 
                        newc->v.sclass = SECCLASS_FIFO_FILE;
4508
 
                        break;
4509
 
                case 'l':
4510
 
                        newc->v.sclass = SECCLASS_LNK_FILE;
4511
 
                        break;
4512
 
                case 's':
4513
 
                        newc->v.sclass = SECCLASS_SOCK_FILE;
4514
 
                        break;
4515
 
                case '-':
4516
 
                        newc->v.sclass = SECCLASS_FILE;
4517
 
                        break;
4518
 
                default:
4519
 
                        sprintf(errormsg, "invalid type %s", type);
4520
 
                        yyerror(errormsg);
4521
 
                        goto fail;
4522
 
                }
4523
 
        }
4524
 
        if (parse_security_context(&newc->context[0]))
4525
 
                goto fail;
4526
 
 
4527
 
        head = genfs->head;
4528
 
 
4529
 
        for (p = NULL, c = head; c; p = c, c = c->next) {
4530
 
                if (!strcmp(newc->u.name, c->u.name) &&
4531
 
                    (!newc->v.sclass || !c->v.sclass
4532
 
                     || newc->v.sclass == c->v.sclass)) {
4533
 
                        sprintf(errormsg,
4534
 
                                "duplicate entry for genfs entry (%s, %s)",
4535
 
                                fstype, newc->u.name);
4536
 
                        yyerror(errormsg);
4537
 
                        goto fail;
4538
 
                }
4539
 
                len = strlen(newc->u.name);
4540
 
                len2 = strlen(c->u.name);
4541
 
                if (len > len2)
4542
 
                        break;
4543
 
        }
4544
 
 
4545
 
        newc->next = c;
4546
 
        if (p)
4547
 
                p->next = newc;
4548
 
        else
4549
 
                genfs->head = newc;
4550
 
        return 0;
4551
 
      fail:
4552
 
        if (type)
4553
 
                free(type);
4554
 
        context_destroy(&newc->context[0]);
4555
 
        if (fstype)
4556
 
                free(fstype);
4557
 
        if (newc->u.name)
4558
 
                free(newc->u.name);
4559
 
        free(newc);
4560
 
        return -1;
4561
 
}
4562
 
 
4563
 
static int define_genfs_context(int has_type)
4564
 
{
4565
 
        return define_genfs_context_helper(queue_remove(id_queue), has_type);
4566
 
}
4567
 
 
4568
 
static int define_range_trans(int class_specified)
4569
 
{
4570
 
        char *id;
4571
 
        level_datum_t *levdatum = 0;
4572
 
        class_datum_t *cladatum;
4573
 
        range_trans_rule_t *rule;
4574
 
        int l, add = 1;
4575
 
 
4576
 
        if (!mlspol) {
4577
 
                yyerror("range_transition rule in non-MLS configuration");
4578
 
                return -1;
4579
 
        }
4580
 
 
4581
 
        if (pass == 1) {
4582
 
                while ((id = queue_remove(id_queue)))
4583
 
                        free(id);
4584
 
                while ((id = queue_remove(id_queue)))
4585
 
                        free(id);
4586
 
                if (class_specified)
4587
 
                        while ((id = queue_remove(id_queue)))
4588
 
                                free(id);
4589
 
                id = queue_remove(id_queue);
4590
 
                free(id);
4591
 
                for (l = 0; l < 2; l++) {
4592
 
                        while ((id = queue_remove(id_queue))) {
4593
 
                                free(id);
4594
 
                        }
4595
 
                        id = queue_remove(id_queue);
4596
 
                        if (!id)
4597
 
                                break;
4598
 
                        free(id);
4599
 
                }
4600
 
                return 0;
4601
 
        }
4602
 
 
4603
 
        rule = malloc(sizeof(struct range_trans_rule));
4604
 
        if (!rule) {
4605
 
                yyerror("out of memory");
4606
 
                return -1;
4607
 
        }
4608
 
        range_trans_rule_init(rule);
4609
 
 
4610
 
        while ((id = queue_remove(id_queue))) {
4611
 
                if (set_types(&rule->stypes, id, &add, 0))
4612
 
                        goto out;
4613
 
        }
4614
 
        add = 1;
4615
 
        while ((id = queue_remove(id_queue))) {
4616
 
                if (set_types(&rule->ttypes, id, &add, 0))
4617
 
                        goto out;
4618
 
        }
4619
 
 
4620
 
        if (class_specified) {
4621
 
                while ((id = queue_remove(id_queue))) {
4622
 
                        if (!is_id_in_scope(SYM_CLASSES, id)) {
4623
 
                                yyerror2("class %s is not within scope", id);
4624
 
                                free(id);
4625
 
                                goto out;
4626
 
                        }
4627
 
                        cladatum = hashtab_search(policydbp->p_classes.table,
4628
 
                                                  id);
4629
 
                        if (!cladatum) {
4630
 
                                sprintf(errormsg, "unknown class %s", id);
4631
 
                                yyerror(errormsg);
4632
 
                                goto out;
4633
 
                        }
4634
 
 
4635
 
                        ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1,
4636
 
                                        TRUE);
4637
 
                        free(id);
4638
 
                }
4639
 
        } else {
4640
 
                cladatum = hashtab_search(policydbp->p_classes.table,
4641
 
                                          "process");
4642
 
                if (!cladatum) {
4643
 
                        sprintf(errormsg, "could not find process class for "
4644
 
                                "legacy range_transition statement\n");
4645
 
                        yyerror(errormsg);
4646
 
                        goto out;
4647
 
                }
4648
 
 
4649
 
                ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE);
4650
 
        }
4651
 
 
4652
 
        id = (char *)queue_remove(id_queue);
4653
 
        if (!id) {
4654
 
                yyerror("no range in range_transition definition?");
4655
 
                goto out;
4656
 
        }
4657
 
        for (l = 0; l < 2; l++) {
4658
 
                levdatum = hashtab_search(policydbp->p_levels.table, id);
4659
 
                if (!levdatum) {
4660
 
                        sprintf(errormsg,
4661
 
                                "unknown level %s used in range_transition "
4662
 
                                "definition", id);
4663
 
                        yyerror(errormsg);
4664
 
                        free(id);
4665
 
                        goto out;
4666
 
                }
4667
 
                free(id);
4668
 
 
4669
 
                rule->trange.level[l].sens = levdatum->level->sens;
4670
 
 
4671
 
                while ((id = queue_remove(id_queue))) {
4672
 
                        if (parse_semantic_categories(id, levdatum,
4673
 
                                                  &rule->trange.level[l].cat)) {
4674
 
                                free(id);
4675
 
                                goto out;
4676
 
                        }
4677
 
                        free(id);
4678
 
                }
4679
 
 
4680
 
                id = (char *)queue_remove(id_queue);
4681
 
                if (!id)
4682
 
                        break;
4683
 
        }
4684
 
        if (l == 0) {
4685
 
                if (mls_semantic_level_cpy(&rule->trange.level[1],
4686
 
                                           &rule->trange.level[0])) {
4687
 
                        yyerror("out of memory");
4688
 
                        goto out;
4689
 
                }
4690
 
        }
4691
 
 
4692
 
        append_range_trans(rule);
4693
 
        return 0;
4694
 
 
4695
 
out:
4696
 
        range_trans_rule_destroy(rule);
4697
 
        return -1;
4698
 
}
4699
 
 
4700
 
 
4701
 
/* FLASK */
4702
 
 
4703