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