• 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 	cond_bool_datum_t *datum;
23 
24 	sepol_bool_key_unpack(key, &cname);
25 	name = strdup(cname);
26 	value = sepol_bool_get_value(data);
27 
28 	if (!name)
29 		goto omem;
30 
31 	datum = 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 	policydb_t *policydb = &p->p;
88 	const char *name;
89 	sepol_bool_key_unpack(key, &name);
90 
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 		free(name);
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