Home | History | Annotate | Download | only in src
      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) */
     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 */
     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 
     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 
     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 
    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 
    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 
    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 
    150 int sepol_ibendport_get_port(const sepol_ibendport_t *ibendport)
    151 {
    152 	return ibendport->port;
    153 }
    154 
    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 
    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 
    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 
    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 
    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 */
    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 
    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 
    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