#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>

#include <sepol/policydb/policydb.h>
#include <stdarg.h>

#include "debug.h"
#include "private.h"
#include "dso.h"
#include "mls.h"

/* -- Deprecated -- */

void sepol_set_delusers(int on __attribute((unused)))
{
	WARN(NULL, "Deprecated interface");
}

#undef BADLINE
#define BADLINE() { \
	ERR(NULL, "invalid entry %s (%s:%u)", \
		buffer, path, lineno); \
	continue; \
}

static int load_users(struct policydb *policydb, const char *path)
{
	FILE *fp;
	char *buffer = NULL, *p, *q, oldc;
	size_t len = 0;
	ssize_t nread;
	unsigned lineno = 0, islist = 0, bit;
	user_datum_t *usrdatum;
	role_datum_t *roldatum;
	ebitmap_node_t *rnode;

	fp = fopen(path, "r");
	if (fp == NULL)
		return -1;
	__fsetlocking(fp, FSETLOCKING_BYCALLER);

	while ((nread = getline(&buffer, &len, fp)) > 0) {
		lineno++;
		if (buffer[nread - 1] == '\n')
			buffer[nread - 1] = 0;
		p = buffer;
		while (*p && isspace(*p))
			p++;
		if (!(*p) || *p == '#')
			continue;

		if (strncasecmp(p, "user", 4))
			BADLINE();
		p += 4;
		if (!isspace(*p))
			BADLINE();
		while (*p && isspace(*p))
			p++;
		if (!(*p))
			BADLINE();
		q = p;
		while (*p && !isspace(*p))
			p++;
		if (!(*p))
			BADLINE();
		*p++ = 0;

		usrdatum = hashtab_search(policydb->p_users.table, q);
		if (usrdatum) {
			/* Replacing an existing user definition. */
			ebitmap_destroy(&usrdatum->roles.roles);
			ebitmap_init(&usrdatum->roles.roles);
		} else {
			char *id = strdup(q);

			/* Adding a new user definition. */
			usrdatum =
			    (user_datum_t *) malloc(sizeof(user_datum_t));
			if (!id || !usrdatum) {
				ERR(NULL, "out of memory");
				free(buffer);
				fclose(fp);
				return -1;
			}
			memset(usrdatum, 0, sizeof(user_datum_t));
			usrdatum->s.value = ++policydb->p_users.nprim;
			ebitmap_init(&usrdatum->roles.roles);
			if (hashtab_insert(policydb->p_users.table,
					   id, (hashtab_datum_t) usrdatum)) {
				ERR(NULL, "out of memory");
				free(buffer);
				fclose(fp);
				return -1;
			}
		}

		while (*p && isspace(*p))
			p++;
		if (!(*p))
			BADLINE();
		if (strncasecmp(p, "roles", 5))
			BADLINE();
		p += 5;
		if (!isspace(*p))
			BADLINE();
		while (*p && isspace(*p))
			p++;
		if (!(*p))
			BADLINE();
		if (*p == '{') {
			islist = 1;
			p++;
		} else
			islist = 0;

		oldc = 0;
		do {
			while (*p && isspace(*p))
				p++;
			if (!(*p))
				break;

			q = p;
			while (*p && *p != ';' && *p != '}' && !isspace(*p))
				p++;
			if (!(*p))
				break;
			if (*p == '}')
				islist = 0;
			oldc = *p;
			*p++ = 0;
			if (!q[0])
				break;

			roldatum = hashtab_search(policydb->p_roles.table, q);
			if (!roldatum) {
				ERR(NULL, "undefined role %s (%s:%u)",
				    q, path, lineno);
				continue;
			}
			/* Set the role and every role it dominates */
			ebitmap_for_each_bit(&roldatum->dominates, rnode, bit) {
				if (ebitmap_node_get_bit(rnode, bit))
					if (ebitmap_set_bit
					    (&usrdatum->roles.roles, bit, 1)) {
						ERR(NULL, "out of memory");
						free(buffer);
						fclose(fp);
						return -1;
					}
			}
		} while (islist);
		if (oldc == 0)
			BADLINE();

		if (policydb->mls) {
			context_struct_t context;
			char *scontext, *r, *s;

			while (*p && isspace(*p))
				p++;
			if (!(*p))
				BADLINE();
			if (strncasecmp(p, "level", 5))
				BADLINE();
			p += 5;
			if (!isspace(*p))
				BADLINE();
			while (*p && isspace(*p))
				p++;
			if (!(*p))
				BADLINE();
			q = p;
			while (*p && strncasecmp(p, "range", 5))
				p++;
			if (!(*p))
				BADLINE();
			*--p = 0;
			p++;

			scontext = malloc(p - q);
			if (!scontext) {
				ERR(NULL, "out of memory");
				free(buffer);
				fclose(fp);
				return -1;
			}
			r = scontext;
			s = q;
			while (*s) {
				if (!isspace(*s))
					*r++ = *s;
				s++;
			}
			*r = 0;
			r = scontext;

			context_init(&context);
			if (mls_context_to_sid(policydb, oldc, &r, &context) <
			    0) {
				ERR(NULL, "invalid level %s (%s:%u)", scontext,
				    path, lineno);
				free(scontext);
				continue;

			}
			free(scontext);
			memcpy(&usrdatum->dfltlevel, &context.range.level[0],
			       sizeof(usrdatum->dfltlevel));

			if (strncasecmp(p, "range", 5))
				BADLINE();
			p += 5;
			if (!isspace(*p))
				BADLINE();
			while (*p && isspace(*p))
				p++;
			if (!(*p))
				BADLINE();
			q = p;
			while (*p && *p != ';')
				p++;
			if (!(*p))
				BADLINE();
			*p++ = 0;

			scontext = malloc(p - q);
			if (!scontext) {
				ERR(NULL, "out of memory");
				free(buffer);
				fclose(fp);
				return -1;
			}
			r = scontext;
			s = q;
			while (*s) {
				if (!isspace(*s))
					*r++ = *s;
				s++;
			}
			*r = 0;
			r = scontext;

			context_init(&context);
			if (mls_context_to_sid(policydb, oldc, &r, &context) <
			    0) {
				ERR(NULL, "invalid range %s (%s:%u)", scontext,
				    path, lineno);
				free(scontext);
				continue;
			}
			free(scontext);
			memcpy(&usrdatum->range, &context.range,
			       sizeof(usrdatum->range));
		}
	}

	free(buffer);
	fclose(fp);
	return 0;
}

int sepol_genusers(void *data, size_t len,
		   const char *usersdir, void **newdata, size_t * newlen)
{
	struct policydb policydb;
	char path[PATH_MAX];

	/* Construct policy database */
	if (policydb_init(&policydb))
		goto err;
	if (policydb_from_image(NULL, data, len, &policydb) < 0)
		goto err;

	/* Load locally defined users. */
	snprintf(path, sizeof path, "%s/local.users", usersdir);
	if (load_users(&policydb, path) < 0)
		goto err_destroy;

	/* Write policy database */
	if (policydb_to_image(NULL, &policydb, newdata, newlen) < 0)
		goto err_destroy;

	policydb_destroy(&policydb);
	return 0;

      err_destroy:
	policydb_destroy(&policydb);

      err:
	return -1;
}

int hidden sepol_genusers_policydb(policydb_t * policydb, const char *usersdir)
{
	char path[PATH_MAX];

	/* Load locally defined users. */
	snprintf(path, sizeof path, "%s/local.users", usersdir);
	if (load_users(policydb, path) < 0) {
		ERR(NULL, "unable to load local.users: %s", strerror(errno));
		return -1;
	}

	if (policydb_reindex_users(policydb) < 0) {
		ERR(NULL, "unable to reindex users: %s", strerror(errno));
		return -1;

	}

	return 0;
}

/* -- End Deprecated -- */
