1 #include <stdlib.h>
2 #include <string.h>
3 #include <netinet/in.h>
4 #include <arpa/inet.h>
5 #include <errno.h>
6
7 #include "sepol/policydb/policydb.h"
8 #include "ibendport_internal.h"
9 #include "context_internal.h"
10 #include "debug.h"
11
12 struct sepol_ibendport {
13 /* Device Name */
14 char *ibdev_name;
15
16 /* Port number */
17 int port;
18
19 /* Context */
20 sepol_context_t *con;
21 };
22
23 struct sepol_ibendport_key {
24 /* Device Name */
25 char *ibdev_name;
26
27 /* Port number */
28 int port;
29 };
30
31 /* Allocates a sufficiently large string (ibdev_name) */
sepol_ibendport_alloc_ibdev_name(sepol_handle_t * handle,char ** ibdev_name)32 int sepol_ibendport_alloc_ibdev_name(sepol_handle_t *handle,
33 char **ibdev_name)
34 {
35 *ibdev_name = calloc(1, IB_DEVICE_NAME_MAX);
36
37 if (!*ibdev_name)
38 goto omem;
39
40 return STATUS_SUCCESS;
41
42 omem:
43 ERR(handle, "out of memory");
44 ERR(handle, "could not allocate string buffer for ibdev_name");
45 return STATUS_ERR;
46 }
47
48 /* Key */
sepol_ibendport_key_create(sepol_handle_t * handle,const char * ibdev_name,int port,sepol_ibendport_key_t ** key_ptr)49 int sepol_ibendport_key_create(sepol_handle_t *handle,
50 const char *ibdev_name,
51 int port,
52 sepol_ibendport_key_t **key_ptr)
53 {
54 sepol_ibendport_key_t *tmp_key =
55 (sepol_ibendport_key_t *)malloc(sizeof(sepol_ibendport_key_t));
56
57 if (!tmp_key) {
58 ERR(handle, "out of memory, could not create ibendport key");
59 goto omem;
60 }
61
62 if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_key->ibdev_name) < 0)
63 goto err;
64
65 strncpy(tmp_key->ibdev_name, ibdev_name, IB_DEVICE_NAME_MAX);
66 tmp_key->port = port;
67
68 *key_ptr = tmp_key;
69 return STATUS_SUCCESS;
70
71 omem:
72 ERR(handle, "out of memory");
73
74 err:
75 sepol_ibendport_key_free(tmp_key);
76 ERR(handle, "could not create ibendport key for IB device %s, port %u",
77 ibdev_name, port);
78 return STATUS_ERR;
79 }
80
hidden_def(sepol_ibendport_key_create)81 hidden_def(sepol_ibendport_key_create)
82
83 void sepol_ibendport_key_unpack(const sepol_ibendport_key_t *key,
84 const char **ibdev_name, int *port)
85 {
86 *ibdev_name = key->ibdev_name;
87 *port = key->port;
88 }
89
hidden_def(sepol_ibendport_key_unpack)90 hidden_def(sepol_ibendport_key_unpack)
91
92 int sepol_ibendport_key_extract(sepol_handle_t *handle,
93 const sepol_ibendport_t *ibendport,
94 sepol_ibendport_key_t **key_ptr)
95 {
96 if (sepol_ibendport_key_create
97 (handle, ibendport->ibdev_name, ibendport->port, key_ptr) < 0) {
98 ERR(handle, "could not extract key from ibendport device %s port %d",
99 ibendport->ibdev_name,
100 ibendport->port);
101
102 return STATUS_ERR;
103 }
104
105 return STATUS_SUCCESS;
106 }
107
sepol_ibendport_key_free(sepol_ibendport_key_t * key)108 void sepol_ibendport_key_free(sepol_ibendport_key_t *key)
109 {
110 if (!key)
111 return;
112 free(key->ibdev_name);
113 free(key);
114 }
115
sepol_ibendport_compare(const sepol_ibendport_t * ibendport,const sepol_ibendport_key_t * key)116 int sepol_ibendport_compare(const sepol_ibendport_t *ibendport, const sepol_ibendport_key_t *key)
117 {
118 int rc;
119
120 rc = strcmp(ibendport->ibdev_name, key->ibdev_name);
121
122 if ((ibendport->port == key->port) && !rc)
123 return 0;
124
125 if (ibendport->port < key->port)
126 return -1;
127 else if (key->port < ibendport->port)
128 return 1;
129 else
130 return rc;
131 }
132
sepol_ibendport_compare2(const sepol_ibendport_t * ibendport,const sepol_ibendport_t * ibendport2)133 int sepol_ibendport_compare2(const sepol_ibendport_t *ibendport, const sepol_ibendport_t *ibendport2)
134 {
135 int rc;
136
137 rc = strcmp(ibendport->ibdev_name, ibendport2->ibdev_name);
138
139 if ((ibendport->port == ibendport2->port) && !rc)
140 return 0;
141
142 if (ibendport->port < ibendport2->port)
143 return -1;
144 else if (ibendport2->port < ibendport->port)
145 return 1;
146 else
147 return rc;
148 }
149
sepol_ibendport_get_port(const sepol_ibendport_t * ibendport)150 int sepol_ibendport_get_port(const sepol_ibendport_t *ibendport)
151 {
152 return ibendport->port;
153 }
154
hidden_def(sepol_ibendport_get_port)155 hidden_def(sepol_ibendport_get_port)
156
157 void sepol_ibendport_set_port(sepol_ibendport_t *ibendport, int port)
158 {
159 ibendport->port = port;
160 }
161
hidden_def(sepol_ibendport_set_port)162 hidden_def(sepol_ibendport_set_port)
163
164 int sepol_ibendport_get_ibdev_name(sepol_handle_t *handle,
165 const sepol_ibendport_t *ibendport,
166 char **ibdev_name)
167 {
168 char *tmp_ibdev_name = NULL;
169
170 if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_ibdev_name) < 0)
171 goto err;
172
173 strncpy(tmp_ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX);
174 *ibdev_name = tmp_ibdev_name;
175 return STATUS_SUCCESS;
176
177 err:
178 free(tmp_ibdev_name);
179 ERR(handle, "could not get ibendport ibdev_name");
180 return STATUS_ERR;
181 }
182
hidden_def(sepol_ibendport_get_ibdev_name)183 hidden_def(sepol_ibendport_get_ibdev_name)
184
185 int sepol_ibendport_set_ibdev_name(sepol_handle_t *handle,
186 sepol_ibendport_t *ibendport,
187 const char *ibdev_name)
188 {
189 char *tmp = NULL;
190
191 if (sepol_ibendport_alloc_ibdev_name(handle, &tmp) < 0)
192 goto err;
193
194 strncpy(tmp, ibdev_name, IB_DEVICE_NAME_MAX);
195 free(ibendport->ibdev_name);
196 ibendport->ibdev_name = tmp;
197 return STATUS_SUCCESS;
198
199 err:
200 free(tmp);
201 ERR(handle, "could not set ibendport subnet prefix to %s", ibdev_name);
202 return STATUS_ERR;
203 }
204
hidden_def(sepol_ibendport_set_ibdev_name)205 hidden_def(sepol_ibendport_set_ibdev_name)
206
207 /* Create */
208 int sepol_ibendport_create(sepol_handle_t *handle, sepol_ibendport_t **ibendport)
209 {
210 sepol_ibendport_t *tmp_ibendport = (sepol_ibendport_t *)malloc(sizeof(sepol_ibendport_t));
211
212 if (!tmp_ibendport) {
213 ERR(handle, "out of memory, could not create ibendport record");
214 return STATUS_ERR;
215 }
216
217 tmp_ibendport->ibdev_name = NULL;
218 tmp_ibendport->port = 0;
219 tmp_ibendport->con = NULL;
220 *ibendport = tmp_ibendport;
221
222 return STATUS_SUCCESS;
223 }
224
hidden_def(sepol_ibendport_create)225 hidden_def(sepol_ibendport_create)
226
227 /* Deep copy clone */
228 int sepol_ibendport_clone(sepol_handle_t *handle,
229 const sepol_ibendport_t *ibendport,
230 sepol_ibendport_t **ibendport_ptr)
231 {
232 sepol_ibendport_t *new_ibendport = NULL;
233
234 if (sepol_ibendport_create(handle, &new_ibendport) < 0)
235 goto err;
236
237 if (sepol_ibendport_alloc_ibdev_name(handle, &new_ibendport->ibdev_name) < 0)
238 goto omem;
239
240 strncpy(new_ibendport->ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX);
241 new_ibendport->port = ibendport->port;
242
243 if (ibendport->con &&
244 (sepol_context_clone(handle, ibendport->con, &new_ibendport->con) < 0))
245 goto err;
246
247 *ibendport_ptr = new_ibendport;
248 return STATUS_SUCCESS;
249
250 omem:
251 ERR(handle, "out of memory");
252
253 err:
254 ERR(handle, "could not clone ibendport record");
255 sepol_ibendport_free(new_ibendport);
256 return STATUS_ERR;
257 }
258
259 /* Destroy */
sepol_ibendport_free(sepol_ibendport_t * ibendport)260 void sepol_ibendport_free(sepol_ibendport_t *ibendport)
261 {
262 if (!ibendport)
263 return;
264
265 free(ibendport->ibdev_name);
266 sepol_context_free(ibendport->con);
267 free(ibendport);
268 }
269
hidden_def(sepol_ibendport_free)270 hidden_def(sepol_ibendport_free)
271
272 /* Context */
273 sepol_context_t *sepol_ibendport_get_con(const sepol_ibendport_t *ibendport)
274 {
275 return ibendport->con;
276 }
277
hidden_def(sepol_ibendport_get_con)278 hidden_def(sepol_ibendport_get_con)
279
280 int sepol_ibendport_set_con(sepol_handle_t *handle,
281 sepol_ibendport_t *ibendport, sepol_context_t *con)
282 {
283 sepol_context_t *newcon;
284
285 if (sepol_context_clone(handle, con, &newcon) < 0) {
286 ERR(handle, "out of memory, could not set ibendport context");
287 return STATUS_ERR;
288 }
289
290 sepol_context_free(ibendport->con);
291 ibendport->con = newcon;
292 return STATUS_SUCCESS;
293 }
294
295 hidden_def(sepol_ibendport_set_con)
296