1 #include <netinet/in.h>
2 #include <stdlib.h>
3
4 #include "debug.h"
5 #include "context.h"
6 #include "handle.h"
7
8 #include <sepol/policydb/policydb.h>
9 #include "ibendport_internal.h"
10
11 /* Create a low level ibendport structure from
12 * a high level representation
13 */
ibendport_from_record(sepol_handle_t * handle,const policydb_t * policydb,ocontext_t ** ibendport,const sepol_ibendport_t * data)14 static int ibendport_from_record(sepol_handle_t *handle,
15 const policydb_t *policydb,
16 ocontext_t **ibendport,
17 const sepol_ibendport_t *data)
18 {
19 ocontext_t *tmp_ibendport = NULL;
20 context_struct_t *tmp_con = NULL;
21 char *ibdev_name = NULL;
22 int port = sepol_ibendport_get_port(data);
23
24 tmp_ibendport = (ocontext_t *)calloc(1, sizeof(ocontext_t));
25 if (!tmp_ibendport)
26 goto omem;
27
28 if (sepol_ibendport_alloc_ibdev_name(handle,
29 &tmp_ibendport->u.ibendport.dev_name) < 0)
30 goto omem;
31
32 if (sepol_ibendport_get_ibdev_name(handle,
33 data,
34 &ibdev_name) < 0)
35 goto err;
36
37 strncpy(tmp_ibendport->u.ibendport.dev_name, ibdev_name, IB_DEVICE_NAME_MAX);
38
39 free(ibdev_name);
40 ibdev_name = NULL;
41
42 tmp_ibendport->u.ibendport.port = port;
43
44 /* Context */
45 if (context_from_record(handle, policydb, &tmp_con,
46 sepol_ibendport_get_con(data)) < 0)
47 goto err;
48 context_cpy(&tmp_ibendport->context[0], tmp_con);
49 context_destroy(tmp_con);
50 free(tmp_con);
51 tmp_con = NULL;
52
53 *ibendport = tmp_ibendport;
54 return STATUS_SUCCESS;
55
56 omem:
57 ERR(handle, "out of memory");
58
59 err:
60 if (tmp_ibendport) {
61 context_destroy(&tmp_ibendport->context[0]);
62 free(tmp_ibendport);
63 }
64 context_destroy(tmp_con);
65 free(tmp_con);
66 free(ibdev_name);
67 ERR(handle, "could not create ibendport structure");
68 return STATUS_ERR;
69 }
70
ibendport_to_record(sepol_handle_t * handle,const policydb_t * policydb,ocontext_t * ibendport,sepol_ibendport_t ** record)71 static int ibendport_to_record(sepol_handle_t *handle,
72 const policydb_t *policydb,
73 ocontext_t *ibendport,
74 sepol_ibendport_t **record)
75 {
76 int port = ibendport->u.ibendport.port;
77 context_struct_t *con = &ibendport->context[0];
78
79 sepol_context_t *tmp_con = NULL;
80 sepol_ibendport_t *tmp_record = NULL;
81
82 if (sepol_ibendport_create(handle, &tmp_record) < 0)
83 goto err;
84
85 if (sepol_ibendport_set_ibdev_name(handle, tmp_record,
86 ibendport->u.ibendport.dev_name) < 0)
87 goto err;
88
89 sepol_ibendport_set_port(tmp_record, port);
90
91 if (context_to_record(handle, policydb, con, &tmp_con) < 0)
92 goto err;
93
94 if (sepol_ibendport_set_con(handle, tmp_record, tmp_con) < 0)
95 goto err;
96
97 sepol_context_free(tmp_con);
98 *record = tmp_record;
99 return STATUS_SUCCESS;
100
101 err:
102 ERR(handle, "could not convert ibendport to record");
103 sepol_context_free(tmp_con);
104 sepol_ibendport_free(tmp_record);
105 return STATUS_ERR;
106 }
107
108 /* Return the number of ibendports */
sepol_ibendport_count(sepol_handle_t * handle,const sepol_policydb_t * p,unsigned int * response)109 extern int sepol_ibendport_count(sepol_handle_t *handle __attribute__ ((unused)),
110 const sepol_policydb_t *p, unsigned int *response)
111 {
112 unsigned int count = 0;
113 ocontext_t *c, *head;
114 const policydb_t *policydb = &p->p;
115
116 head = policydb->ocontexts[OCON_IBENDPORT];
117 for (c = head; c; c = c->next)
118 count++;
119
120 *response = count;
121
122 return STATUS_SUCCESS;
123 }
124
125 /* Check if a ibendport exists */
sepol_ibendport_exists(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_ibendport_key_t * key,int * response)126 int sepol_ibendport_exists(sepol_handle_t *handle __attribute__ ((unused)),
127 const sepol_policydb_t *p,
128 const sepol_ibendport_key_t *key, int *response)
129 {
130 const policydb_t *policydb = &p->p;
131 ocontext_t *c, *head;
132 int port;
133 const char *ibdev_name;
134
135 sepol_ibendport_key_unpack(key, &ibdev_name, &port);
136
137 head = policydb->ocontexts[OCON_IBENDPORT];
138 for (c = head; c; c = c->next) {
139 const char *ibdev_name2 = c->u.ibendport.dev_name;
140 int port2 = c->u.ibendport.port;
141
142 if (port2 == port &&
143 (!strcmp(ibdev_name, ibdev_name2))) {
144 *response = 1;
145 return STATUS_SUCCESS;
146 }
147 }
148
149 *response = 0;
150 return STATUS_SUCCESS;
151 }
152
sepol_ibendport_query(sepol_handle_t * handle,const sepol_policydb_t * p,const sepol_ibendport_key_t * key,sepol_ibendport_t ** response)153 int sepol_ibendport_query(sepol_handle_t *handle,
154 const sepol_policydb_t *p,
155 const sepol_ibendport_key_t *key,
156 sepol_ibendport_t **response)
157 {
158 const policydb_t *policydb = &p->p;
159 ocontext_t *c, *head;
160 int port;
161 const char *ibdev_name;
162
163 sepol_ibendport_key_unpack(key, &ibdev_name, &port);
164
165 head = policydb->ocontexts[OCON_IBENDPORT];
166 for (c = head; c; c = c->next) {
167 const char *ibdev_name2 = c->u.ibendport.dev_name;
168 int port2 = c->u.ibendport.port;
169
170 if (port2 == port &&
171 (!strcmp(ibdev_name, ibdev_name2))) {
172 if (ibendport_to_record(handle, policydb, c, response) < 0)
173 goto err;
174 return STATUS_SUCCESS;
175 }
176 }
177
178 *response = NULL;
179 return STATUS_SUCCESS;
180
181 err:
182 ERR(handle, "could not query ibendport, IB device: %s port %u",
183 ibdev_name, port);
184 return STATUS_ERR;
185 }
186
187 /* Load a ibendport into policy */
sepol_ibendport_modify(sepol_handle_t * handle,sepol_policydb_t * p,const sepol_ibendport_key_t * key,const sepol_ibendport_t * data)188 int sepol_ibendport_modify(sepol_handle_t *handle,
189 sepol_policydb_t *p,
190 const sepol_ibendport_key_t *key,
191 const sepol_ibendport_t *data)
192 {
193 policydb_t *policydb = &p->p;
194 ocontext_t *ibendport = NULL;
195 int port;
196 const char *ibdev_name;
197
198 sepol_ibendport_key_unpack(key, &ibdev_name, &port);
199
200 if (ibendport_from_record(handle, policydb, &ibendport, data) < 0)
201 goto err;
202
203 /* Attach to context list */
204 ibendport->next = policydb->ocontexts[OCON_IBENDPORT];
205 policydb->ocontexts[OCON_IBENDPORT] = ibendport;
206
207 return STATUS_SUCCESS;
208
209 err:
210 ERR(handle, "could not load ibendport %s/%d",
211 ibdev_name, port);
212 if (ibendport) {
213 context_destroy(&ibendport->context[0]);
214 free(ibendport);
215 }
216 return STATUS_ERR;
217 }
218
sepol_ibendport_iterate(sepol_handle_t * handle,const sepol_policydb_t * p,int (* fn)(const sepol_ibendport_t * ibendport,void * fn_arg),void * arg)219 int sepol_ibendport_iterate(sepol_handle_t *handle,
220 const sepol_policydb_t *p,
221 int (*fn)(const sepol_ibendport_t *ibendport,
222 void *fn_arg), void *arg)
223 {
224 const policydb_t *policydb = &p->p;
225 ocontext_t *c, *head;
226 sepol_ibendport_t *ibendport = NULL;
227
228 head = policydb->ocontexts[OCON_IBENDPORT];
229 for (c = head; c; c = c->next) {
230 int status;
231
232 if (ibendport_to_record(handle, policydb, c, &ibendport) < 0)
233 goto err;
234
235 /* Invoke handler */
236 status = fn(ibendport, arg);
237 if (status < 0)
238 goto err;
239
240 sepol_ibendport_free(ibendport);
241 ibendport = NULL;
242
243 /* Handler requested exit */
244 if (status > 0)
245 break;
246 }
247
248 return STATUS_SUCCESS;
249
250 err:
251 ERR(handle, "could not iterate over ibendports");
252 sepol_ibendport_free(ibendport);
253 return STATUS_ERR;
254 }
255