/* 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; }