1 #include <string.h>
2 #include <stdlib.h>
3
4 #include "handle.h"
5 #include "private.h"
6 #include "debug.h"
7
8 #include <sepol/booleans.h>
9 #include <sepol/policydb/hashtab.h>
10 #include <sepol/policydb/policydb.h>
11 #include <sepol/policydb/conditional.h>
12 #include "boolean_internal.h"
13
bool_update(sepol_handle_t * handle,policydb_t * policydb,const sepol_bool_key_t * key,const sepol_bool_t * data)14 static int bool_update(sepol_handle_t * handle,
15 policydb_t * policydb,
16 const sepol_bool_key_t * key, const sepol_bool_t * data)
17 {
18
19 const char *cname;
20 char *name;
21 int value;
22
23 sepol_bool_key_unpack(key, &cname);
24 name = strdup(cname);
25 value = sepol_bool_get_value(data);
26
27 if (!name)
28 goto omem;
29
30 cond_bool_datum_t *datum =
31 hashtab_search(policydb->p_bools.table, name);
32 if (!datum) {
33 ERR(handle, "boolean %s no longer in policy", name);
34 goto err;
35 }
36 if (value != 0 && value != 1) {
37 ERR(handle, "illegal value %d for boolean %s", value, name);
38 goto err;
39 }
40
41 free(name);
42 datum->state = value;
43 return STATUS_SUCCESS;
44
45 omem:
46 ERR(handle, "out of memory");
47
48 err:
49 free(name);
50 ERR(handle, "could not update boolean %s", cname);
51 return STATUS_ERR;
52 }
53
bool_to_record(sepol_handle_t * handle,const policydb_t * policydb,int bool_idx,sepol_bool_t ** record)54 static int bool_to_record(sepol_handle_t * handle,
55 const policydb_t * policydb,
56 int bool_idx, sepol_bool_t ** record)
57 {
58
59 const char *name = policydb->p_bool_val_to_name[bool_idx];
60 cond_bool_datum_t *booldatum = policydb->bool_val_to_struct[bool_idx];
61 int value = booldatum->state;
62
63 sepol_bool_t *tmp_record = NULL;
64
65 if (sepol_bool_create(handle, &tmp_record) < 0)
66 goto err;
67
68 if (sepol_bool_set_name(handle, tmp_record, name) < 0)
69 goto err;
70
71 sepol_bool_set_value(tmp_record, value);
72
73 *record = tmp_record;
74 return STATUS_SUCCESS;
75
76 err:
77 ERR(handle, "could not convert boolean %s to record", name);
78 sepol_bool_free(tmp_record);
79 return STATUS_ERR;
80 }
81
sepol_bool_set(sepol_handle_t * handle,sepol_policydb_t * p,const sepol_bool_key_t * key,const sepol_bool_t * data)82 int sepol_bool_set(sepol_handle_t * handle,
83 sepol_policydb_t * p,
84 const sepol_bool_key_t * key, const sepol_bool_t * data)
85 {
86
87 const char *name;
88 sepol_bool_key_unpack(key, &name);
89
90 policydb_t *policydb = &p->p;
91 if (bool_update(handle, policydb, key, data) < 0)
92 goto err;
93
94 if (evaluate_conds(policydb) < 0) {
95 ERR(handle, "error while re-evaluating conditionals");
96 goto err;
97 }
98
99 return STATUS_SUCCESS;
100
101 err:
102 ERR(handle, "could not set boolean %s", name);
103 return STATUS_ERR;
104 }
105
sepol_bool_count(sepol_handle_t * handle,const sepol_policydb_t * p,unsigned int * response)106 int sepol_bool_count(sepol_handle_t * handle __attribute__ ((unused)),
107 const sepol_policydb_t * p, unsigned int *response)
108 {
109
110 const policydb_t *policydb = &p->p;
111 *response = policydb->p_bools.nprim;
112
113 handle = NULL;
114 return STATUS_SUCCESS;
115 }
116
sepol_bool_exists(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_bool_key_t * key,int * response)117 int sepol_bool_exists(sepol_handle_t * handle,
118 const sepol_policydb_t * p,
119 const sepol_bool_key_t * key, int *response)
120 {
121
122 const policydb_t *policydb = &p->p;
123
124 const char *cname;
125 char *name = NULL;
126 sepol_bool_key_unpack(key, &cname);
127 name = strdup(cname);
128
129 if (!name) {
130 ERR(handle, "out of memory, could not check "
131 "if user %s exists", cname);
132 return STATUS_ERR;
133 }
134
135 *response = (hashtab_search(policydb->p_bools.table, name) != NULL);
136 free(name);
137 return STATUS_SUCCESS;
138 }
139
sepol_bool_query(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_bool_key_t * key,sepol_bool_t ** response)140 int sepol_bool_query(sepol_handle_t * handle,
141 const sepol_policydb_t * p,
142 const sepol_bool_key_t * key, sepol_bool_t ** response)
143 {
144
145 const policydb_t *policydb = &p->p;
146 cond_bool_datum_t *booldatum = NULL;
147
148 const char *cname;
149 char *name = NULL;
150 sepol_bool_key_unpack(key, &cname);
151 name = strdup(cname);
152
153 if (!name)
154 goto omem;
155
156 booldatum = hashtab_search(policydb->p_bools.table, name);
157 if (!booldatum) {
158 *response = NULL;
159 return STATUS_SUCCESS;
160 }
161
162 if (bool_to_record(handle, policydb,
163 booldatum->s.value - 1, response) < 0)
164 goto err;
165
166 free(name);
167 return STATUS_SUCCESS;
168
169 omem:
170 ERR(handle, "out of memory");
171
172 err:
173 ERR(handle, "could not query boolean %s", cname);
174 free(name);
175 return STATUS_ERR;
176 }
177
sepol_bool_iterate(sepol_handle_t * handle,const sepol_policydb_t * p,int (* fn)(const sepol_bool_t * boolean,void * fn_arg),void * arg)178 int sepol_bool_iterate(sepol_handle_t * handle,
179 const sepol_policydb_t * p,
180 int (*fn) (const sepol_bool_t * boolean,
181 void *fn_arg), void *arg)
182 {
183
184 const policydb_t *policydb = &p->p;
185 unsigned int nbools = policydb->p_bools.nprim;
186 sepol_bool_t *boolean = NULL;
187 unsigned int i;
188
189 /* For each boolean */
190 for (i = 0; i < nbools; i++) {
191
192 int status;
193
194 if (bool_to_record(handle, policydb, i, &boolean) < 0)
195 goto err;
196
197 /* Invoke handler */
198 status = fn(boolean, arg);
199 if (status < 0)
200 goto err;
201
202 sepol_bool_free(boolean);
203 boolean = NULL;
204
205 /* Handler requested exit */
206 if (status > 0)
207 break;
208 }
209
210 return STATUS_SUCCESS;
211
212 err:
213 ERR(handle, "could not iterate over booleans");
214 sepol_bool_free(boolean);
215 return STATUS_ERR;
216 }
217