| /* Authors: Joshua Brindle <jbrindle@tresys.com> |
| * Jason Tang <jtang@tresys.com> |
| * |
| * Copyright (C) 2005-2006 Tresys Technology, LLC |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| #include <assert.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| #include <sepol/policydb/flask_types.h> |
| #include <sepol/policydb/policydb.h> |
| |
| struct val_to_name { |
| unsigned int val; |
| char *name; |
| }; |
| |
| /* Add an unsigned integer to a dynamically reallocated array. *cnt |
| * is a reference pointer to the number of values already within array |
| * *a; it will be incremented upon successfully appending i. If *a is |
| * NULL then this function will create a new array (*cnt is reset to |
| * 0). Return 0 on success, -1 on out of memory. */ |
| int add_i_to_a(uint32_t i, uint32_t * cnt, uint32_t ** a) |
| { |
| if (cnt == NULL || a == NULL) |
| return -1; |
| |
| /* FIX ME: This is not very elegant! We use an array that we |
| * grow as new uint32_t are added to an array. But rather |
| * than be smart about it, for now we realloc() the array each |
| * time a new uint32_t is added! */ |
| if (*a != NULL) |
| *a = (uint32_t *) realloc(*a, (*cnt + 1) * sizeof(uint32_t)); |
| else { /* empty list */ |
| |
| *cnt = 0; |
| *a = (uint32_t *) malloc(sizeof(uint32_t)); |
| } |
| if (*a == NULL) { |
| return -1; |
| } |
| (*a)[*cnt] = i; |
| (*cnt)++; |
| return 0; |
| } |
| |
| static int perm_name(hashtab_key_t key, hashtab_datum_t datum, void *data) |
| { |
| struct val_to_name *v = data; |
| perm_datum_t *perdatum; |
| |
| perdatum = (perm_datum_t *) datum; |
| |
| if (v->val == perdatum->s.value) { |
| v->name = key; |
| return 1; |
| } |
| |
| return 0; |
| } |
| |
| char *sepol_av_to_string(policydb_t * policydbp, uint32_t tclass, |
| sepol_access_vector_t av) |
| { |
| struct val_to_name v; |
| static char avbuf[1024]; |
| class_datum_t *cladatum; |
| char *perm = NULL, *p; |
| unsigned int i; |
| int rc; |
| int avlen = 0, len; |
| |
| cladatum = policydbp->class_val_to_struct[tclass - 1]; |
| p = avbuf; |
| for (i = 0; i < cladatum->permissions.nprim; i++) { |
| if (av & (1 << i)) { |
| v.val = i + 1; |
| rc = hashtab_map(cladatum->permissions.table, |
| perm_name, &v); |
| if (!rc && cladatum->comdatum) { |
| rc = hashtab_map(cladatum->comdatum-> |
| permissions.table, perm_name, |
| &v); |
| } |
| if (rc) |
| perm = v.name; |
| if (perm) { |
| len = |
| snprintf(p, sizeof(avbuf) - avlen, " %s", |
| perm); |
| if (len < 0 |
| || (size_t) len >= (sizeof(avbuf) - avlen)) |
| return NULL; |
| p += len; |
| avlen += len; |
| } |
| } |
| } |
| |
| return avbuf; |
| } |