Home | History | Annotate | Download | only in src
      1 #include <stdlib.h>
      2 
      3 #include "debug.h"
      4 #include "context.h"
      5 #include "handle.h"
      6 
      7 #include <sepol/policydb/policydb.h>
      8 #include <sepol/interfaces.h>
      9 #include "iface_internal.h"
     10 
     11 /* Create a low level structure from record */
     12 static int iface_from_record(sepol_handle_t * handle,
     13 			     const policydb_t * policydb,
     14 			     ocontext_t ** iface, const sepol_iface_t * record)
     15 {
     16 
     17 	ocontext_t *tmp_iface = NULL;
     18 	context_struct_t *tmp_con = NULL;
     19 
     20 	tmp_iface = (ocontext_t *) calloc(1, sizeof(ocontext_t));
     21 	if (!tmp_iface)
     22 		goto omem;
     23 
     24 	/* Name */
     25 	tmp_iface->u.name = strdup(sepol_iface_get_name(record));
     26 	if (!tmp_iface->u.name)
     27 		goto omem;
     28 
     29 	/* Interface Context */
     30 	if (context_from_record(handle, policydb,
     31 				&tmp_con, sepol_iface_get_ifcon(record)) < 0)
     32 		goto err;
     33 	context_cpy(&tmp_iface->context[0], tmp_con);
     34 	context_destroy(tmp_con);
     35 	free(tmp_con);
     36 	tmp_con = NULL;
     37 
     38 	/* Message Context */
     39 	if (context_from_record(handle, policydb,
     40 				&tmp_con, sepol_iface_get_msgcon(record)) < 0)
     41 		goto err;
     42 	context_cpy(&tmp_iface->context[1], tmp_con);
     43 	context_destroy(tmp_con);
     44 	free(tmp_con);
     45 	tmp_con = NULL;
     46 
     47 	*iface = tmp_iface;
     48 	return STATUS_SUCCESS;
     49 
     50       omem:
     51 	ERR(handle, "out of memory");
     52 
     53       err:
     54 	if (tmp_iface != NULL) {
     55 		free(tmp_iface->u.name);
     56 		context_destroy(&tmp_iface->context[0]);
     57 		context_destroy(&tmp_iface->context[1]);
     58 		free(tmp_iface);
     59 	}
     60 	context_destroy(tmp_con);
     61 	free(tmp_con);
     62 	ERR(handle, "error creating interface structure");
     63 	return STATUS_ERR;
     64 }
     65 
     66 static int iface_to_record(sepol_handle_t * handle,
     67 			   const policydb_t * policydb,
     68 			   ocontext_t * iface, sepol_iface_t ** record)
     69 {
     70 
     71 	char *name = iface->u.name;
     72 	context_struct_t *ifcon = &iface->context[0];
     73 	context_struct_t *msgcon = &iface->context[1];
     74 
     75 	sepol_context_t *tmp_con = NULL;
     76 	sepol_iface_t *tmp_record = NULL;
     77 
     78 	if (sepol_iface_create(handle, &tmp_record) < 0)
     79 		goto err;
     80 
     81 	if (sepol_iface_set_name(handle, tmp_record, name) < 0)
     82 		goto err;
     83 
     84 	if (context_to_record(handle, policydb, ifcon, &tmp_con) < 0)
     85 		goto err;
     86 	if (sepol_iface_set_ifcon(handle, tmp_record, tmp_con) < 0)
     87 		goto err;
     88 	sepol_context_free(tmp_con);
     89 	tmp_con = NULL;
     90 
     91 	if (context_to_record(handle, policydb, msgcon, &tmp_con) < 0)
     92 		goto err;
     93 	if (sepol_iface_set_msgcon(handle, tmp_record, tmp_con) < 0)
     94 		goto err;
     95 	sepol_context_free(tmp_con);
     96 	tmp_con = NULL;
     97 
     98 	*record = tmp_record;
     99 	return STATUS_SUCCESS;
    100 
    101       err:
    102 	ERR(handle, "could not convert interface %s to record", name);
    103 	sepol_context_free(tmp_con);
    104 	sepol_iface_free(tmp_record);
    105 	return STATUS_ERR;
    106 }
    107 
    108 /* Check if an interface exists */
    109 int sepol_iface_exists(sepol_handle_t * handle __attribute__ ((unused)),
    110 		       const sepol_policydb_t * p,
    111 		       const sepol_iface_key_t * key, int *response)
    112 {
    113 
    114 	const policydb_t *policydb = &p->p;
    115 	ocontext_t *c, *head;
    116 
    117 	const char *name;
    118 	sepol_iface_key_unpack(key, &name);
    119 
    120 	head = policydb->ocontexts[OCON_NETIF];
    121 	for (c = head; c; c = c->next) {
    122 		if (!strcmp(name, c->u.name)) {
    123 			*response = 1;
    124 			return STATUS_SUCCESS;
    125 		}
    126 	}
    127 	*response = 0;
    128 
    129 	handle = NULL;
    130 	return STATUS_SUCCESS;
    131 }
    132 
    133 /* Query an interface */
    134 int sepol_iface_query(sepol_handle_t * handle,
    135 		      const sepol_policydb_t * p,
    136 		      const sepol_iface_key_t * key, sepol_iface_t ** response)
    137 {
    138 
    139 	const policydb_t *policydb = &p->p;
    140 	ocontext_t *c, *head;
    141 
    142 	const char *name;
    143 	sepol_iface_key_unpack(key, &name);
    144 
    145 	head = policydb->ocontexts[OCON_NETIF];
    146 	for (c = head; c; c = c->next) {
    147 		if (!strcmp(name, c->u.name)) {
    148 
    149 			if (iface_to_record(handle, policydb, c, response) < 0)
    150 				goto err;
    151 
    152 			return STATUS_SUCCESS;
    153 		}
    154 	}
    155 
    156 	*response = NULL;
    157 	return STATUS_SUCCESS;
    158 
    159       err:
    160 	ERR(handle, "could not query interface %s", name);
    161 	return STATUS_ERR;
    162 }
    163 
    164 /* Load an interface into policy */
    165 int sepol_iface_modify(sepol_handle_t * handle,
    166 		       sepol_policydb_t * p,
    167 		       const sepol_iface_key_t * key,
    168 		       const sepol_iface_t * data)
    169 {
    170 
    171 	policydb_t *policydb = &p->p;
    172 	ocontext_t *head, *prev, *c, *iface = NULL;
    173 
    174 	const char *name;
    175 	sepol_iface_key_unpack(key, &name);
    176 
    177 	if (iface_from_record(handle, policydb, &iface, data) < 0)
    178 		goto err;
    179 
    180 	prev = NULL;
    181 	head = policydb->ocontexts[OCON_NETIF];
    182 	for (c = head; c; c = c->next) {
    183 		if (!strcmp(name, c->u.name)) {
    184 
    185 			/* Replace */
    186 			iface->next = c->next;
    187 			if (prev == NULL)
    188 				policydb->ocontexts[OCON_NETIF] = iface;
    189 			else
    190 				prev->next = iface;
    191 			free(c->u.name);
    192 			context_destroy(&c->context[0]);
    193 			context_destroy(&c->context[1]);
    194 			free(c);
    195 
    196 			return STATUS_SUCCESS;
    197 		}
    198 		prev = c;
    199 	}
    200 
    201 	/* Attach to context list */
    202 	iface->next = policydb->ocontexts[OCON_NETIF];
    203 	policydb->ocontexts[OCON_NETIF] = iface;
    204 	return STATUS_SUCCESS;
    205 
    206       err:
    207 	ERR(handle, "error while loading interface %s", name);
    208 
    209 	if (iface != NULL) {
    210 		free(iface->u.name);
    211 		context_destroy(&iface->context[0]);
    212 		context_destroy(&iface->context[1]);
    213 		free(iface);
    214 	}
    215 	return STATUS_ERR;
    216 }
    217 
    218 /* Return the number of interfaces */
    219 extern int sepol_iface_count(sepol_handle_t * handle __attribute__ ((unused)),
    220 			     const sepol_policydb_t * p, unsigned int *response)
    221 {
    222 
    223 	unsigned int count = 0;
    224 	ocontext_t *c, *head;
    225 	const policydb_t *policydb = &p->p;
    226 
    227 	head = policydb->ocontexts[OCON_NETIF];
    228 	for (c = head; c != NULL; c = c->next)
    229 		count++;
    230 
    231 	*response = count;
    232 
    233 	handle = NULL;
    234 	return STATUS_SUCCESS;
    235 }
    236 
    237 int sepol_iface_iterate(sepol_handle_t * handle,
    238 			const sepol_policydb_t * p,
    239 			int (*fn) (const sepol_iface_t * iface,
    240 				   void *fn_arg), void *arg)
    241 {
    242 
    243 	const policydb_t *policydb = &p->p;
    244 	ocontext_t *c, *head;
    245 	sepol_iface_t *iface = NULL;
    246 
    247 	head = policydb->ocontexts[OCON_NETIF];
    248 	for (c = head; c; c = c->next) {
    249 		int status;
    250 
    251 		if (iface_to_record(handle, policydb, c, &iface) < 0)
    252 			goto err;
    253 
    254 		/* Invoke handler */
    255 		status = fn(iface, arg);
    256 		if (status < 0)
    257 			goto err;
    258 
    259 		sepol_iface_free(iface);
    260 		iface = NULL;
    261 
    262 		/* Handler requested exit */
    263 		if (status > 0)
    264 			break;
    265 	}
    266 
    267 	return STATUS_SUCCESS;
    268 
    269       err:
    270 	ERR(handle, "could not iterate over interfaces");
    271 	sepol_iface_free(iface);
    272 	return STATUS_ERR;
    273 }
    274