1 /* Authors: Joshua Brindle <jbrindle (at) tresys.com> 2 * Jason Tang <jtang (at) tresys.com> 3 * 4 * Copyright (C) 2005-2006 Tresys Technology, LLC 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include <assert.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 25 #include <sepol/policydb/flask_types.h> 26 #include <sepol/policydb/policydb.h> 27 28 struct val_to_name { 29 unsigned int val; 30 char *name; 31 }; 32 33 /* Add an unsigned integer to a dynamically reallocated array. *cnt 34 * is a reference pointer to the number of values already within array 35 * *a; it will be incremented upon successfully appending i. If *a is 36 * NULL then this function will create a new array (*cnt is reset to 37 * 0). Return 0 on success, -1 on out of memory. */ 38 int add_i_to_a(uint32_t i, uint32_t * cnt, uint32_t ** a) 39 { 40 if (cnt == NULL || a == NULL) 41 return -1; 42 43 /* FIX ME: This is not very elegant! We use an array that we 44 * grow as new uint32_t are added to an array. But rather 45 * than be smart about it, for now we realloc() the array each 46 * time a new uint32_t is added! */ 47 if (*a != NULL) 48 *a = (uint32_t *) realloc(*a, (*cnt + 1) * sizeof(uint32_t)); 49 else { /* empty list */ 50 51 *cnt = 0; 52 *a = (uint32_t *) malloc(sizeof(uint32_t)); 53 } 54 if (*a == NULL) { 55 return -1; 56 } 57 (*a)[*cnt] = i; 58 (*cnt)++; 59 return 0; 60 } 61 62 static int perm_name(hashtab_key_t key, hashtab_datum_t datum, void *data) 63 { 64 struct val_to_name *v = data; 65 perm_datum_t *perdatum; 66 67 perdatum = (perm_datum_t *) datum; 68 69 if (v->val == perdatum->s.value) { 70 v->name = key; 71 return 1; 72 } 73 74 return 0; 75 } 76 77 char *sepol_av_to_string(policydb_t * policydbp, uint32_t tclass, 78 sepol_access_vector_t av) 79 { 80 struct val_to_name v; 81 static char avbuf[1024]; 82 class_datum_t *cladatum; 83 char *perm = NULL, *p; 84 unsigned int i; 85 int rc; 86 int avlen = 0, len; 87 88 cladatum = policydbp->class_val_to_struct[tclass - 1]; 89 p = avbuf; 90 for (i = 0; i < cladatum->permissions.nprim; i++) { 91 if (av & (1 << i)) { 92 v.val = i + 1; 93 rc = hashtab_map(cladatum->permissions.table, 94 perm_name, &v); 95 if (!rc && cladatum->comdatum) { 96 rc = hashtab_map(cladatum->comdatum-> 97 permissions.table, perm_name, 98 &v); 99 } 100 if (rc) 101 perm = v.name; 102 if (perm) { 103 len = 104 snprintf(p, sizeof(avbuf) - avlen, " %s", 105 perm); 106 if (len < 0 107 || (size_t) len >= (sizeof(avbuf) - avlen)) 108 return NULL; 109 p += len; 110 avlen += len; 111 } 112 } 113 } 114 115 return avbuf; 116 } 117