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 	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 */
     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 
     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 
     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 
    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 
    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 
    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 
    153 int sepol_ibendport_get_port(const sepol_ibendport_t *ibendport)
    154 {
    155 	return ibendport->port;
    156 }
    157 
    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 
    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 
    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 
    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 
    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 */
    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 
    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 
    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