#include <stdio.h>

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

#include <sepol/policydb/policydb.h>

#ifndef __APPLE__
#include <stdio_ext.h>
#endif

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

#ifdef __APPLE__
	if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) {
	  ERR(NULL, "out of memory");
	  return -1;
	}

	while(fgets(buffer, 255, fp) != NULL) {
		nread = strlen(buffer);
#else
	size_t len = 0;
	__fsetlocking(fp, FSETLOCKING_BYCALLER);
	while ((nread = getline(&buffer, &len, fp)) > 0) {
#endif

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

			if (!id) {
				ERR(NULL, "out of memory");
				free(buffer);
				fclose(fp);
				return -1;
			}

			/* Adding a new user definition. */
			usrdatum = malloc(sizeof(user_datum_t));
			if (!usrdatum) {
				ERR(NULL, "out of memory");
				free(buffer);
				free(id);
				fclose(fp);
				return -1;
			}

			user_datum_init(usrdatum);
			usrdatum->s.value = ++policydb->p_users.nprim;
			if (hashtab_insert(policydb->p_users.table,
					   id, (hashtab_datum_t) usrdatum)) {
				ERR(NULL, "out of memory");
				free(buffer);
				free(id);
				user_datum_destroy(usrdatum);
				free(usrdatum);
				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 -- */
