1255e72915d4cbddceb435e13d81601755714e9fSE Android#include <netinet/in.h> 2255e72915d4cbddceb435e13d81601755714e9fSE Android#include <arpa/inet.h> 3255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h> 4255e72915d4cbddceb435e13d81601755714e9fSE Android 5255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h" 6255e72915d4cbddceb435e13d81601755714e9fSE Android#include "context.h" 7255e72915d4cbddceb435e13d81601755714e9fSE Android#include "handle.h" 8255e72915d4cbddceb435e13d81601755714e9fSE Android 9255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/policydb.h> 10255e72915d4cbddceb435e13d81601755714e9fSE Android#include "node_internal.h" 11255e72915d4cbddceb435e13d81601755714e9fSE Android 12255e72915d4cbddceb435e13d81601755714e9fSE Android/* Create a low level node structure from 13255e72915d4cbddceb435e13d81601755714e9fSE Android * a high level representation */ 14255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int node_from_record(sepol_handle_t * handle, 15255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t * policydb, 16255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t ** node, const sepol_node_t * data) 17255e72915d4cbddceb435e13d81601755714e9fSE Android{ 18255e72915d4cbddceb435e13d81601755714e9fSE Android 19255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *tmp_node = NULL; 20255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *tmp_con = NULL; 21255e72915d4cbddceb435e13d81601755714e9fSE Android char *addr_buf = NULL, *mask_buf = NULL; 22255e72915d4cbddceb435e13d81601755714e9fSE Android 23255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_node = (ocontext_t *) calloc(1, sizeof(ocontext_t)); 24255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tmp_node) 25255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 26255e72915d4cbddceb435e13d81601755714e9fSE Android 27255e72915d4cbddceb435e13d81601755714e9fSE Android size_t addr_bsize, mask_bsize; 28255e72915d4cbddceb435e13d81601755714e9fSE Android 29255e72915d4cbddceb435e13d81601755714e9fSE Android /* Address and netmask */ 30255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_node_get_addr_bytes(handle, data, &addr_buf, &addr_bsize) < 0) 31255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 32255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_node_get_mask_bytes(handle, data, &mask_buf, &mask_bsize) < 0) 33255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 34255e72915d4cbddceb435e13d81601755714e9fSE Android 35255e72915d4cbddceb435e13d81601755714e9fSE Android int proto = sepol_node_get_proto(data); 36255e72915d4cbddceb435e13d81601755714e9fSE Android 37255e72915d4cbddceb435e13d81601755714e9fSE Android switch (proto) { 38255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_IP4: 39255e72915d4cbddceb435e13d81601755714e9fSE Android memcpy(&tmp_node->u.node.addr, addr_buf, addr_bsize); 40255e72915d4cbddceb435e13d81601755714e9fSE Android memcpy(&tmp_node->u.node.mask, mask_buf, mask_bsize); 41255e72915d4cbddceb435e13d81601755714e9fSE Android break; 42255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_IP6: 43255e72915d4cbddceb435e13d81601755714e9fSE Android memcpy(tmp_node->u.node6.addr, addr_buf, addr_bsize); 44255e72915d4cbddceb435e13d81601755714e9fSE Android memcpy(tmp_node->u.node6.mask, mask_buf, mask_bsize); 45255e72915d4cbddceb435e13d81601755714e9fSE Android break; 46255e72915d4cbddceb435e13d81601755714e9fSE Android default: 47255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "unsupported protocol %u", proto); 48255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 49255e72915d4cbddceb435e13d81601755714e9fSE Android } 50255e72915d4cbddceb435e13d81601755714e9fSE Android free(addr_buf); 51255e72915d4cbddceb435e13d81601755714e9fSE Android free(mask_buf); 52255e72915d4cbddceb435e13d81601755714e9fSE Android addr_buf = NULL; 53255e72915d4cbddceb435e13d81601755714e9fSE Android mask_buf = NULL; 54255e72915d4cbddceb435e13d81601755714e9fSE Android 55255e72915d4cbddceb435e13d81601755714e9fSE Android /* Context */ 56255e72915d4cbddceb435e13d81601755714e9fSE Android if (context_from_record(handle, policydb, &tmp_con, 57255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_node_get_con(data)) < 0) 58255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 59255e72915d4cbddceb435e13d81601755714e9fSE Android context_cpy(&tmp_node->context[0], tmp_con); 60255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(tmp_con); 61255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp_con); 62255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_con = NULL; 63255e72915d4cbddceb435e13d81601755714e9fSE Android 64255e72915d4cbddceb435e13d81601755714e9fSE Android *node = tmp_node; 65255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 66255e72915d4cbddceb435e13d81601755714e9fSE Android 67255e72915d4cbddceb435e13d81601755714e9fSE Android omem: 68255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "out of memory"); 69255e72915d4cbddceb435e13d81601755714e9fSE Android 70255e72915d4cbddceb435e13d81601755714e9fSE Android err: 71255e72915d4cbddceb435e13d81601755714e9fSE Android if (tmp_node != NULL) { 72255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&tmp_node->context[0]); 73255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp_node); 74255e72915d4cbddceb435e13d81601755714e9fSE Android } 75255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(tmp_con); 76255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp_con); 77255e72915d4cbddceb435e13d81601755714e9fSE Android free(addr_buf); 78255e72915d4cbddceb435e13d81601755714e9fSE Android free(mask_buf); 79255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not create node structure"); 80255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 81255e72915d4cbddceb435e13d81601755714e9fSE Android} 82255e72915d4cbddceb435e13d81601755714e9fSE Android 83255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int node_to_record(sepol_handle_t * handle, 84255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t * policydb, 85255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t * node, int proto, sepol_node_t ** record) 86255e72915d4cbddceb435e13d81601755714e9fSE Android{ 87255e72915d4cbddceb435e13d81601755714e9fSE Android 88255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *con = &node->context[0]; 89255e72915d4cbddceb435e13d81601755714e9fSE Android 90255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_t *tmp_con = NULL; 91255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_node_t *tmp_record = NULL; 92255e72915d4cbddceb435e13d81601755714e9fSE Android 93255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_node_create(handle, &tmp_record) < 0) 94255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 95255e72915d4cbddceb435e13d81601755714e9fSE Android 96255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_node_set_proto(tmp_record, proto); 97255e72915d4cbddceb435e13d81601755714e9fSE Android 98255e72915d4cbddceb435e13d81601755714e9fSE Android switch (proto) { 99255e72915d4cbddceb435e13d81601755714e9fSE Android 100255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_IP4: 101255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_node_set_addr_bytes(handle, tmp_record, 102255e72915d4cbddceb435e13d81601755714e9fSE Android (const char *)&node->u.node.addr, 103255e72915d4cbddceb435e13d81601755714e9fSE Android 4) < 0) 104255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 105255e72915d4cbddceb435e13d81601755714e9fSE Android 106255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_node_set_mask_bytes(handle, tmp_record, 107255e72915d4cbddceb435e13d81601755714e9fSE Android (const char *)&node->u.node.mask, 108255e72915d4cbddceb435e13d81601755714e9fSE Android 4) < 0) 109255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 110255e72915d4cbddceb435e13d81601755714e9fSE Android break; 111255e72915d4cbddceb435e13d81601755714e9fSE Android 112255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_IP6: 113255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_node_set_addr_bytes(handle, tmp_record, 114255e72915d4cbddceb435e13d81601755714e9fSE Android (const char *)&node->u.node6.addr, 115255e72915d4cbddceb435e13d81601755714e9fSE Android 16) < 0) 116255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 117255e72915d4cbddceb435e13d81601755714e9fSE Android 118255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_node_set_mask_bytes(handle, tmp_record, 119255e72915d4cbddceb435e13d81601755714e9fSE Android (const char *)&node->u.node6.mask, 120255e72915d4cbddceb435e13d81601755714e9fSE Android 16) < 0) 121255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 122255e72915d4cbddceb435e13d81601755714e9fSE Android break; 123255e72915d4cbddceb435e13d81601755714e9fSE Android 124255e72915d4cbddceb435e13d81601755714e9fSE Android default: 125255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "unsupported protocol %u", proto); 126255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 127255e72915d4cbddceb435e13d81601755714e9fSE Android } 128255e72915d4cbddceb435e13d81601755714e9fSE Android 129255e72915d4cbddceb435e13d81601755714e9fSE Android if (context_to_record(handle, policydb, con, &tmp_con) < 0) 130255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 131255e72915d4cbddceb435e13d81601755714e9fSE Android 132255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_node_set_con(handle, tmp_record, tmp_con) < 0) 133255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 134255e72915d4cbddceb435e13d81601755714e9fSE Android 135255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_free(tmp_con); 136255e72915d4cbddceb435e13d81601755714e9fSE Android *record = tmp_record; 137255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 138255e72915d4cbddceb435e13d81601755714e9fSE Android 139255e72915d4cbddceb435e13d81601755714e9fSE Android err: 140255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not convert node to record"); 141255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_free(tmp_con); 142255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_node_free(tmp_record); 143255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 144255e72915d4cbddceb435e13d81601755714e9fSE Android} 145255e72915d4cbddceb435e13d81601755714e9fSE Android 146255e72915d4cbddceb435e13d81601755714e9fSE Android/* Return the number of nodes */ 147255e72915d4cbddceb435e13d81601755714e9fSE Androidextern int sepol_node_count(sepol_handle_t * handle __attribute__ ((unused)), 148255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, unsigned int *response) 149255e72915d4cbddceb435e13d81601755714e9fSE Android{ 150255e72915d4cbddceb435e13d81601755714e9fSE Android 151255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int count = 0; 152255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *head; 153255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 154255e72915d4cbddceb435e13d81601755714e9fSE Android 155255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_NODE]; 156255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c != NULL; c = c->next) 157255e72915d4cbddceb435e13d81601755714e9fSE Android count++; 158255e72915d4cbddceb435e13d81601755714e9fSE Android 159255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_NODE6]; 160255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c != NULL; c = c->next) 161255e72915d4cbddceb435e13d81601755714e9fSE Android count++; 162255e72915d4cbddceb435e13d81601755714e9fSE Android 163255e72915d4cbddceb435e13d81601755714e9fSE Android *response = count; 164255e72915d4cbddceb435e13d81601755714e9fSE Android 165255e72915d4cbddceb435e13d81601755714e9fSE Android handle = NULL; 166255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 167255e72915d4cbddceb435e13d81601755714e9fSE Android} 168255e72915d4cbddceb435e13d81601755714e9fSE Android 169255e72915d4cbddceb435e13d81601755714e9fSE Android/* Check if a node exists */ 170255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_exists(sepol_handle_t * handle, 171255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, 172255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_node_key_t * key, int *response) 173255e72915d4cbddceb435e13d81601755714e9fSE Android{ 174255e72915d4cbddceb435e13d81601755714e9fSE Android 175255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 176255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *head; 177255e72915d4cbddceb435e13d81601755714e9fSE Android 178255e72915d4cbddceb435e13d81601755714e9fSE Android int proto; 179255e72915d4cbddceb435e13d81601755714e9fSE Android const char *addr, *mask; 180255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_node_key_unpack(key, &addr, &mask, &proto); 181255e72915d4cbddceb435e13d81601755714e9fSE Android 182255e72915d4cbddceb435e13d81601755714e9fSE Android switch (proto) { 183255e72915d4cbddceb435e13d81601755714e9fSE Android 184255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_IP4: 185255e72915d4cbddceb435e13d81601755714e9fSE Android { 186255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_NODE]; 187255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c; c = c->next) { 188255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int *addr2 = &c->u.node.addr; 189255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int *mask2 = &c->u.node.mask; 190255e72915d4cbddceb435e13d81601755714e9fSE Android 191255e72915d4cbddceb435e13d81601755714e9fSE Android if (!memcmp(addr, addr2, 4) && 192255e72915d4cbddceb435e13d81601755714e9fSE Android !memcmp(mask, mask2, 4)) { 193255e72915d4cbddceb435e13d81601755714e9fSE Android 194255e72915d4cbddceb435e13d81601755714e9fSE Android *response = 1; 195255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 196255e72915d4cbddceb435e13d81601755714e9fSE Android } 197255e72915d4cbddceb435e13d81601755714e9fSE Android } 198255e72915d4cbddceb435e13d81601755714e9fSE Android break; 199255e72915d4cbddceb435e13d81601755714e9fSE Android } 200255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_IP6: 201255e72915d4cbddceb435e13d81601755714e9fSE Android { 202255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_NODE6]; 203255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c; c = c->next) { 204255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int *addr2 = c->u.node6.addr; 205255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int *mask2 = c->u.node6.mask; 206255e72915d4cbddceb435e13d81601755714e9fSE Android 207255e72915d4cbddceb435e13d81601755714e9fSE Android if (!memcmp(addr, addr2, 16) && 208255e72915d4cbddceb435e13d81601755714e9fSE Android !memcmp(mask, mask2, 16)) { 209255e72915d4cbddceb435e13d81601755714e9fSE Android *response = 1; 210255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 211255e72915d4cbddceb435e13d81601755714e9fSE Android } 212255e72915d4cbddceb435e13d81601755714e9fSE Android } 213255e72915d4cbddceb435e13d81601755714e9fSE Android break; 214255e72915d4cbddceb435e13d81601755714e9fSE Android } 215255e72915d4cbddceb435e13d81601755714e9fSE Android default: 216255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "unsupported protocol %u", proto); 217255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 218255e72915d4cbddceb435e13d81601755714e9fSE Android } 219255e72915d4cbddceb435e13d81601755714e9fSE Android 220255e72915d4cbddceb435e13d81601755714e9fSE Android *response = 0; 221255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 222255e72915d4cbddceb435e13d81601755714e9fSE Android 223255e72915d4cbddceb435e13d81601755714e9fSE Android err: 224255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not check if node %s/%s (%s) exists", 225255e72915d4cbddceb435e13d81601755714e9fSE Android addr, mask, sepol_node_get_proto_str(proto)); 226255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 227255e72915d4cbddceb435e13d81601755714e9fSE Android} 228255e72915d4cbddceb435e13d81601755714e9fSE Android 229255e72915d4cbddceb435e13d81601755714e9fSE Android/* Query a node */ 230255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_query(sepol_handle_t * handle, 231255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, 232255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_node_key_t * key, sepol_node_t ** response) 233255e72915d4cbddceb435e13d81601755714e9fSE Android{ 234255e72915d4cbddceb435e13d81601755714e9fSE Android 235255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 236255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *head; 237255e72915d4cbddceb435e13d81601755714e9fSE Android 238255e72915d4cbddceb435e13d81601755714e9fSE Android int proto; 239255e72915d4cbddceb435e13d81601755714e9fSE Android const char *addr, *mask; 240255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_node_key_unpack(key, &addr, &mask, &proto); 241255e72915d4cbddceb435e13d81601755714e9fSE Android 242255e72915d4cbddceb435e13d81601755714e9fSE Android switch (proto) { 243255e72915d4cbddceb435e13d81601755714e9fSE Android 244255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_IP4: 245255e72915d4cbddceb435e13d81601755714e9fSE Android { 246255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_NODE]; 247255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c; c = c->next) { 248255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int *addr2 = &c->u.node.addr; 249255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int *mask2 = &c->u.node.mask; 250255e72915d4cbddceb435e13d81601755714e9fSE Android 251255e72915d4cbddceb435e13d81601755714e9fSE Android if (!memcmp(addr, addr2, 4) && 252255e72915d4cbddceb435e13d81601755714e9fSE Android !memcmp(mask, mask2, 4)) { 253255e72915d4cbddceb435e13d81601755714e9fSE Android 254255e72915d4cbddceb435e13d81601755714e9fSE Android if (node_to_record(handle, policydb, 255255e72915d4cbddceb435e13d81601755714e9fSE Android c, SEPOL_PROTO_IP4, 256255e72915d4cbddceb435e13d81601755714e9fSE Android response) < 0) 257255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 258255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 259255e72915d4cbddceb435e13d81601755714e9fSE Android } 260255e72915d4cbddceb435e13d81601755714e9fSE Android } 261255e72915d4cbddceb435e13d81601755714e9fSE Android break; 262255e72915d4cbddceb435e13d81601755714e9fSE Android } 263255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_IP6: 264255e72915d4cbddceb435e13d81601755714e9fSE Android { 265255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_NODE6]; 266255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c; c = c->next) { 267255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int *addr2 = c->u.node6.addr; 268255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int *mask2 = c->u.node6.mask; 269255e72915d4cbddceb435e13d81601755714e9fSE Android 270255e72915d4cbddceb435e13d81601755714e9fSE Android if (!memcmp(addr, addr2, 16) && 271255e72915d4cbddceb435e13d81601755714e9fSE Android !memcmp(mask, mask2, 16)) { 272255e72915d4cbddceb435e13d81601755714e9fSE Android 273255e72915d4cbddceb435e13d81601755714e9fSE Android if (node_to_record(handle, policydb, 274255e72915d4cbddceb435e13d81601755714e9fSE Android c, SEPOL_PROTO_IP6, 275255e72915d4cbddceb435e13d81601755714e9fSE Android response) < 0) 276255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 277255e72915d4cbddceb435e13d81601755714e9fSE Android } 278255e72915d4cbddceb435e13d81601755714e9fSE Android } 279255e72915d4cbddceb435e13d81601755714e9fSE Android break; 280255e72915d4cbddceb435e13d81601755714e9fSE Android } 281255e72915d4cbddceb435e13d81601755714e9fSE Android default: 282255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "unsupported protocol %u", proto); 283255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 284255e72915d4cbddceb435e13d81601755714e9fSE Android } 285255e72915d4cbddceb435e13d81601755714e9fSE Android *response = NULL; 286255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 287255e72915d4cbddceb435e13d81601755714e9fSE Android 288255e72915d4cbddceb435e13d81601755714e9fSE Android err: 289255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not query node %s/%s (%s)", 290255e72915d4cbddceb435e13d81601755714e9fSE Android addr, mask, sepol_node_get_proto_str(proto)); 291255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 292255e72915d4cbddceb435e13d81601755714e9fSE Android 293255e72915d4cbddceb435e13d81601755714e9fSE Android} 294255e72915d4cbddceb435e13d81601755714e9fSE Android 295255e72915d4cbddceb435e13d81601755714e9fSE Android/* Load a node into policy */ 296255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_modify(sepol_handle_t * handle, 297255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_policydb_t * p, 298255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_node_key_t * key, const sepol_node_t * data) 299255e72915d4cbddceb435e13d81601755714e9fSE Android{ 300255e72915d4cbddceb435e13d81601755714e9fSE Android 301255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *policydb = &p->p; 302255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *node = NULL; 303255e72915d4cbddceb435e13d81601755714e9fSE Android 304255e72915d4cbddceb435e13d81601755714e9fSE Android int proto; 305255e72915d4cbddceb435e13d81601755714e9fSE Android const char *addr, *mask; 306255e72915d4cbddceb435e13d81601755714e9fSE Android 307255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_node_key_unpack(key, &addr, &mask, &proto); 308255e72915d4cbddceb435e13d81601755714e9fSE Android 309255e72915d4cbddceb435e13d81601755714e9fSE Android if (node_from_record(handle, policydb, &node, data) < 0) 310255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 311255e72915d4cbddceb435e13d81601755714e9fSE Android 312255e72915d4cbddceb435e13d81601755714e9fSE Android switch (proto) { 313255e72915d4cbddceb435e13d81601755714e9fSE Android 314255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_IP4: 315255e72915d4cbddceb435e13d81601755714e9fSE Android { 316255e72915d4cbddceb435e13d81601755714e9fSE Android /* Attach to context list */ 317255e72915d4cbddceb435e13d81601755714e9fSE Android node->next = policydb->ocontexts[OCON_NODE]; 318255e72915d4cbddceb435e13d81601755714e9fSE Android policydb->ocontexts[OCON_NODE] = node; 319255e72915d4cbddceb435e13d81601755714e9fSE Android break; 320255e72915d4cbddceb435e13d81601755714e9fSE Android } 321255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_IP6: 322255e72915d4cbddceb435e13d81601755714e9fSE Android { 323255e72915d4cbddceb435e13d81601755714e9fSE Android /* Attach to context list */ 324255e72915d4cbddceb435e13d81601755714e9fSE Android node->next = policydb->ocontexts[OCON_NODE6]; 325255e72915d4cbddceb435e13d81601755714e9fSE Android policydb->ocontexts[OCON_NODE6] = node; 326255e72915d4cbddceb435e13d81601755714e9fSE Android break; 327255e72915d4cbddceb435e13d81601755714e9fSE Android } 328255e72915d4cbddceb435e13d81601755714e9fSE Android default: 329255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "unsupported protocol %u", proto); 330255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 331255e72915d4cbddceb435e13d81601755714e9fSE Android } 332255e72915d4cbddceb435e13d81601755714e9fSE Android 333255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 334255e72915d4cbddceb435e13d81601755714e9fSE Android 335255e72915d4cbddceb435e13d81601755714e9fSE Android err: 336255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not load node %s/%s (%s)", 337255e72915d4cbddceb435e13d81601755714e9fSE Android addr, mask, sepol_node_get_proto_str(proto)); 338255e72915d4cbddceb435e13d81601755714e9fSE Android if (node != NULL) { 339255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&node->context[0]); 340255e72915d4cbddceb435e13d81601755714e9fSE Android free(node); 341255e72915d4cbddceb435e13d81601755714e9fSE Android } 342255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 343255e72915d4cbddceb435e13d81601755714e9fSE Android} 344255e72915d4cbddceb435e13d81601755714e9fSE Android 345255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_node_iterate(sepol_handle_t * handle, 346255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, 347255e72915d4cbddceb435e13d81601755714e9fSE Android int (*fn) (const sepol_node_t * node, 348255e72915d4cbddceb435e13d81601755714e9fSE Android void *fn_arg), void *arg) 349255e72915d4cbddceb435e13d81601755714e9fSE Android{ 350255e72915d4cbddceb435e13d81601755714e9fSE Android 351255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 352255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *head; 353255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_node_t *node = NULL; 354255e72915d4cbddceb435e13d81601755714e9fSE Android int status; 355255e72915d4cbddceb435e13d81601755714e9fSE Android 356255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_NODE]; 357255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c; c = c->next) { 358255e72915d4cbddceb435e13d81601755714e9fSE Android if (node_to_record(handle, policydb, c, SEPOL_PROTO_IP4, &node) 359255e72915d4cbddceb435e13d81601755714e9fSE Android < 0) 360255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 361255e72915d4cbddceb435e13d81601755714e9fSE Android 362255e72915d4cbddceb435e13d81601755714e9fSE Android /* Invoke handler */ 363255e72915d4cbddceb435e13d81601755714e9fSE Android status = fn(node, arg); 364255e72915d4cbddceb435e13d81601755714e9fSE Android if (status < 0) 365255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 366255e72915d4cbddceb435e13d81601755714e9fSE Android 367255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_node_free(node); 368255e72915d4cbddceb435e13d81601755714e9fSE Android node = NULL; 369255e72915d4cbddceb435e13d81601755714e9fSE Android 370255e72915d4cbddceb435e13d81601755714e9fSE Android /* Handler requested exit */ 371255e72915d4cbddceb435e13d81601755714e9fSE Android if (status > 0) 372255e72915d4cbddceb435e13d81601755714e9fSE Android break; 373255e72915d4cbddceb435e13d81601755714e9fSE Android } 374255e72915d4cbddceb435e13d81601755714e9fSE Android 375255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_NODE6]; 376255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c; c = c->next) { 377255e72915d4cbddceb435e13d81601755714e9fSE Android if (node_to_record(handle, policydb, c, SEPOL_PROTO_IP6, &node) 378255e72915d4cbddceb435e13d81601755714e9fSE Android < 0) 379255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 380255e72915d4cbddceb435e13d81601755714e9fSE Android 381255e72915d4cbddceb435e13d81601755714e9fSE Android /* Invoke handler */ 382255e72915d4cbddceb435e13d81601755714e9fSE Android status = fn(node, arg); 383255e72915d4cbddceb435e13d81601755714e9fSE Android if (status < 0) 384255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 385255e72915d4cbddceb435e13d81601755714e9fSE Android 386255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_node_free(node); 387255e72915d4cbddceb435e13d81601755714e9fSE Android node = NULL; 388255e72915d4cbddceb435e13d81601755714e9fSE Android 389255e72915d4cbddceb435e13d81601755714e9fSE Android /* Handler requested exit */ 390255e72915d4cbddceb435e13d81601755714e9fSE Android if (status > 0) 391255e72915d4cbddceb435e13d81601755714e9fSE Android break; 392255e72915d4cbddceb435e13d81601755714e9fSE Android } 393255e72915d4cbddceb435e13d81601755714e9fSE Android 394255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 395255e72915d4cbddceb435e13d81601755714e9fSE Android 396255e72915d4cbddceb435e13d81601755714e9fSE Android err: 397255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not iterate over nodes"); 398255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_node_free(node); 399255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 400255e72915d4cbddceb435e13d81601755714e9fSE Android} 401