#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <pwd.h>
#include "selinux_internal.h"
#include "context_internal.h"
#include "get_context_list_internal.h"

int get_default_context_with_role(const char *user,
				  const char *role,
				  char * fromcon,
				  char ** newcon)
{
	char **conary;
	char **ptr;
	context_t con;
	const char *role2;
	int rc;

	rc = get_ordered_context_list(user, fromcon, &conary);
	if (rc <= 0)
		return -1;

	for (ptr = conary; *ptr; ptr++) {
		con = context_new(*ptr);
		if (!con)
			continue;
		role2 = context_role_get(con);
		if (role2 && !strcmp(role, role2)) {
			context_free(con);
			break;
		}
		context_free(con);
	}

	rc = -1;
	if (!(*ptr)) {
		errno = EINVAL;
		goto out;
	}
	*newcon = strdup(*ptr);
	if (!(*newcon))
		goto out;
	rc = 0;
      out:
	freeconary(conary);
	return rc;
}

hidden_def(get_default_context_with_role)

int get_default_context_with_rolelevel(const char *user,
				       const char *role,
				       const char *level,
				       char * fromcon,
				       char ** newcon)
{

	int rc = 0;
	int freefrom = 0;
	context_t con;
	char *newfromcon;
	if (!level)
		return get_default_context_with_role(user, role, fromcon,
						     newcon);

	if (!fromcon) {
		rc = getcon(&fromcon);
		if (rc < 0)
			return rc;
		freefrom = 1;
	}

	rc = -1;
	con = context_new(fromcon);
	if (!con)
		goto out;

	if (context_range_set(con, level))
		goto out;

	newfromcon = context_str(con);
	if (!newfromcon)
		goto out;

	rc = get_default_context_with_role(user, role, newfromcon, newcon);

      out:
	context_free(con);
	if (freefrom)
		freecon(fromcon);
	return rc;

}

int get_default_context(const char *user,
			char * fromcon, char ** newcon)
{
	char **conary;
	int rc;

	rc = get_ordered_context_list(user, fromcon, &conary);
	if (rc <= 0)
		return -1;

	*newcon = strdup(conary[0]);
	freeconary(conary);
	if (!(*newcon))
		return -1;
	return 0;
}

static int find_partialcon(char ** list,
			   unsigned int nreach, char *part)
{
	const char *conrole, *contype;
	char *partrole, *parttype, *ptr;
	context_t con;
	unsigned int i;

	partrole = part;
	ptr = part;
	while (*ptr && !isspace(*ptr) && *ptr != ':')
		ptr++;
	if (*ptr != ':')
		return -1;
	*ptr++ = 0;
	parttype = ptr;
	while (*ptr && !isspace(*ptr) && *ptr != ':')
		ptr++;
	*ptr = 0;

	for (i = 0; i < nreach; i++) {
		con = context_new(list[i]);
		if (!con)
			return -1;
		conrole = context_role_get(con);
		contype = context_type_get(con);
		if (!conrole || !contype) {
			context_free(con);
			return -1;
		}
		if (!strcmp(conrole, partrole) && !strcmp(contype, parttype)) {
			context_free(con);
			return i;
		}
		context_free(con);
	}

	return -1;
}

static int get_context_order(FILE * fp,
			     char * fromcon,
			     char ** reachable,
			     unsigned int nreach,
			     unsigned int *ordering, unsigned int *nordered)
{
	char *start, *end = NULL;
	char *line = NULL;
	size_t line_len = 0;
	ssize_t len;
	int found = 0;
	const char *fromrole, *fromtype;
	char *linerole, *linetype;
	unsigned int i;
	context_t con;
	int rc;

	errno = -EINVAL;

	/* Extract the role and type of the fromcon for matching.
	   User identity and MLS range can be variable. */
	con = context_new(fromcon);
	if (!con)
		return -1;
	fromrole = context_role_get(con);
	fromtype = context_type_get(con);
	if (!fromrole || !fromtype) {
		context_free(con);
		return -1;
	}

	while ((len = getline(&line, &line_len, fp)) > 0) {
		if (line[len - 1] == '\n')
			line[len - 1] = 0;

		/* Skip leading whitespace. */
		start = line;
		while (*start && isspace(*start))
			start++;
		if (!(*start))
			continue;

		/* Find the end of the (partial) fromcon in the line. */
		end = start;
		while (*end && !isspace(*end))
			end++;
		if (!(*end))
			continue;

		/* Check for a match. */
		linerole = start;
		while (*start && !isspace(*start) && *start != ':')
			start++;
		if (*start != ':')
			continue;
		*start = 0;
		linetype = ++start;
		while (*start && !isspace(*start) && *start != ':')
			start++;
		if (!(*start))
			continue;
		*start = 0;
		if (!strcmp(fromrole, linerole) && !strcmp(fromtype, linetype)) {
			found = 1;
			break;
		}
	}

	if (!found) {
		errno = ENOENT;
		rc = -1;
		goto out;
	}

	start = ++end;
	while (*start) {
		/* Skip leading whitespace */
		while (*start && isspace(*start))
			start++;
		if (!(*start))
			break;

		/* Find the end of this partial context. */
		end = start;
		while (*end && !isspace(*end))
			end++;
		if (*end)
			*end++ = 0;

		/* Check for a match in the reachable list. */
		rc = find_partialcon(reachable, nreach, start);
		if (rc < 0) {
			/* No match, skip it. */
			start = end;
			continue;
		}

		/* If a match is found and the entry is not already ordered
		   (e.g. due to prior match in prior config file), then set
		   the ordering for it. */
		i = rc;
		if (ordering[i] == nreach)
			ordering[i] = (*nordered)++;
		start = end;
	}

	rc = 0;

      out:
	context_free(con);
	free(line);
	return rc;
}

static int get_failsafe_context(const char *user, char ** newcon)
{
	FILE *fp;
	char buf[255], *ptr;
	size_t plen, nlen;
	int rc;

	fp = fopen(selinux_failsafe_context_path(), "re");
	if (!fp)
		return -1;

	ptr = fgets_unlocked(buf, sizeof buf, fp);
	fclose(fp);

	if (!ptr)
		return -1;
	plen = strlen(ptr);
	if (buf[plen - 1] == '\n')
		buf[plen - 1] = 0;

	nlen = strlen(user) + 1 + plen + 1;
	*newcon = malloc(nlen);
	if (!(*newcon))
		return -1;
	rc = snprintf(*newcon, nlen, "%s:%s", user, ptr);
	if (rc < 0 || (size_t) rc >= nlen) {
		free(*newcon);
		*newcon = 0;
		return -1;
	}

	/* If possible, check the context to catch
	   errors early rather than waiting until the
	   caller tries to use setexeccon on the context.
	   But this may not always be possible, e.g. if
	   selinuxfs isn't mounted. */
	if (security_check_context(*newcon) && errno != ENOENT) {
		free(*newcon);
		*newcon = 0;
		return -1;
	}

	return 0;
}

struct context_order {
	char * con;
	unsigned int order;
};

static int order_compare(const void *A, const void *B)
{
	const struct context_order *c1 = A, *c2 = B;
	if (c1->order < c2->order)
		return -1;
	else if (c1->order > c2->order)
		return 1;
	return strcmp(c1->con, c2->con);
}

int get_ordered_context_list_with_level(const char *user,
					const char *level,
					char * fromcon,
					char *** list)
{
	int rc;
	int freefrom = 0;
	context_t con;
	char *newfromcon;

	if (!level)
		return get_ordered_context_list(user, fromcon, list);

	if (!fromcon) {
		rc = getcon(&fromcon);
		if (rc < 0)
			return rc;
		freefrom = 1;
	}

	rc = -1;
	con = context_new(fromcon);
	if (!con)
		goto out;

	if (context_range_set(con, level))
		goto out;

	newfromcon = context_str(con);
	if (!newfromcon)
		goto out;

	rc = get_ordered_context_list(user, newfromcon, list);

      out:
	context_free(con);
	if (freefrom)
		freecon(fromcon);
	return rc;
}

hidden_def(get_ordered_context_list_with_level)

int get_default_context_with_level(const char *user,
				   const char *level,
				   char * fromcon,
				   char ** newcon)
{
	char **conary;
	int rc;

	rc = get_ordered_context_list_with_level(user, level, fromcon, &conary);
	if (rc <= 0)
		return -1;

	*newcon = strdup(conary[0]);
	freeconary(conary);
	if (!(*newcon))
		return -1;
	return 0;
}

int get_ordered_context_list(const char *user,
			     char * fromcon,
			     char *** list)
{
	char **reachable = NULL;
	unsigned int *ordering = NULL;
	struct context_order *co = NULL;
	char **ptr;
	int rc = 0;
	unsigned int nreach = 0, nordered = 0, freefrom = 0, i;
	FILE *fp;
	char *fname = NULL;
	size_t fname_len;
	const char *user_contexts_path = selinux_user_contexts_path();

	if (!fromcon) {
		/* Get the current context and use it for the starting context */
		rc = getcon(&fromcon);
		if (rc < 0)
			return rc;
		freefrom = 1;
	}

	/* Determine the set of reachable contexts for the user. */
	rc = security_compute_user(fromcon, user, &reachable);
	if (rc < 0)
		goto failsafe;
	nreach = 0;
	for (ptr = reachable; *ptr; ptr++)
		nreach++;
	if (!nreach)
		goto failsafe;

	/* Initialize ordering array. */
	ordering = malloc(nreach * sizeof(unsigned int));
	if (!ordering)
		goto failsafe;
	for (i = 0; i < nreach; i++)
		ordering[i] = nreach;

	/* Determine the ordering to apply from the optional per-user config
	   and from the global config. */
	fname_len = strlen(user_contexts_path) + strlen(user) + 2;
	fname = malloc(fname_len);
	if (!fname)
		goto failsafe;
	snprintf(fname, fname_len, "%s%s", user_contexts_path, user);
	fp = fopen(fname, "re");
	if (fp) {
		__fsetlocking(fp, FSETLOCKING_BYCALLER);
		rc = get_context_order(fp, fromcon, reachable, nreach, ordering,
				       &nordered);
		fclose(fp);
		if (rc < 0 && errno != ENOENT) {
			fprintf(stderr,
				"%s:  error in processing configuration file %s\n",
				__FUNCTION__, fname);
			/* Fall through, try global config */
		}
	}
	free(fname);
	fp = fopen(selinux_default_context_path(), "re");
	if (fp) {
		__fsetlocking(fp, FSETLOCKING_BYCALLER);
		rc = get_context_order(fp, fromcon, reachable, nreach, ordering,
				       &nordered);
		fclose(fp);
		if (rc < 0 && errno != ENOENT) {
			fprintf(stderr,
				"%s:  error in processing configuration file %s\n",
				__FUNCTION__, selinux_default_context_path());
			/* Fall through */
		}
		rc = 0;
	}

	if (!nordered)
		goto failsafe;

	/* Apply the ordering. */
	co = malloc(nreach * sizeof(struct context_order));
	if (!co)
		goto failsafe;
	for (i = 0; i < nreach; i++) {
		co[i].con = reachable[i];
		co[i].order = ordering[i];
	}
	qsort(co, nreach, sizeof(struct context_order), order_compare);
	for (i = 0; i < nreach; i++)
		reachable[i] = co[i].con;
	free(co);

	/* Only report the ordered entries to the caller. */
	if (nordered <= nreach) {
		for (i = nordered; i < nreach; i++)
			free(reachable[i]);
		reachable[nordered] = NULL;
		rc = nordered;
	}

      out:
	if (rc > 0)
		*list = reachable;
	else
		freeconary(reachable);

	free(ordering);
	if (freefrom)
		freecon(fromcon);

	return rc;

      failsafe:
	/* Unable to determine a reachable context list, try to fall back to
	   the "failsafe" context to at least permit root login
	   for emergency recovery if possible. */
	freeconary(reachable);
	reachable = malloc(2 * sizeof(char *));
	if (!reachable) {
		rc = -1;
		goto out;
	}
	reachable[0] = reachable[1] = 0;
	rc = get_failsafe_context(user, &reachable[0]);
	if (rc < 0) {
		freeconary(reachable);
		reachable = NULL;
		goto out;
	}
	rc = 1;			/* one context in the list */
	goto out;
}

hidden_def(get_ordered_context_list)
