1*2d543d20SAndroid Build Coastguard Worker #include <netinet/in.h>
2*2d543d20SAndroid Build Coastguard Worker #include <arpa/inet.h>
3*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
4*2d543d20SAndroid Build Coastguard Worker
5*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
6*2d543d20SAndroid Build Coastguard Worker #include "context.h"
7*2d543d20SAndroid Build Coastguard Worker #include "handle.h"
8*2d543d20SAndroid Build Coastguard Worker
9*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
10*2d543d20SAndroid Build Coastguard Worker #include "node_internal.h"
11*2d543d20SAndroid Build Coastguard Worker
12*2d543d20SAndroid Build Coastguard Worker /* Create a low level node structure from
13*2d543d20SAndroid Build Coastguard Worker * a high level representation */
node_from_record(sepol_handle_t * handle,const policydb_t * policydb,ocontext_t ** node,const sepol_node_t * data)14*2d543d20SAndroid Build Coastguard Worker static int node_from_record(sepol_handle_t * handle,
15*2d543d20SAndroid Build Coastguard Worker const policydb_t * policydb,
16*2d543d20SAndroid Build Coastguard Worker ocontext_t ** node, const sepol_node_t * data)
17*2d543d20SAndroid Build Coastguard Worker {
18*2d543d20SAndroid Build Coastguard Worker
19*2d543d20SAndroid Build Coastguard Worker ocontext_t *tmp_node = NULL;
20*2d543d20SAndroid Build Coastguard Worker context_struct_t *tmp_con = NULL;
21*2d543d20SAndroid Build Coastguard Worker char *addr_buf = NULL, *mask_buf = NULL;
22*2d543d20SAndroid Build Coastguard Worker size_t addr_bsize, mask_bsize;
23*2d543d20SAndroid Build Coastguard Worker int proto;
24*2d543d20SAndroid Build Coastguard Worker
25*2d543d20SAndroid Build Coastguard Worker tmp_node = (ocontext_t *) calloc(1, sizeof(ocontext_t));
26*2d543d20SAndroid Build Coastguard Worker if (!tmp_node)
27*2d543d20SAndroid Build Coastguard Worker goto omem;
28*2d543d20SAndroid Build Coastguard Worker
29*2d543d20SAndroid Build Coastguard Worker /* Address and netmask */
30*2d543d20SAndroid Build Coastguard Worker if (sepol_node_get_addr_bytes(handle, data, &addr_buf, &addr_bsize) < 0)
31*2d543d20SAndroid Build Coastguard Worker goto err;
32*2d543d20SAndroid Build Coastguard Worker if (sepol_node_get_mask_bytes(handle, data, &mask_buf, &mask_bsize) < 0)
33*2d543d20SAndroid Build Coastguard Worker goto err;
34*2d543d20SAndroid Build Coastguard Worker
35*2d543d20SAndroid Build Coastguard Worker proto = sepol_node_get_proto(data);
36*2d543d20SAndroid Build Coastguard Worker
37*2d543d20SAndroid Build Coastguard Worker switch (proto) {
38*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_IP4:
39*2d543d20SAndroid Build Coastguard Worker memcpy(&tmp_node->u.node.addr, addr_buf, addr_bsize);
40*2d543d20SAndroid Build Coastguard Worker memcpy(&tmp_node->u.node.mask, mask_buf, mask_bsize);
41*2d543d20SAndroid Build Coastguard Worker break;
42*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_IP6:
43*2d543d20SAndroid Build Coastguard Worker memcpy(tmp_node->u.node6.addr, addr_buf, addr_bsize);
44*2d543d20SAndroid Build Coastguard Worker memcpy(tmp_node->u.node6.mask, mask_buf, mask_bsize);
45*2d543d20SAndroid Build Coastguard Worker break;
46*2d543d20SAndroid Build Coastguard Worker default:
47*2d543d20SAndroid Build Coastguard Worker ERR(handle, "unsupported protocol %u", proto);
48*2d543d20SAndroid Build Coastguard Worker goto err;
49*2d543d20SAndroid Build Coastguard Worker }
50*2d543d20SAndroid Build Coastguard Worker free(addr_buf);
51*2d543d20SAndroid Build Coastguard Worker free(mask_buf);
52*2d543d20SAndroid Build Coastguard Worker addr_buf = NULL;
53*2d543d20SAndroid Build Coastguard Worker mask_buf = NULL;
54*2d543d20SAndroid Build Coastguard Worker
55*2d543d20SAndroid Build Coastguard Worker /* Context */
56*2d543d20SAndroid Build Coastguard Worker if (context_from_record(handle, policydb, &tmp_con,
57*2d543d20SAndroid Build Coastguard Worker sepol_node_get_con(data)) < 0)
58*2d543d20SAndroid Build Coastguard Worker goto err;
59*2d543d20SAndroid Build Coastguard Worker context_cpy(&tmp_node->context[0], tmp_con);
60*2d543d20SAndroid Build Coastguard Worker context_destroy(tmp_con);
61*2d543d20SAndroid Build Coastguard Worker free(tmp_con);
62*2d543d20SAndroid Build Coastguard Worker tmp_con = NULL;
63*2d543d20SAndroid Build Coastguard Worker
64*2d543d20SAndroid Build Coastguard Worker *node = tmp_node;
65*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
66*2d543d20SAndroid Build Coastguard Worker
67*2d543d20SAndroid Build Coastguard Worker omem:
68*2d543d20SAndroid Build Coastguard Worker ERR(handle, "out of memory");
69*2d543d20SAndroid Build Coastguard Worker
70*2d543d20SAndroid Build Coastguard Worker err:
71*2d543d20SAndroid Build Coastguard Worker if (tmp_node != NULL) {
72*2d543d20SAndroid Build Coastguard Worker context_destroy(&tmp_node->context[0]);
73*2d543d20SAndroid Build Coastguard Worker free(tmp_node);
74*2d543d20SAndroid Build Coastguard Worker }
75*2d543d20SAndroid Build Coastguard Worker context_destroy(tmp_con);
76*2d543d20SAndroid Build Coastguard Worker free(tmp_con);
77*2d543d20SAndroid Build Coastguard Worker free(addr_buf);
78*2d543d20SAndroid Build Coastguard Worker free(mask_buf);
79*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not create node structure");
80*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
81*2d543d20SAndroid Build Coastguard Worker }
82*2d543d20SAndroid Build Coastguard Worker
node_to_record(sepol_handle_t * handle,const policydb_t * policydb,ocontext_t * node,int proto,sepol_node_t ** record)83*2d543d20SAndroid Build Coastguard Worker static int node_to_record(sepol_handle_t * handle,
84*2d543d20SAndroid Build Coastguard Worker const policydb_t * policydb,
85*2d543d20SAndroid Build Coastguard Worker ocontext_t * node, int proto, sepol_node_t ** record)
86*2d543d20SAndroid Build Coastguard Worker {
87*2d543d20SAndroid Build Coastguard Worker
88*2d543d20SAndroid Build Coastguard Worker context_struct_t *con = &node->context[0];
89*2d543d20SAndroid Build Coastguard Worker
90*2d543d20SAndroid Build Coastguard Worker sepol_context_t *tmp_con = NULL;
91*2d543d20SAndroid Build Coastguard Worker sepol_node_t *tmp_record = NULL;
92*2d543d20SAndroid Build Coastguard Worker
93*2d543d20SAndroid Build Coastguard Worker if (sepol_node_create(handle, &tmp_record) < 0)
94*2d543d20SAndroid Build Coastguard Worker goto err;
95*2d543d20SAndroid Build Coastguard Worker
96*2d543d20SAndroid Build Coastguard Worker sepol_node_set_proto(tmp_record, proto);
97*2d543d20SAndroid Build Coastguard Worker
98*2d543d20SAndroid Build Coastguard Worker switch (proto) {
99*2d543d20SAndroid Build Coastguard Worker
100*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_IP4:
101*2d543d20SAndroid Build Coastguard Worker if (sepol_node_set_addr_bytes(handle, tmp_record,
102*2d543d20SAndroid Build Coastguard Worker (const char *)&node->u.node.addr,
103*2d543d20SAndroid Build Coastguard Worker 4) < 0)
104*2d543d20SAndroid Build Coastguard Worker goto err;
105*2d543d20SAndroid Build Coastguard Worker
106*2d543d20SAndroid Build Coastguard Worker if (sepol_node_set_mask_bytes(handle, tmp_record,
107*2d543d20SAndroid Build Coastguard Worker (const char *)&node->u.node.mask,
108*2d543d20SAndroid Build Coastguard Worker 4) < 0)
109*2d543d20SAndroid Build Coastguard Worker goto err;
110*2d543d20SAndroid Build Coastguard Worker break;
111*2d543d20SAndroid Build Coastguard Worker
112*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_IP6:
113*2d543d20SAndroid Build Coastguard Worker if (sepol_node_set_addr_bytes(handle, tmp_record,
114*2d543d20SAndroid Build Coastguard Worker (const char *)&node->u.node6.addr,
115*2d543d20SAndroid Build Coastguard Worker 16) < 0)
116*2d543d20SAndroid Build Coastguard Worker goto err;
117*2d543d20SAndroid Build Coastguard Worker
118*2d543d20SAndroid Build Coastguard Worker if (sepol_node_set_mask_bytes(handle, tmp_record,
119*2d543d20SAndroid Build Coastguard Worker (const char *)&node->u.node6.mask,
120*2d543d20SAndroid Build Coastguard Worker 16) < 0)
121*2d543d20SAndroid Build Coastguard Worker goto err;
122*2d543d20SAndroid Build Coastguard Worker break;
123*2d543d20SAndroid Build Coastguard Worker
124*2d543d20SAndroid Build Coastguard Worker default:
125*2d543d20SAndroid Build Coastguard Worker ERR(handle, "unsupported protocol %u", proto);
126*2d543d20SAndroid Build Coastguard Worker goto err;
127*2d543d20SAndroid Build Coastguard Worker }
128*2d543d20SAndroid Build Coastguard Worker
129*2d543d20SAndroid Build Coastguard Worker if (context_to_record(handle, policydb, con, &tmp_con) < 0)
130*2d543d20SAndroid Build Coastguard Worker goto err;
131*2d543d20SAndroid Build Coastguard Worker
132*2d543d20SAndroid Build Coastguard Worker if (sepol_node_set_con(handle, tmp_record, tmp_con) < 0)
133*2d543d20SAndroid Build Coastguard Worker goto err;
134*2d543d20SAndroid Build Coastguard Worker
135*2d543d20SAndroid Build Coastguard Worker sepol_context_free(tmp_con);
136*2d543d20SAndroid Build Coastguard Worker *record = tmp_record;
137*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
138*2d543d20SAndroid Build Coastguard Worker
139*2d543d20SAndroid Build Coastguard Worker err:
140*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not convert node to record");
141*2d543d20SAndroid Build Coastguard Worker sepol_context_free(tmp_con);
142*2d543d20SAndroid Build Coastguard Worker sepol_node_free(tmp_record);
143*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
144*2d543d20SAndroid Build Coastguard Worker }
145*2d543d20SAndroid Build Coastguard Worker
146*2d543d20SAndroid Build Coastguard Worker /* Return the number of nodes */
sepol_node_count(sepol_handle_t * handle,const sepol_policydb_t * p,unsigned int * response)147*2d543d20SAndroid Build Coastguard Worker extern int sepol_node_count(sepol_handle_t * handle __attribute__ ((unused)),
148*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t * p, unsigned int *response)
149*2d543d20SAndroid Build Coastguard Worker {
150*2d543d20SAndroid Build Coastguard Worker
151*2d543d20SAndroid Build Coastguard Worker unsigned int count = 0;
152*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
153*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
154*2d543d20SAndroid Build Coastguard Worker
155*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_NODE];
156*2d543d20SAndroid Build Coastguard Worker for (c = head; c != NULL; c = c->next)
157*2d543d20SAndroid Build Coastguard Worker count++;
158*2d543d20SAndroid Build Coastguard Worker
159*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_NODE6];
160*2d543d20SAndroid Build Coastguard Worker for (c = head; c != NULL; c = c->next)
161*2d543d20SAndroid Build Coastguard Worker count++;
162*2d543d20SAndroid Build Coastguard Worker
163*2d543d20SAndroid Build Coastguard Worker *response = count;
164*2d543d20SAndroid Build Coastguard Worker
165*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
166*2d543d20SAndroid Build Coastguard Worker }
167*2d543d20SAndroid Build Coastguard Worker
168*2d543d20SAndroid Build Coastguard Worker /* Check if a node exists */
sepol_node_exists(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_node_key_t * key,int * response)169*2d543d20SAndroid Build Coastguard Worker int sepol_node_exists(sepol_handle_t * handle,
170*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t * p,
171*2d543d20SAndroid Build Coastguard Worker const sepol_node_key_t * key, int *response)
172*2d543d20SAndroid Build Coastguard Worker {
173*2d543d20SAndroid Build Coastguard Worker
174*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
175*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
176*2d543d20SAndroid Build Coastguard Worker
177*2d543d20SAndroid Build Coastguard Worker int proto;
178*2d543d20SAndroid Build Coastguard Worker const char *addr, *mask;
179*2d543d20SAndroid Build Coastguard Worker sepol_node_key_unpack(key, &addr, &mask, &proto);
180*2d543d20SAndroid Build Coastguard Worker
181*2d543d20SAndroid Build Coastguard Worker switch (proto) {
182*2d543d20SAndroid Build Coastguard Worker
183*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_IP4:
184*2d543d20SAndroid Build Coastguard Worker {
185*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_NODE];
186*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
187*2d543d20SAndroid Build Coastguard Worker unsigned int *addr2 = &c->u.node.addr;
188*2d543d20SAndroid Build Coastguard Worker unsigned int *mask2 = &c->u.node.mask;
189*2d543d20SAndroid Build Coastguard Worker
190*2d543d20SAndroid Build Coastguard Worker if (!memcmp(addr, addr2, 4) &&
191*2d543d20SAndroid Build Coastguard Worker !memcmp(mask, mask2, 4)) {
192*2d543d20SAndroid Build Coastguard Worker
193*2d543d20SAndroid Build Coastguard Worker *response = 1;
194*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
195*2d543d20SAndroid Build Coastguard Worker }
196*2d543d20SAndroid Build Coastguard Worker }
197*2d543d20SAndroid Build Coastguard Worker break;
198*2d543d20SAndroid Build Coastguard Worker }
199*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_IP6:
200*2d543d20SAndroid Build Coastguard Worker {
201*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_NODE6];
202*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
203*2d543d20SAndroid Build Coastguard Worker unsigned int *addr2 = c->u.node6.addr;
204*2d543d20SAndroid Build Coastguard Worker unsigned int *mask2 = c->u.node6.mask;
205*2d543d20SAndroid Build Coastguard Worker
206*2d543d20SAndroid Build Coastguard Worker if (!memcmp(addr, addr2, 16) &&
207*2d543d20SAndroid Build Coastguard Worker !memcmp(mask, mask2, 16)) {
208*2d543d20SAndroid Build Coastguard Worker *response = 1;
209*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
210*2d543d20SAndroid Build Coastguard Worker }
211*2d543d20SAndroid Build Coastguard Worker }
212*2d543d20SAndroid Build Coastguard Worker break;
213*2d543d20SAndroid Build Coastguard Worker }
214*2d543d20SAndroid Build Coastguard Worker default:
215*2d543d20SAndroid Build Coastguard Worker ERR(handle, "unsupported protocol %u", proto);
216*2d543d20SAndroid Build Coastguard Worker goto err;
217*2d543d20SAndroid Build Coastguard Worker }
218*2d543d20SAndroid Build Coastguard Worker
219*2d543d20SAndroid Build Coastguard Worker *response = 0;
220*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
221*2d543d20SAndroid Build Coastguard Worker
222*2d543d20SAndroid Build Coastguard Worker err:
223*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not check if node %s/%s (%s) exists",
224*2d543d20SAndroid Build Coastguard Worker addr, mask, sepol_node_get_proto_str(proto));
225*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
226*2d543d20SAndroid Build Coastguard Worker }
227*2d543d20SAndroid Build Coastguard Worker
228*2d543d20SAndroid Build Coastguard Worker /* Query a node */
sepol_node_query(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_node_key_t * key,sepol_node_t ** response)229*2d543d20SAndroid Build Coastguard Worker int sepol_node_query(sepol_handle_t * handle,
230*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t * p,
231*2d543d20SAndroid Build Coastguard Worker const sepol_node_key_t * key, sepol_node_t ** response)
232*2d543d20SAndroid Build Coastguard Worker {
233*2d543d20SAndroid Build Coastguard Worker
234*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
235*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
236*2d543d20SAndroid Build Coastguard Worker
237*2d543d20SAndroid Build Coastguard Worker int proto;
238*2d543d20SAndroid Build Coastguard Worker const char *addr, *mask;
239*2d543d20SAndroid Build Coastguard Worker sepol_node_key_unpack(key, &addr, &mask, &proto);
240*2d543d20SAndroid Build Coastguard Worker
241*2d543d20SAndroid Build Coastguard Worker switch (proto) {
242*2d543d20SAndroid Build Coastguard Worker
243*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_IP4:
244*2d543d20SAndroid Build Coastguard Worker {
245*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_NODE];
246*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
247*2d543d20SAndroid Build Coastguard Worker unsigned int *addr2 = &c->u.node.addr;
248*2d543d20SAndroid Build Coastguard Worker unsigned int *mask2 = &c->u.node.mask;
249*2d543d20SAndroid Build Coastguard Worker
250*2d543d20SAndroid Build Coastguard Worker if (!memcmp(addr, addr2, 4) &&
251*2d543d20SAndroid Build Coastguard Worker !memcmp(mask, mask2, 4)) {
252*2d543d20SAndroid Build Coastguard Worker
253*2d543d20SAndroid Build Coastguard Worker if (node_to_record(handle, policydb,
254*2d543d20SAndroid Build Coastguard Worker c, SEPOL_PROTO_IP4,
255*2d543d20SAndroid Build Coastguard Worker response) < 0)
256*2d543d20SAndroid Build Coastguard Worker goto err;
257*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
258*2d543d20SAndroid Build Coastguard Worker }
259*2d543d20SAndroid Build Coastguard Worker }
260*2d543d20SAndroid Build Coastguard Worker break;
261*2d543d20SAndroid Build Coastguard Worker }
262*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_IP6:
263*2d543d20SAndroid Build Coastguard Worker {
264*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_NODE6];
265*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
266*2d543d20SAndroid Build Coastguard Worker unsigned int *addr2 = c->u.node6.addr;
267*2d543d20SAndroid Build Coastguard Worker unsigned int *mask2 = c->u.node6.mask;
268*2d543d20SAndroid Build Coastguard Worker
269*2d543d20SAndroid Build Coastguard Worker if (!memcmp(addr, addr2, 16) &&
270*2d543d20SAndroid Build Coastguard Worker !memcmp(mask, mask2, 16)) {
271*2d543d20SAndroid Build Coastguard Worker
272*2d543d20SAndroid Build Coastguard Worker if (node_to_record(handle, policydb,
273*2d543d20SAndroid Build Coastguard Worker c, SEPOL_PROTO_IP6,
274*2d543d20SAndroid Build Coastguard Worker response) < 0)
275*2d543d20SAndroid Build Coastguard Worker goto err;
276*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
277*2d543d20SAndroid Build Coastguard Worker }
278*2d543d20SAndroid Build Coastguard Worker }
279*2d543d20SAndroid Build Coastguard Worker break;
280*2d543d20SAndroid Build Coastguard Worker }
281*2d543d20SAndroid Build Coastguard Worker default:
282*2d543d20SAndroid Build Coastguard Worker ERR(handle, "unsupported protocol %u", proto);
283*2d543d20SAndroid Build Coastguard Worker goto err;
284*2d543d20SAndroid Build Coastguard Worker }
285*2d543d20SAndroid Build Coastguard Worker *response = NULL;
286*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
287*2d543d20SAndroid Build Coastguard Worker
288*2d543d20SAndroid Build Coastguard Worker err:
289*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not query node %s/%s (%s)",
290*2d543d20SAndroid Build Coastguard Worker addr, mask, sepol_node_get_proto_str(proto));
291*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
292*2d543d20SAndroid Build Coastguard Worker
293*2d543d20SAndroid Build Coastguard Worker }
294*2d543d20SAndroid Build Coastguard Worker
295*2d543d20SAndroid Build Coastguard Worker /* Load a node into policy */
sepol_node_modify(sepol_handle_t * handle,sepol_policydb_t * p,const sepol_node_key_t * key,const sepol_node_t * data)296*2d543d20SAndroid Build Coastguard Worker int sepol_node_modify(sepol_handle_t * handle,
297*2d543d20SAndroid Build Coastguard Worker sepol_policydb_t * p,
298*2d543d20SAndroid Build Coastguard Worker const sepol_node_key_t * key, const sepol_node_t * data)
299*2d543d20SAndroid Build Coastguard Worker {
300*2d543d20SAndroid Build Coastguard Worker
301*2d543d20SAndroid Build Coastguard Worker policydb_t *policydb = &p->p;
302*2d543d20SAndroid Build Coastguard Worker ocontext_t *node = NULL;
303*2d543d20SAndroid Build Coastguard Worker
304*2d543d20SAndroid Build Coastguard Worker int proto;
305*2d543d20SAndroid Build Coastguard Worker const char *addr, *mask;
306*2d543d20SAndroid Build Coastguard Worker
307*2d543d20SAndroid Build Coastguard Worker sepol_node_key_unpack(key, &addr, &mask, &proto);
308*2d543d20SAndroid Build Coastguard Worker
309*2d543d20SAndroid Build Coastguard Worker if (node_from_record(handle, policydb, &node, data) < 0)
310*2d543d20SAndroid Build Coastguard Worker goto err;
311*2d543d20SAndroid Build Coastguard Worker
312*2d543d20SAndroid Build Coastguard Worker switch (proto) {
313*2d543d20SAndroid Build Coastguard Worker
314*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_IP4:
315*2d543d20SAndroid Build Coastguard Worker {
316*2d543d20SAndroid Build Coastguard Worker /* Attach to context list */
317*2d543d20SAndroid Build Coastguard Worker node->next = policydb->ocontexts[OCON_NODE];
318*2d543d20SAndroid Build Coastguard Worker policydb->ocontexts[OCON_NODE] = node;
319*2d543d20SAndroid Build Coastguard Worker break;
320*2d543d20SAndroid Build Coastguard Worker }
321*2d543d20SAndroid Build Coastguard Worker case SEPOL_PROTO_IP6:
322*2d543d20SAndroid Build Coastguard Worker {
323*2d543d20SAndroid Build Coastguard Worker /* Attach to context list */
324*2d543d20SAndroid Build Coastguard Worker node->next = policydb->ocontexts[OCON_NODE6];
325*2d543d20SAndroid Build Coastguard Worker policydb->ocontexts[OCON_NODE6] = node;
326*2d543d20SAndroid Build Coastguard Worker break;
327*2d543d20SAndroid Build Coastguard Worker }
328*2d543d20SAndroid Build Coastguard Worker default:
329*2d543d20SAndroid Build Coastguard Worker ERR(handle, "unsupported protocol %u", proto);
330*2d543d20SAndroid Build Coastguard Worker goto err;
331*2d543d20SAndroid Build Coastguard Worker }
332*2d543d20SAndroid Build Coastguard Worker
333*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
334*2d543d20SAndroid Build Coastguard Worker
335*2d543d20SAndroid Build Coastguard Worker err:
336*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not load node %s/%s (%s)",
337*2d543d20SAndroid Build Coastguard Worker addr, mask, sepol_node_get_proto_str(proto));
338*2d543d20SAndroid Build Coastguard Worker if (node != NULL) {
339*2d543d20SAndroid Build Coastguard Worker context_destroy(&node->context[0]);
340*2d543d20SAndroid Build Coastguard Worker free(node);
341*2d543d20SAndroid Build Coastguard Worker }
342*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
343*2d543d20SAndroid Build Coastguard Worker }
344*2d543d20SAndroid Build Coastguard Worker
sepol_node_iterate(sepol_handle_t * handle,const sepol_policydb_t * p,int (* fn)(const sepol_node_t * node,void * fn_arg),void * arg)345*2d543d20SAndroid Build Coastguard Worker int sepol_node_iterate(sepol_handle_t * handle,
346*2d543d20SAndroid Build Coastguard Worker const sepol_policydb_t * p,
347*2d543d20SAndroid Build Coastguard Worker int (*fn) (const sepol_node_t * node,
348*2d543d20SAndroid Build Coastguard Worker void *fn_arg), void *arg)
349*2d543d20SAndroid Build Coastguard Worker {
350*2d543d20SAndroid Build Coastguard Worker
351*2d543d20SAndroid Build Coastguard Worker const policydb_t *policydb = &p->p;
352*2d543d20SAndroid Build Coastguard Worker ocontext_t *c, *head;
353*2d543d20SAndroid Build Coastguard Worker sepol_node_t *node = NULL;
354*2d543d20SAndroid Build Coastguard Worker int status;
355*2d543d20SAndroid Build Coastguard Worker
356*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_NODE];
357*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
358*2d543d20SAndroid Build Coastguard Worker if (node_to_record(handle, policydb, c, SEPOL_PROTO_IP4, &node)
359*2d543d20SAndroid Build Coastguard Worker < 0)
360*2d543d20SAndroid Build Coastguard Worker goto err;
361*2d543d20SAndroid Build Coastguard Worker
362*2d543d20SAndroid Build Coastguard Worker /* Invoke handler */
363*2d543d20SAndroid Build Coastguard Worker status = fn(node, arg);
364*2d543d20SAndroid Build Coastguard Worker if (status < 0)
365*2d543d20SAndroid Build Coastguard Worker goto err;
366*2d543d20SAndroid Build Coastguard Worker
367*2d543d20SAndroid Build Coastguard Worker sepol_node_free(node);
368*2d543d20SAndroid Build Coastguard Worker node = NULL;
369*2d543d20SAndroid Build Coastguard Worker
370*2d543d20SAndroid Build Coastguard Worker /* Handler requested exit */
371*2d543d20SAndroid Build Coastguard Worker if (status > 0)
372*2d543d20SAndroid Build Coastguard Worker break;
373*2d543d20SAndroid Build Coastguard Worker }
374*2d543d20SAndroid Build Coastguard Worker
375*2d543d20SAndroid Build Coastguard Worker head = policydb->ocontexts[OCON_NODE6];
376*2d543d20SAndroid Build Coastguard Worker for (c = head; c; c = c->next) {
377*2d543d20SAndroid Build Coastguard Worker if (node_to_record(handle, policydb, c, SEPOL_PROTO_IP6, &node)
378*2d543d20SAndroid Build Coastguard Worker < 0)
379*2d543d20SAndroid Build Coastguard Worker goto err;
380*2d543d20SAndroid Build Coastguard Worker
381*2d543d20SAndroid Build Coastguard Worker /* Invoke handler */
382*2d543d20SAndroid Build Coastguard Worker status = fn(node, arg);
383*2d543d20SAndroid Build Coastguard Worker if (status < 0)
384*2d543d20SAndroid Build Coastguard Worker goto err;
385*2d543d20SAndroid Build Coastguard Worker
386*2d543d20SAndroid Build Coastguard Worker sepol_node_free(node);
387*2d543d20SAndroid Build Coastguard Worker node = NULL;
388*2d543d20SAndroid Build Coastguard Worker
389*2d543d20SAndroid Build Coastguard Worker /* Handler requested exit */
390*2d543d20SAndroid Build Coastguard Worker if (status > 0)
391*2d543d20SAndroid Build Coastguard Worker break;
392*2d543d20SAndroid Build Coastguard Worker }
393*2d543d20SAndroid Build Coastguard Worker
394*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
395*2d543d20SAndroid Build Coastguard Worker
396*2d543d20SAndroid Build Coastguard Worker err:
397*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not iterate over nodes");
398*2d543d20SAndroid Build Coastguard Worker sepol_node_free(node);
399*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
400*2d543d20SAndroid Build Coastguard Worker }
401