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