Home | History | Annotate | Download | only in src
      1 #include <netinet/in.h>
      2 #include <stdlib.h>
      3 
      4 #include "debug.h"
      5 #include "context.h"
      6 #include "handle.h"
      7 
      8 #include <sepol/policydb/policydb.h>
      9 #include "ibendport_internal.h"
     10 
     11 /* Create a low level ibendport structure from
     12  * a high level representation
     13  */
     14 static int ibendport_from_record(sepol_handle_t *handle,
     15 				 const policydb_t *policydb,
     16 				 ocontext_t **ibendport,
     17 				 const sepol_ibendport_t *data)
     18 {
     19 	ocontext_t *tmp_ibendport = NULL;
     20 	context_struct_t *tmp_con = NULL;
     21 	char *ibdev_name = NULL;
     22 	int port = sepol_ibendport_get_port(data);
     23 
     24 	tmp_ibendport = (ocontext_t *)calloc(1, sizeof(ocontext_t));
     25 	if (!tmp_ibendport)
     26 		goto omem;
     27 
     28 	if (sepol_ibendport_alloc_ibdev_name(handle,
     29 					     &tmp_ibendport->u.ibendport.dev_name) < 0)
     30 		goto omem;
     31 
     32 	if (sepol_ibendport_get_ibdev_name(handle,
     33 					   data,
     34 					   &ibdev_name) < 0)
     35 		goto err;
     36 
     37 	strncpy(tmp_ibendport->u.ibendport.dev_name, ibdev_name, IB_DEVICE_NAME_MAX);
     38 
     39 	free(ibdev_name);
     40 	ibdev_name = NULL;
     41 
     42 	tmp_ibendport->u.ibendport.port = port;
     43 
     44 	/* Context */
     45 	if (context_from_record(handle, policydb, &tmp_con,
     46 				sepol_ibendport_get_con(data)) < 0)
     47 		goto err;
     48 	context_cpy(&tmp_ibendport->context[0], tmp_con);
     49 	context_destroy(tmp_con);
     50 	free(tmp_con);
     51 	tmp_con = NULL;
     52 
     53 	*ibendport = tmp_ibendport;
     54 	return STATUS_SUCCESS;
     55 
     56 omem:
     57 	ERR(handle, "out of memory");
     58 
     59 err:
     60 	if (tmp_ibendport) {
     61 		context_destroy(&tmp_ibendport->context[0]);
     62 		free(tmp_ibendport);
     63 	}
     64 	context_destroy(tmp_con);
     65 	free(tmp_con);
     66 	free(ibdev_name);
     67 	ERR(handle, "could not create ibendport structure");
     68 	return STATUS_ERR;
     69 }
     70 
     71 static int ibendport_to_record(sepol_handle_t *handle,
     72 			       const policydb_t *policydb,
     73 			       ocontext_t *ibendport,
     74 			       sepol_ibendport_t **record)
     75 {
     76 	int port = ibendport->u.ibendport.port;
     77 	context_struct_t *con = &ibendport->context[0];
     78 
     79 	sepol_context_t *tmp_con = NULL;
     80 	sepol_ibendport_t *tmp_record = NULL;
     81 
     82 	if (sepol_ibendport_create(handle, &tmp_record) < 0)
     83 		goto err;
     84 
     85 	if (sepol_ibendport_set_ibdev_name(handle, tmp_record,
     86 					   ibendport->u.ibendport.dev_name) < 0)
     87 		goto err;
     88 
     89 	sepol_ibendport_set_port(tmp_record, port);
     90 
     91 	if (context_to_record(handle, policydb, con, &tmp_con) < 0)
     92 		goto err;
     93 
     94 	if (sepol_ibendport_set_con(handle, tmp_record, tmp_con) < 0)
     95 		goto err;
     96 
     97 	sepol_context_free(tmp_con);
     98 	*record = tmp_record;
     99 	return STATUS_SUCCESS;
    100 
    101 err:
    102 	ERR(handle, "could not convert ibendport to record");
    103 	sepol_context_free(tmp_con);
    104 	sepol_ibendport_free(tmp_record);
    105 	return STATUS_ERR;
    106 }
    107 
    108 /* Return the number of ibendports */
    109 extern int sepol_ibendport_count(sepol_handle_t *handle __attribute__ ((unused)),
    110 				 const sepol_policydb_t *p, unsigned int *response)
    111 {
    112 	unsigned int count = 0;
    113 	ocontext_t *c, *head;
    114 	const policydb_t *policydb = &p->p;
    115 
    116 	head = policydb->ocontexts[OCON_IBENDPORT];
    117 	for (c = head; c; c = c->next)
    118 		count++;
    119 
    120 	*response = count;
    121 
    122 	return STATUS_SUCCESS;
    123 }
    124 
    125 /* Check if a ibendport exists */
    126 int sepol_ibendport_exists(sepol_handle_t *handle __attribute__ ((unused)),
    127 			   const sepol_policydb_t *p,
    128 			   const sepol_ibendport_key_t *key, int *response)
    129 {
    130 	const policydb_t *policydb = &p->p;
    131 	ocontext_t *c, *head;
    132 	int port;
    133 	const char *ibdev_name;
    134 
    135 	sepol_ibendport_key_unpack(key, &ibdev_name, &port);
    136 
    137 	head = policydb->ocontexts[OCON_IBENDPORT];
    138 	for (c = head; c; c = c->next) {
    139 		const char *ibdev_name2 = c->u.ibendport.dev_name;
    140 		int port2 = c->u.ibendport.port;
    141 
    142 		if (port2 == port &&
    143 		    (!strcmp(ibdev_name, ibdev_name2))) {
    144 			*response = 1;
    145 			return STATUS_SUCCESS;
    146 		}
    147 	}
    148 
    149 	*response = 0;
    150 	return STATUS_SUCCESS;
    151 }
    152 
    153 int sepol_ibendport_query(sepol_handle_t *handle,
    154 			  const sepol_policydb_t *p,
    155 			  const sepol_ibendport_key_t *key,
    156 			  sepol_ibendport_t **response)
    157 {
    158 	const policydb_t *policydb = &p->p;
    159 	ocontext_t *c, *head;
    160 	int port;
    161 	const char *ibdev_name;
    162 
    163 	sepol_ibendport_key_unpack(key, &ibdev_name, &port);
    164 
    165 	head = policydb->ocontexts[OCON_IBENDPORT];
    166 	for (c = head; c; c = c->next) {
    167 		const char *ibdev_name2 = c->u.ibendport.dev_name;
    168 		int port2 = c->u.ibendport.port;
    169 
    170 		if (port2 == port &&
    171 		    (!strcmp(ibdev_name, ibdev_name2))) {
    172 			if (ibendport_to_record(handle, policydb, c, response) < 0)
    173 				goto err;
    174 			return STATUS_SUCCESS;
    175 		}
    176 	}
    177 
    178 	*response = NULL;
    179 	return STATUS_SUCCESS;
    180 
    181 err:
    182 	ERR(handle, "could not query ibendport, IB device: %s port %u",
    183 	    ibdev_name, port);
    184 	return STATUS_ERR;
    185 }
    186 
    187 /* Load a ibendport into policy */
    188 int sepol_ibendport_modify(sepol_handle_t *handle,
    189 			   sepol_policydb_t *p,
    190 			   const sepol_ibendport_key_t *key,
    191 			   const sepol_ibendport_t *data)
    192 {
    193 	policydb_t *policydb = &p->p;
    194 	ocontext_t *ibendport = NULL;
    195 	int port;
    196 	const char *ibdev_name;
    197 
    198 	sepol_ibendport_key_unpack(key, &ibdev_name, &port);
    199 
    200 	if (ibendport_from_record(handle, policydb, &ibendport, data) < 0)
    201 		goto err;
    202 
    203 	/* Attach to context list */
    204 	ibendport->next = policydb->ocontexts[OCON_IBENDPORT];
    205 	policydb->ocontexts[OCON_IBENDPORT] = ibendport;
    206 
    207 	return STATUS_SUCCESS;
    208 
    209 err:
    210 	ERR(handle, "could not load ibendport %s/%d",
    211 	    ibdev_name, port);
    212 	if (ibendport) {
    213 		context_destroy(&ibendport->context[0]);
    214 		free(ibendport);
    215 	}
    216 	return STATUS_ERR;
    217 }
    218 
    219 int sepol_ibendport_iterate(sepol_handle_t *handle,
    220 			    const sepol_policydb_t *p,
    221 			    int (*fn)(const sepol_ibendport_t *ibendport,
    222 				      void *fn_arg), void *arg)
    223 {
    224 	const policydb_t *policydb = &p->p;
    225 	ocontext_t *c, *head;
    226 	sepol_ibendport_t *ibendport = NULL;
    227 
    228 	head = policydb->ocontexts[OCON_IBENDPORT];
    229 	for (c = head; c; c = c->next) {
    230 		int status;
    231 
    232 		if (ibendport_to_record(handle, policydb, c, &ibendport) < 0)
    233 			goto err;
    234 
    235 		/* Invoke handler */
    236 		status = fn(ibendport, arg);
    237 		if (status < 0)
    238 			goto err;
    239 
    240 		sepol_ibendport_free(ibendport);
    241 		ibendport = NULL;
    242 
    243 		/* Handler requested exit */
    244 		if (status > 0)
    245 			break;
    246 	}
    247 
    248 	return STATUS_SUCCESS;
    249 
    250 err:
    251 	ERR(handle, "could not iterate over ibendports");
    252 	sepol_ibendport_free(ibendport);
    253 	return STATUS_ERR;
    254 }
    255