/* Authors: Jason Tang <jtang@tresys.com>
 *
 * Functions that manipulate a logical block (conditional, optional,
 * or global scope) for a policy module.
 *
 * Copyright (C) 2005 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 <sepol/policydb/policydb.h>
#include <sepol/policydb/conditional.h>
#include <sepol/policydb/avrule_block.h>

#include <assert.h>
#include <stdlib.h>

/* It is anticipated that there be less declarations within an avrule
 * block than the global policy.  Thus the symbol table sizes are
 * smaller than those listed in policydb.c */
static unsigned int symtab_sizes[SYM_NUM] = {
	2,
	4,
	8,
	32,
	16,
	4,
	2,
	2,
};

avrule_block_t *avrule_block_create(void)
{
	avrule_block_t *block;
	if ((block = calloc(1, sizeof(*block))) == NULL) {
		return NULL;
	}
	return block;
}

avrule_decl_t *avrule_decl_create(uint32_t decl_id)
{
	avrule_decl_t *decl;
	int i;
	if ((decl = calloc(1, sizeof(*decl))) == NULL) {
		return NULL;
	}
	decl->decl_id = decl_id;
	for (i = 0; i < SYM_NUM; i++) {
		if (symtab_init(&decl->symtab[i], symtab_sizes[i])) {
			avrule_decl_destroy(decl);
			free(decl);
			return NULL;
		}
	}

	for (i = 0; i < SYM_NUM; i++) {
		ebitmap_init(&decl->required.scope[i]);
		ebitmap_init(&decl->declared.scope[i]);
	}
	return decl;
}

/* note that unlike the other destroy functions, this one does /NOT/
 * destroy the pointer itself */
static void scope_index_destroy(scope_index_t * scope)
{
	unsigned int i;
	if (scope == NULL) {
		return;
	}
	for (i = 0; i < SYM_NUM; i++) {
		ebitmap_destroy(scope->scope + i);
	}
	for (i = 0; i < scope->class_perms_len; i++) {
		ebitmap_destroy(scope->class_perms_map + i);
	}
	free(scope->class_perms_map);
}

void avrule_decl_destroy(avrule_decl_t * x)
{
	if (x == NULL) {
		return;
	}
	cond_list_destroy(x->cond_list);
	avrule_list_destroy(x->avrules);
	role_trans_rule_list_destroy(x->role_tr_rules);
	filename_trans_rule_list_destroy(x->filename_trans_rules);
	role_allow_rule_list_destroy(x->role_allow_rules);
	range_trans_rule_list_destroy(x->range_tr_rules);
	scope_index_destroy(&x->required);
	scope_index_destroy(&x->declared);
	symtabs_destroy(x->symtab);
	free(x->module_name);
	free(x);
}

void avrule_block_destroy(avrule_block_t * x)
{
	avrule_decl_t *decl;
	if (x == NULL) {
		return;
	}
	decl = x->branch_list;
	while (decl != NULL) {
		avrule_decl_t *next_decl = decl->next;
		avrule_decl_destroy(decl);
		decl = next_decl;
	}
	free(x);
}

void avrule_block_list_destroy(avrule_block_t * x)
{
	while (x != NULL) {
		avrule_block_t *next = x->next;
		avrule_block_destroy(x);
		x = next;
	}
}

/* Get a conditional node from a avrule_decl with the same expression.
 * If that expression does not exist then create one. */
cond_list_t *get_decl_cond_list(policydb_t * p, avrule_decl_t * decl,
				cond_list_t * cond)
{
	cond_list_t *result;
	int was_created;
	result = cond_node_find(p, cond, decl->cond_list, &was_created);
	if (result != NULL && was_created) {
		result->next = decl->cond_list;
		decl->cond_list = result;
	}
	return result;
}

/* Look up an identifier in a policy's scoping table.  If it is there,
 * marked as SCOPE_DECL, and any of its declaring block has been enabled,
 * then return 1.  Otherwise return 0. Can only be called after the 
 * decl_val_to_struct index has been created */
int is_id_enabled(char *id, policydb_t * p, int symbol_table)
{
	scope_datum_t *scope =
	    (scope_datum_t *) hashtab_search(p->scope[symbol_table].table, id);
	uint32_t i;
	if (scope == NULL) {
		return 0;
	}
	if (scope->scope != SCOPE_DECL) {
		return 0;
	}
	for (i = 0; i < scope->decl_ids_len; i++) {
		avrule_decl_t *decl =
		    p->decl_val_to_struct[scope->decl_ids[i] - 1];
		if (decl != NULL && decl->enabled) {
			return 1;
		}
	}
	return 0;
}

/* Check if a particular permission is present within the given class,
 * and that the class is enabled.  Returns 1 if both conditions are
 * true, 0 if neither could be found or if the class id disabled. */
int is_perm_enabled(char *class_id, char *perm_id, policydb_t * p)
{
	class_datum_t *cladatum;
	perm_datum_t *perm;
	if (!is_id_enabled(class_id, p, SYM_CLASSES)) {
		return 0;
	}
	cladatum =
	    (class_datum_t *) hashtab_search(p->p_classes.table, class_id);
	if (cladatum == NULL) {
		return 0;
	}
	perm = hashtab_search(cladatum->permissions.table, perm_id);
	if (perm == NULL && cladatum->comdatum != 0) {
		/* permission was not in this class.  before giving
		 * up, check the class's parent */
		perm =
		    hashtab_search(cladatum->comdatum->permissions.table,
				   perm_id);
	}
	if (perm == NULL) {
		return 0;
	}
	return 1;
}
