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 - 1);
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
81
sepol_ibendport_key_unpack(const sepol_ibendport_key_t * key,const char ** ibdev_name,int * port)82 void sepol_ibendport_key_unpack(const sepol_ibendport_key_t *key,
83 const char **ibdev_name, int *port)
84 {
85 *ibdev_name = key->ibdev_name;
86 *port = key->port;
87 }
88
89
sepol_ibendport_key_extract(sepol_handle_t * handle,const sepol_ibendport_t * ibendport,sepol_ibendport_key_t ** key_ptr)90 int sepol_ibendport_key_extract(sepol_handle_t *handle,
91 const sepol_ibendport_t *ibendport,
92 sepol_ibendport_key_t **key_ptr)
93 {
94 if (sepol_ibendport_key_create
95 (handle, ibendport->ibdev_name, ibendport->port, key_ptr) < 0) {
96 ERR(handle, "could not extract key from ibendport device %s port %d",
97 ibendport->ibdev_name,
98 ibendport->port);
99
100 return STATUS_ERR;
101 }
102
103 return STATUS_SUCCESS;
104 }
105
sepol_ibendport_key_free(sepol_ibendport_key_t * key)106 void sepol_ibendport_key_free(sepol_ibendport_key_t *key)
107 {
108 if (!key)
109 return;
110 free(key->ibdev_name);
111 free(key);
112 }
113
sepol_ibendport_compare(const sepol_ibendport_t * ibendport,const sepol_ibendport_key_t * key)114 int sepol_ibendport_compare(const sepol_ibendport_t *ibendport, const sepol_ibendport_key_t *key)
115 {
116 int rc;
117
118 rc = strcmp(ibendport->ibdev_name, key->ibdev_name);
119
120 if ((ibendport->port == key->port) && !rc)
121 return 0;
122
123 if (ibendport->port < key->port)
124 return -1;
125 else if (key->port < ibendport->port)
126 return 1;
127 else
128 return rc;
129 }
130
sepol_ibendport_compare2(const sepol_ibendport_t * ibendport,const sepol_ibendport_t * ibendport2)131 int sepol_ibendport_compare2(const sepol_ibendport_t *ibendport, const sepol_ibendport_t *ibendport2)
132 {
133 int rc;
134
135 rc = strcmp(ibendport->ibdev_name, ibendport2->ibdev_name);
136
137 if ((ibendport->port == ibendport2->port) && !rc)
138 return 0;
139
140 if (ibendport->port < ibendport2->port)
141 return -1;
142 else if (ibendport2->port < ibendport->port)
143 return 1;
144 else
145 return rc;
146 }
147
sepol_ibendport_get_port(const sepol_ibendport_t * ibendport)148 int sepol_ibendport_get_port(const sepol_ibendport_t *ibendport)
149 {
150 return ibendport->port;
151 }
152
153
sepol_ibendport_set_port(sepol_ibendport_t * ibendport,int port)154 void sepol_ibendport_set_port(sepol_ibendport_t *ibendport, int port)
155 {
156 ibendport->port = port;
157 }
158
159
sepol_ibendport_get_ibdev_name(sepol_handle_t * handle,const sepol_ibendport_t * ibendport,char ** ibdev_name)160 int sepol_ibendport_get_ibdev_name(sepol_handle_t *handle,
161 const sepol_ibendport_t *ibendport,
162 char **ibdev_name)
163 {
164 char *tmp_ibdev_name = NULL;
165
166 if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_ibdev_name) < 0)
167 goto err;
168
169 strncpy(tmp_ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX - 1);
170 *ibdev_name = tmp_ibdev_name;
171 return STATUS_SUCCESS;
172
173 err:
174 free(tmp_ibdev_name);
175 ERR(handle, "could not get ibendport ibdev_name");
176 return STATUS_ERR;
177 }
178
179
sepol_ibendport_set_ibdev_name(sepol_handle_t * handle,sepol_ibendport_t * ibendport,const char * ibdev_name)180 int sepol_ibendport_set_ibdev_name(sepol_handle_t *handle,
181 sepol_ibendport_t *ibendport,
182 const char *ibdev_name)
183 {
184 char *tmp = NULL;
185
186 if (sepol_ibendport_alloc_ibdev_name(handle, &tmp) < 0)
187 goto err;
188
189 strncpy(tmp, ibdev_name, IB_DEVICE_NAME_MAX - 1);
190 free(ibendport->ibdev_name);
191 ibendport->ibdev_name = tmp;
192 return STATUS_SUCCESS;
193
194 err:
195 free(tmp);
196 ERR(handle, "could not set ibendport subnet prefix to %s", ibdev_name);
197 return STATUS_ERR;
198 }
199
200
201 /* Create */
sepol_ibendport_create(sepol_handle_t * handle,sepol_ibendport_t ** ibendport)202 int sepol_ibendport_create(sepol_handle_t *handle, sepol_ibendport_t **ibendport)
203 {
204 sepol_ibendport_t *tmp_ibendport = (sepol_ibendport_t *)malloc(sizeof(sepol_ibendport_t));
205
206 if (!tmp_ibendport) {
207 ERR(handle, "out of memory, could not create ibendport record");
208 return STATUS_ERR;
209 }
210
211 tmp_ibendport->ibdev_name = NULL;
212 tmp_ibendport->port = 0;
213 tmp_ibendport->con = NULL;
214 *ibendport = tmp_ibendport;
215
216 return STATUS_SUCCESS;
217 }
218
219
220 /* Deep copy clone */
sepol_ibendport_clone(sepol_handle_t * handle,const sepol_ibendport_t * ibendport,sepol_ibendport_t ** ibendport_ptr)221 int sepol_ibendport_clone(sepol_handle_t *handle,
222 const sepol_ibendport_t *ibendport,
223 sepol_ibendport_t **ibendport_ptr)
224 {
225 sepol_ibendport_t *new_ibendport = NULL;
226
227 if (sepol_ibendport_create(handle, &new_ibendport) < 0)
228 goto err;
229
230 if (sepol_ibendport_alloc_ibdev_name(handle, &new_ibendport->ibdev_name) < 0)
231 goto omem;
232
233 strncpy(new_ibendport->ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX - 1);
234 new_ibendport->port = ibendport->port;
235
236 if (ibendport->con &&
237 (sepol_context_clone(handle, ibendport->con, &new_ibendport->con) < 0))
238 goto err;
239
240 *ibendport_ptr = new_ibendport;
241 return STATUS_SUCCESS;
242
243 omem:
244 ERR(handle, "out of memory");
245
246 err:
247 ERR(handle, "could not clone ibendport record");
248 sepol_ibendport_free(new_ibendport);
249 return STATUS_ERR;
250 }
251
252 /* Destroy */
sepol_ibendport_free(sepol_ibendport_t * ibendport)253 void sepol_ibendport_free(sepol_ibendport_t *ibendport)
254 {
255 if (!ibendport)
256 return;
257
258 free(ibendport->ibdev_name);
259 sepol_context_free(ibendport->con);
260 free(ibendport);
261 }
262
263
264 /* Context */
sepol_ibendport_get_con(const sepol_ibendport_t * ibendport)265 sepol_context_t *sepol_ibendport_get_con(const sepol_ibendport_t *ibendport)
266 {
267 return ibendport->con;
268 }
269
270
sepol_ibendport_set_con(sepol_handle_t * handle,sepol_ibendport_t * ibendport,sepol_context_t * con)271 int sepol_ibendport_set_con(sepol_handle_t *handle,
272 sepol_ibendport_t *ibendport, sepol_context_t *con)
273 {
274 sepol_context_t *newcon;
275
276 if (sepol_context_clone(handle, con, &newcon) < 0) {
277 ERR(handle, "out of memory, could not set ibendport context");
278 return STATUS_ERR;
279 }
280
281 sepol_context_free(ibendport->con);
282 ibendport->con = newcon;
283 return STATUS_SUCCESS;
284 }
285
286