• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 	return STATUS_SUCCESS;
114 }
115 
sepol_bool_exists(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_bool_key_t * key,int * response)116 int sepol_bool_exists(sepol_handle_t * handle,
117 		      const sepol_policydb_t * p,
118 		      const sepol_bool_key_t * key, int *response)
119 {
120 
121 	const policydb_t *policydb = &p->p;
122 
123 	const char *cname;
124 	char *name = NULL;
125 	sepol_bool_key_unpack(key, &cname);
126 	name = strdup(cname);
127 
128 	if (!name) {
129 		ERR(handle, "out of memory, could not check "
130 		    "if user %s exists", cname);
131 		return STATUS_ERR;
132 	}
133 
134 	*response = (hashtab_search(policydb->p_bools.table, name) != NULL);
135 	free(name);
136 	return STATUS_SUCCESS;
137 }
138 
sepol_bool_query(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_bool_key_t * key,sepol_bool_t ** response)139 int sepol_bool_query(sepol_handle_t * handle,
140 		     const sepol_policydb_t * p,
141 		     const sepol_bool_key_t * key, sepol_bool_t ** response)
142 {
143 
144 	const policydb_t *policydb = &p->p;
145 	cond_bool_datum_t *booldatum = NULL;
146 
147 	const char *cname;
148 	char *name = NULL;
149 	sepol_bool_key_unpack(key, &cname);
150 	name = strdup(cname);
151 
152 	if (!name)
153 		goto omem;
154 
155 	booldatum = hashtab_search(policydb->p_bools.table, name);
156 	if (!booldatum) {
157 		*response = NULL;
158 		return STATUS_SUCCESS;
159 	}
160 
161 	if (bool_to_record(handle, policydb,
162 			   booldatum->s.value - 1, response) < 0)
163 		goto err;
164 
165 	free(name);
166 	return STATUS_SUCCESS;
167 
168       omem:
169 	ERR(handle, "out of memory");
170 
171       err:
172 	ERR(handle, "could not query boolean %s", cname);
173 	free(name);
174 	return STATUS_ERR;
175 }
176 
sepol_bool_iterate(sepol_handle_t * handle,const sepol_policydb_t * p,int (* fn)(const sepol_bool_t * boolean,void * fn_arg),void * arg)177 int sepol_bool_iterate(sepol_handle_t * handle,
178 		       const sepol_policydb_t * p,
179 		       int (*fn) (const sepol_bool_t * boolean,
180 				  void *fn_arg), void *arg)
181 {
182 
183 	const policydb_t *policydb = &p->p;
184 	unsigned int nbools = policydb->p_bools.nprim;
185 	sepol_bool_t *boolean = NULL;
186 	unsigned int i;
187 
188 	/* For each boolean */
189 	for (i = 0; i < nbools; i++) {
190 
191 		int status;
192 
193 		if (bool_to_record(handle, policydb, i, &boolean) < 0)
194 			goto err;
195 
196 		/* Invoke handler */
197 		status = fn(boolean, arg);
198 		if (status < 0)
199 			goto err;
200 
201 		sepol_bool_free(boolean);
202 		boolean = NULL;
203 
204 		/* Handler requested exit */
205 		if (status > 0)
206 			break;
207 	}
208 
209 	return STATUS_SUCCESS;
210 
211       err:
212 	ERR(handle, "could not iterate over booleans");
213 	sepol_bool_free(boolean);
214 	return STATUS_ERR;
215 }
216