Home | History | Annotate | Download | only in src
      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