/* Authors: Frank Mayer <mayerf@tresys.com>
 *   and Karl MacMillan <kmacmillan@tresys.com>
 *
 * Copyright (C) 2003,2010 Tresys Technology, LLC
 *
 *	This program is free software; you can redistribute it and/or
 *  	modify it under the terms of the GNU General Public License as
 *  	published by the Free Software Foundation, version 2.
 *
 * Adapted from dispol.c.
 *
 * This program is used by sepolgen-ifgen to get the access for all of
 * the attributes in the policy so that it can resolve the
 * typeattribute statements in the interfaces.
 *
 * It outputs the attribute access in a similar format to what sepolgen
 * uses to store interface vectors:
 *   [Attribute sandbox_x_domain]
 *   sandbox_x_domain,samba_var_t,file,ioctl,read,getattr,lock,open
 *   sandbox_x_domain,samba_var_t,dir,getattr,search,open
 *   sandbox_x_domain,initrc_var_run_t,file,ioctl,read,getattr,lock,open
 *
 */

#include <sepol/policydb/policydb.h>
#include <sepol/policydb/avtab.h>
#include <sepol/policydb/util.h>

#include <selinux/selinux.h>

#include <limits.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

struct val_to_name {
	unsigned int val;
	char *name;
};

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

static int render_access_mask(uint32_t av, avtab_key_t *key, policydb_t *policydbp,
		       FILE *fp)
{
	struct val_to_name v;
	class_datum_t *cladatum;
	char *perm = NULL;
	unsigned int i;
	int rc;
	uint32_t tclass = key->target_class;

	cladatum = policydbp->class_val_to_struct[tclass - 1];
	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) {
				fprintf(fp, ",%s", perm);
			}
		}
	}

	return 0;
}

static int render_key(avtab_key_t *key, policydb_t *p, FILE *fp)
{
	char *stype, *ttype, *tclass;
	stype = p->p_type_val_to_name[key->source_type - 1];
	ttype = p->p_type_val_to_name[key->target_type - 1];
	tclass = p->p_class_val_to_name[key->target_class - 1];
	if (stype && ttype) {
		fprintf(fp, "%s,%s,%s", stype, ttype, tclass);
	} else {
		fprintf(stderr, "error rendering key\n");
		exit(1);
	}

	return 0;
}

struct callback_data
{
	uint32_t attr;
	policydb_t *policy;
	FILE *fp;
};

static int output_avrule(avtab_key_t *key, avtab_datum_t *datum, void *args)
{
	struct callback_data *cb_data = (struct callback_data *)args;

	if (key->source_type != cb_data->attr)
		return 0;

	if (!(key->specified & AVTAB_AV && key->specified & AVTAB_ALLOWED))
		return 0;

	render_key(key, cb_data->policy, cb_data->fp);
	render_access_mask(datum->data, key, cb_data->policy, cb_data->fp);
	fprintf(cb_data->fp, "\n");

	return 0;
}

static int attribute_callback(hashtab_key_t key, hashtab_datum_t datum, void *datap)
{
	struct callback_data *cb_data = (struct callback_data *)datap;
	type_datum_t *t = (type_datum_t *)datum;

	if (t->flavor == TYPE_ATTRIB) {
		fprintf(cb_data->fp, "[Attribute %s]\n", key);
		cb_data->attr = t->s.value;
		if (avtab_map(&cb_data->policy->te_avtab, output_avrule, cb_data) < 0)
			return -1;
		if (avtab_map(&cb_data->policy->te_cond_avtab, output_avrule, cb_data) < 0)
			return -1;
	}

	return 0;
}

static policydb_t *load_policy(const char *filename)
{
	policydb_t *policydb;
	struct policy_file pf;
	FILE *fp;
	char pathname[PATH_MAX];
	int suffix_ver;
	int ret;

	/* no explicit policy name given, try loaded policy on a SELinux enabled system */
	if (!filename) {
		filename = selinux_current_policy_path();
	}

	/*
	 * Fallback to default store paths with version suffixes,
	 * starting from the maximum supported policy version.
	 */
	if (!filename) {
		for (suffix_ver = sepol_policy_kern_vers_max(); suffix_ver > 0; suffix_ver--) {
			snprintf(pathname, sizeof(pathname), "%s.%d", selinux_binary_policy_path(), suffix_ver);

			if (access(pathname, F_OK) == 0) {
				filename = pathname;
				break;
			}
		}

		if (!filename) {
			fprintf(stderr, "Can't find any policy at '%s'\n",
				selinux_binary_policy_path());
			return NULL;
		}
	}

	fp = fopen(filename, "r");
	if (fp == NULL) {
		fprintf(stderr, "Can't open '%s':  %s\n",
			filename, strerror(errno));
		return NULL;
	}

	policy_file_init(&pf);
	pf.type = PF_USE_STDIO;
	pf.fp = fp;

	policydb = malloc(sizeof(policydb_t));
	if (policydb == NULL) {
		fprintf(stderr, "Out of memory!\n");
		fclose(fp);
		return NULL;
	}

	if (policydb_init(policydb)) {
		fprintf(stderr, "Out of memory!\n");
		free(policydb);
		fclose(fp);
		return NULL;
	}

	ret = policydb_read(policydb, &pf, 1);
	if (ret) {
		fprintf(stderr,
			"error(s) encountered while parsing configuration\n");
		free(policydb);
		fclose(fp);
		return NULL;
	}

	fclose(fp);

	return policydb;

}

static void usage(char *progname)
{
	printf("usage: %s out_file [policy_file]\n", progname);
}

int main(int argc, char **argv)
{
	policydb_t *p;
	struct callback_data cb_data;
	FILE *fp;

	if (argc != 2 && argc != 3) {
		usage(argv[0]);
		return -1;
	}

	/* Open the policy. */
	p = load_policy(argv[2]);
	if (p == NULL)
		return -1;

	/* Open the output policy. */
	fp = fopen(argv[1], "w");
	if (fp == NULL) {
		fprintf(stderr, "error opening output file\n");
		policydb_destroy(p);
		free(p);
		return -1;
	}

	/* Find all of the attributes and output their access. */
	cb_data.policy = p;
	cb_data.fp = fp;

	if (hashtab_map(p->p_types.table, attribute_callback, &cb_data)) {
		printf("error finding attributes\n");
	}

	policydb_destroy(p);
	free(p);
	fclose(fp);

	return 0;
}
