113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <netinet/in.h> 213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <arpa/inet.h> 313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h> 413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "debug.h" 613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "context.h" 713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "handle.h" 813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/policydb.h> 1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "node_internal.h" 1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Create a low level node structure from 1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * a high level representation */ 1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int node_from_record(sepol_handle_t * handle, 1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const policydb_t * policydb, 1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ocontext_t ** node, const sepol_node_t * data) 1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ocontext_t *tmp_node = NULL; 2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_struct_t *tmp_con = NULL; 2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *addr_buf = NULL, *mask_buf = NULL; 2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tmp_node = (ocontext_t *) calloc(1, sizeof(ocontext_t)); 2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!tmp_node) 2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto omem; 2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle size_t addr_bsize, mask_bsize; 2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Address and netmask */ 3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (sepol_node_get_addr_bytes(handle, data, &addr_buf, &addr_bsize) < 0) 3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (sepol_node_get_mask_bytes(handle, data, &mask_buf, &mask_bsize) < 0) 3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int proto = sepol_node_get_proto(data); 3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (proto) { 3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PROTO_IP4: 3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memcpy(&tmp_node->u.node.addr, addr_buf, addr_bsize); 4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memcpy(&tmp_node->u.node.mask, mask_buf, mask_bsize); 4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PROTO_IP6: 4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memcpy(tmp_node->u.node6.addr, addr_buf, addr_bsize); 4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memcpy(tmp_node->u.node6.mask, mask_buf, mask_bsize); 4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default: 4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "unsupported protocol %u", proto); 4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(addr_buf); 5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mask_buf); 5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle addr_buf = NULL; 5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mask_buf = NULL; 5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Context */ 5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (context_from_record(handle, policydb, &tmp_con, 5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_node_get_con(data)) < 0) 5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_cpy(&tmp_node->context[0], tmp_con); 6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_destroy(tmp_con); 6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(tmp_con); 6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tmp_con = NULL; 6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *node = tmp_node; 6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle omem: 6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "out of memory"); 6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle err: 7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (tmp_node != NULL) { 7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_destroy(&tmp_node->context[0]); 7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(tmp_node); 7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_destroy(tmp_con); 7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(tmp_con); 7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(addr_buf); 7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mask_buf); 7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "could not create node structure"); 8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_ERR; 8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int node_to_record(sepol_handle_t * handle, 8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const policydb_t * policydb, 8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ocontext_t * node, int proto, sepol_node_t ** record) 8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_struct_t *con = &node->context[0]; 8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_context_t *tmp_con = NULL; 9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_node_t *tmp_record = NULL; 9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (sepol_node_create(handle, &tmp_record) < 0) 9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_node_set_proto(tmp_record, proto); 9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (proto) { 9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PROTO_IP4: 10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (sepol_node_set_addr_bytes(handle, tmp_record, 10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (const char *)&node->u.node.addr, 10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4) < 0) 10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (sepol_node_set_mask_bytes(handle, tmp_record, 10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (const char *)&node->u.node.mask, 10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4) < 0) 10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PROTO_IP6: 11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (sepol_node_set_addr_bytes(handle, tmp_record, 11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (const char *)&node->u.node6.addr, 11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16) < 0) 11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (sepol_node_set_mask_bytes(handle, tmp_record, 11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (const char *)&node->u.node6.mask, 12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16) < 0) 12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default: 12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "unsupported protocol %u", proto); 12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (context_to_record(handle, policydb, con, &tmp_con) < 0) 13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (sepol_node_set_con(handle, tmp_record, tmp_con) < 0) 13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_context_free(tmp_con); 13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *record = tmp_record; 13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle err: 14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "could not convert node to record"); 14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_context_free(tmp_con); 14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_node_free(tmp_record); 14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_ERR; 14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Return the number of nodes */ 147033959726bf32ab59a52201e0696f269c0810609Justin P. Mattockextern int sepol_node_count(sepol_handle_t * handle __attribute__ ((unused)), 14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const sepol_policydb_t * p, unsigned int *response) 14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int count = 0; 15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ocontext_t *c, *head; 15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const policydb_t *policydb = &p->p; 15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle head = policydb->ocontexts[OCON_NODE]; 15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (c = head; c != NULL; c = c->next) 15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle count++; 15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle head = policydb->ocontexts[OCON_NODE6]; 16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (c = head; c != NULL; c = c->next) 16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle count++; 16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *response = count; 16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Check if a node exists */ 16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_exists(sepol_handle_t * handle, 17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const sepol_policydb_t * p, 17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const sepol_node_key_t * key, int *response) 17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const policydb_t *policydb = &p->p; 17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ocontext_t *c, *head; 17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int proto; 17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const char *addr, *mask; 17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_node_key_unpack(key, &addr, &mask, &proto); 18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (proto) { 18213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 18313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PROTO_IP4: 18413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle { 18513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle head = policydb->ocontexts[OCON_NODE]; 18613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (c = head; c; c = c->next) { 18713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int *addr2 = &c->u.node.addr; 18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int *mask2 = &c->u.node.mask; 18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!memcmp(addr, addr2, 4) && 19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle !memcmp(mask, mask2, 4)) { 19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *response = 1; 19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PROTO_IP6: 20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle { 20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle head = policydb->ocontexts[OCON_NODE6]; 20213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (c = head; c; c = c->next) { 20313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int *addr2 = c->u.node6.addr; 20413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int *mask2 = c->u.node6.mask; 20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!memcmp(addr, addr2, 16) && 20713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle !memcmp(mask, mask2, 16)) { 20813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *response = 1; 20913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 21013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 21113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 21213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 21313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 21413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default: 21513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "unsupported protocol %u", proto); 21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 21713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 21813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 21913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *response = 0; 22013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 22113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 22213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle err: 22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "could not check if node %s/%s (%s) exists", 22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle addr, mask, sepol_node_get_proto_str(proto)); 22513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_ERR; 22613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 22713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 22813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Query a node */ 22913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_query(sepol_handle_t * handle, 23013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const sepol_policydb_t * p, 23113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const sepol_node_key_t * key, sepol_node_t ** response) 23213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 23313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 23413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const policydb_t *policydb = &p->p; 23513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ocontext_t *c, *head; 23613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 23713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int proto; 23813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const char *addr, *mask; 23913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_node_key_unpack(key, &addr, &mask, &proto); 24013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 24113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (proto) { 24213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PROTO_IP4: 24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle { 24513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle head = policydb->ocontexts[OCON_NODE]; 24613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (c = head; c; c = c->next) { 24713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int *addr2 = &c->u.node.addr; 24813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int *mask2 = &c->u.node.mask; 24913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 25013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!memcmp(addr, addr2, 4) && 25113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle !memcmp(mask, mask2, 4)) { 25213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 25313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (node_to_record(handle, policydb, 25413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle c, SEPOL_PROTO_IP4, 25513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle response) < 0) 25613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 25713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 25813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 25913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 26013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 26113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 26213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PROTO_IP6: 26313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle { 26413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle head = policydb->ocontexts[OCON_NODE6]; 26513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (c = head; c; c = c->next) { 26613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int *addr2 = c->u.node6.addr; 26713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int *mask2 = c->u.node6.mask; 26813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 26913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!memcmp(addr, addr2, 16) && 27013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle !memcmp(mask, mask2, 16)) { 27113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 27213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (node_to_record(handle, policydb, 27313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle c, SEPOL_PROTO_IP6, 27413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle response) < 0) 27513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 276747a440fdd5b32c16739ecbd76367eb2a582fe82Petr Lautrbach return STATUS_SUCCESS; 27713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 27813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 27913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 28013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 28113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default: 28213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "unsupported protocol %u", proto); 28313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 28413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 28513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *response = NULL; 28613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 28713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 28813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle err: 28913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "could not query node %s/%s (%s)", 29013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle addr, mask, sepol_node_get_proto_str(proto)); 29113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_ERR; 29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 29413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 29513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Load a node into policy */ 29613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_modify(sepol_handle_t * handle, 29713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_policydb_t * p, 29813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const sepol_node_key_t * key, const sepol_node_t * data) 29913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 30013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t *policydb = &p->p; 30213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ocontext_t *node = NULL; 30313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int proto; 30513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const char *addr, *mask; 30613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 30713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_node_key_unpack(key, &addr, &mask, &proto); 30813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 30913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (node_from_record(handle, policydb, &node, data) < 0) 31013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 31113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 31213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (proto) { 31313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 31413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PROTO_IP4: 31513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle { 31613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Attach to context list */ 31713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node->next = policydb->ocontexts[OCON_NODE]; 31813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb->ocontexts[OCON_NODE] = node; 31913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 32013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 32113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case SEPOL_PROTO_IP6: 32213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle { 32313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Attach to context list */ 32413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node->next = policydb->ocontexts[OCON_NODE6]; 32513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb->ocontexts[OCON_NODE6] = node; 32613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 32713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 32813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default: 32913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "unsupported protocol %u", proto); 33013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 33113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 33213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 33313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 33413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle err: 33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "could not load node %s/%s (%s)", 33713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle addr, mask, sepol_node_get_proto_str(proto)); 33813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (node != NULL) { 33913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_destroy(&node->context[0]); 34013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(node); 34113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_ERR; 34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 34413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 34513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint sepol_node_iterate(sepol_handle_t * handle, 34613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const sepol_policydb_t * p, 34713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int (*fn) (const sepol_node_t * node, 34813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *fn_arg), void *arg) 34913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 35013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 35113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const policydb_t *policydb = &p->p; 35213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ocontext_t *c, *head; 35313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_node_t *node = NULL; 35413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int status; 35513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 35613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle head = policydb->ocontexts[OCON_NODE]; 35713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (c = head; c; c = c->next) { 35813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (node_to_record(handle, policydb, c, SEPOL_PROTO_IP4, &node) 35913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle < 0) 36013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 36113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 36213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Invoke handler */ 36313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle status = fn(node, arg); 36413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (status < 0) 36513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 36613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 36713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_node_free(node); 36813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = NULL; 36913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 37013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Handler requested exit */ 37113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (status > 0) 37213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 37313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 37413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 37513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle head = policydb->ocontexts[OCON_NODE6]; 37613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (c = head; c; c = c->next) { 37713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (node_to_record(handle, policydb, c, SEPOL_PROTO_IP6, &node) 37813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle < 0) 37913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 38013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 38113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Invoke handler */ 38213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle status = fn(node, arg); 38313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (status < 0) 38413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 38513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 38613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_node_free(node); 38713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = NULL; 38813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 38913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Handler requested exit */ 39013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (status > 0) 39113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 39213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 39313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 39413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 39513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 39613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle err: 39713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "could not iterate over nodes"); 39813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_node_free(node); 39913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_ERR; 40013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 401