xref: /aosp_15_r20/external/selinux/libsepol/src/booleans.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
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