/* Copyright (C) 2005 Red Hat, Inc. */

#include <stdlib.h>
#include "policy.h"
#include "handle.h"
#include "database.h"
#include "modules.h"
#include "debug.h"

/* Powers of two only */
#define MODE_SET    1
#define MODE_MODIFY 2
#define MODE_SORT   4

static int clear_obsolete(semanage_handle_t * handle,
			  record_t ** records,
			  unsigned int nrecords,
			  dbase_config_t * src, dbase_config_t * dst)
{

	record_key_t *key = NULL;
	unsigned int i;

	dbase_table_t *src_dtable = src->dtable;
	dbase_table_t *dst_dtable = dst->dtable;
	record_table_t *rtable = src_dtable->get_rtable(src->dbase);

	for (i = 0; i < nrecords; i++) {
		int exists;

		if (rtable->key_extract(handle, records[i], &key) < 0)
			goto err;

		if (dst_dtable->exists(handle, dst->dbase, key, &exists) < 0)
			goto err;

		if (!exists) {
			if (src_dtable->del(handle, src->dbase, key) < 0)
				goto err;

			rtable->free(records[i]);
			records[i] = NULL;

			/* FIXME: notice to user */
			/* INFO(handle, "boolean %s is obsolete, unsetting configured value..."); */
		}

		rtable->key_free(key);
	}

	return STATUS_SUCCESS;

      err:
	/* FIXME: handle error */
	rtable->key_free(key);
	return STATUS_ERR;
}

static int load_records(semanage_handle_t * handle,
			dbase_config_t * dst,
			record_t ** records, unsigned int nrecords, int mode)
{

	unsigned int i;
	record_key_t *rkey = NULL;

	dbase_t *dbase = dst->dbase;
	dbase_table_t *dtable = dst->dtable;
	record_table_t *rtable = dtable->get_rtable(dbase);

	for (i = 0; i < nrecords; i++) {

		/* Possibly obsoleted */
		if (!records[i])
			continue;

		if (rtable->key_extract(handle, records[i], &rkey) < 0)
			goto err;

		if (mode & MODE_SET &&
		    dtable->set(handle, dbase, rkey, records[i]) < 0)
			goto err;

		else if (mode & MODE_MODIFY &&
			 dtable->modify(handle, dbase, rkey, records[i]) < 0)
			goto err;

		rtable->key_free(rkey);
	}

	return STATUS_SUCCESS;

      err:
	/* FIXME: handle error */
	rtable->key_free(rkey);
	return STATUS_ERR;
}

typedef struct load_table {
	dbase_config_t *src;
	dbase_config_t *dst;
	int mode;
} load_table_t;

/* This function must be called AFTER all modules are loaded.
 * Modules could be represented as a database, in which case
 * they should be loaded at the beginning of this function */

int semanage_base_merge_components(semanage_handle_t * handle)
{

	unsigned int i, j;
	int rc = STATUS_SUCCESS;

	/* Order is important here - change things carefully.
	 * System components first, local next. Verify runs with 
	 * mutual dependencies are ran after everything is merged */
	load_table_t components[] = {

		{semanage_user_base_dbase_local(handle),
		 semanage_user_base_dbase_policy(handle), MODE_MODIFY},

		{semanage_user_extra_dbase_local(handle),
		 semanage_user_extra_dbase_policy(handle), MODE_MODIFY},

		{semanage_port_dbase_local(handle),
		 semanage_port_dbase_policy(handle), MODE_MODIFY},

		{semanage_iface_dbase_local(handle),
		 semanage_iface_dbase_policy(handle), MODE_MODIFY},

		{semanage_bool_dbase_local(handle),
		 semanage_bool_dbase_policy(handle), MODE_SET},

		{semanage_seuser_dbase_local(handle),
		 semanage_seuser_dbase_policy(handle), MODE_MODIFY},

		{semanage_node_dbase_local(handle),
		 semanage_node_dbase_policy(handle), MODE_MODIFY | MODE_SORT},
	};
	const unsigned int CCOUNT = sizeof(components) / sizeof(components[0]);

	/* Merge components into policy (and validate) */
	for (i = 0; i < CCOUNT; i++) {

		record_t **records = NULL;
		unsigned int nrecords = 0;

		dbase_config_t *src = components[i].src;
		dbase_config_t *dst = components[i].dst;
		int mode = components[i].mode;
		record_table_t *rtable = src->dtable->get_rtable(src->dbase);

		/* Must invoke cache function first */
		if (src->dtable->cache(handle, src->dbase) < 0)
			goto err;
		if (dst->dtable->cache(handle, dst->dbase) < 0)
			goto err;

		/* List all records */
		if (src->dtable->list(handle, src->dbase,
				      &records, &nrecords) < 0)
			goto err;

		/* Sort records on MODE_SORT */
		if (mode & MODE_SORT) {
			qsort(records, nrecords, sizeof(record_t *),
			      (int (*)(const void *, const void *))rtable->
			      compare2_qsort);
		}

		/* Clear obsolete ones for MODE_SET */
		if (mode & MODE_SET &&
		    clear_obsolete(handle, records, nrecords, src, dst) < 0) {
			rc = STATUS_ERR;
			goto dbase_exit;
		}

		/* Load records */
		if (load_records(handle, dst, records, nrecords, mode) < 0) {

			rc = STATUS_ERR;
			goto dbase_exit;
		}

		/* Cleanup */
	      dbase_exit:
		for (j = 0; j < nrecords; j++)
			rtable->free(records[j]);
		free(records);

		/* Abort on error */
		if (rc < 0)
			goto err;
	}

	return rc;

      err:
	ERR(handle, "could not merge local modifications into policy");
	return STATUS_ERR;
}

int semanage_commit_components(semanage_handle_t * handle)
{

	int i;
	dbase_config_t *components[] = {
		semanage_iface_dbase_local(handle),
		semanage_bool_dbase_local(handle),
		semanage_user_base_dbase_local(handle),
		semanage_user_extra_dbase_local(handle),
		semanage_user_extra_dbase_policy(handle),
		semanage_port_dbase_local(handle),
		semanage_fcontext_dbase_local(handle),
		semanage_fcontext_dbase_policy(handle),
		semanage_seuser_dbase_local(handle),
		semanage_seuser_dbase_policy(handle),
		semanage_bool_dbase_active(handle),
		semanage_node_dbase_local(handle),
	};
	const int CCOUNT = sizeof(components) / sizeof(components[0]);

	for (i = 0; i < CCOUNT; i++) {
		/* Flush to disk */
		if (components[i]->dtable->flush(handle, components[i]->dbase) <
		    0)
			goto err;
	}

	return STATUS_SUCCESS;

      err:
	ERR(handle, "could not commit local/active modifications");

	for (i = 0; i < CCOUNT; i++)
		components[i]->dtable->drop_cache(components[i]->dbase);
	return STATUS_ERR;
}
