#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include "selinux_internal.h"
#include "label_internal.h"
#include "callbacks.h"
#include <limits.h>

static __thread struct selabel_handle *hnd;

/*
 * An array for mapping integers to contexts
 */
static __thread char **con_array;
static __thread int con_array_size;
static __thread int con_array_used;

static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_key_t destructor_key;
static int destructor_key_initialized = 0;

static int add_array_elt(char *con)
{
	if (con_array_size) {
		while (con_array_used >= con_array_size) {
			con_array_size *= 2;
			con_array = (char **)realloc(con_array, sizeof(char*) *
						     con_array_size);
			if (!con_array) {
				con_array_size = con_array_used = 0;
				return -1;
			}
		}
	} else {
		con_array_size = 1000;
		con_array = (char **)malloc(sizeof(char*) * con_array_size);
		if (!con_array) {
			con_array_size = con_array_used = 0;
			return -1;
		}
	}

	con_array[con_array_used] = strdup(con);
	if (!con_array[con_array_used])
		return -1;
	return con_array_used++;
}

static void free_array_elts(void)
{
	con_array_size = con_array_used = 0;
	free(con_array);
	con_array = NULL;
}

static void
#ifdef __GNUC__
    __attribute__ ((format(printf, 1, 2)))
#endif
    default_printf(const char *fmt, ...)
{
	va_list ap;
	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	va_end(ap);
}

void
#ifdef __GNUC__
    __attribute__ ((format(printf, 1, 2)))
#endif
    (*myprintf) (const char *fmt,...) = &default_printf;
int myprintf_compat = 0;

void set_matchpathcon_printf(void (*f) (const char *fmt, ...))
{
	myprintf = f ? f : &default_printf;
	myprintf_compat = 1;
}

static int (*myinvalidcon) (const char *p, unsigned l, char *c) = NULL;

void set_matchpathcon_invalidcon(int (*f) (const char *p, unsigned l, char *c))
{
	myinvalidcon = f;
}

static int default_canoncon(const char *path, unsigned lineno, char **context)
{
	char *tmpcon;
	if (security_canonicalize_context_raw(*context, &tmpcon) < 0) {
		if (errno == ENOENT)
			return 0;
		if (lineno)
			myprintf("%s:  line %u has invalid context %s\n", path,
				 lineno, *context);
		else
			myprintf("%s:  invalid context %s\n", path, *context);
		return 1;
	}
	free(*context);
	*context = tmpcon;
	return 0;
}

static int (*mycanoncon) (const char *p, unsigned l, char **c) =
    NULL;

void set_matchpathcon_canoncon(int (*f) (const char *p, unsigned l, char **c))
{
	if (f)
		mycanoncon = f;
	else
		mycanoncon = &default_canoncon;
}

static __thread struct selinux_opt options[SELABEL_NOPT];
static __thread int notrans;

void set_matchpathcon_flags(unsigned int flags)
{
	int i;
	memset(options, 0, sizeof(options));
	i = SELABEL_OPT_BASEONLY;
	options[i].type = i;
	options[i].value = (flags & MATCHPATHCON_BASEONLY) ? (char*)1 : NULL;
	i = SELABEL_OPT_VALIDATE;
	options[i].type = i;
	options[i].value = (flags & MATCHPATHCON_VALIDATE) ? (char*)1 : NULL;
	notrans = flags & MATCHPATHCON_NOTRANS;
}

/*
 * An association between an inode and a 
 * specification.  
 */
typedef struct file_spec {
	ino_t ino;		/* inode number */
	int specind;		/* index of specification in spec */
	char *file;		/* full pathname for diagnostic messages about conflicts */
	struct file_spec *next;	/* next association in hash bucket chain */
} file_spec_t;

/*
 * The hash table of associations, hashed by inode number.
 * Chaining is used for collisions, with elements ordered
 * by inode number in each bucket.  Each hash bucket has a dummy 
 * header.
 */
#define HASH_BITS 16
#define HASH_BUCKETS (1 << HASH_BITS)
#define HASH_MASK (HASH_BUCKETS-1)
static file_spec_t *fl_head;

/*
 * Try to add an association between an inode and
 * a specification.  If there is already an association
 * for the inode and it conflicts with this specification,
 * then use the specification that occurs later in the
 * specification array.
 */
int matchpathcon_filespec_add(ino_t ino, int specind, const char *file)
{
	file_spec_t *prevfl, *fl;
	int h, ret;
	struct stat sb;

	if (!fl_head) {
		fl_head = malloc(sizeof(file_spec_t) * HASH_BUCKETS);
		if (!fl_head)
			goto oom;
		memset(fl_head, 0, sizeof(file_spec_t) * HASH_BUCKETS);
	}

	h = (ino + (ino >> HASH_BITS)) & HASH_MASK;
	for (prevfl = &fl_head[h], fl = fl_head[h].next; fl;
	     prevfl = fl, fl = fl->next) {
		if (ino == fl->ino) {
			ret = lstat(fl->file, &sb);
			if (ret < 0 || sb.st_ino != ino) {
				fl->specind = specind;
				free(fl->file);
				fl->file = malloc(strlen(file) + 1);
				if (!fl->file)
					goto oom;
				strcpy(fl->file, file);
				return fl->specind;

			}

			if (!strcmp(con_array[fl->specind],
				    con_array[specind]))
				return fl->specind;

			myprintf
			    ("%s:  conflicting specifications for %s and %s, using %s.\n",
			     __FUNCTION__, file, fl->file,
			     con_array[fl->specind]);
			free(fl->file);
			fl->file = malloc(strlen(file) + 1);
			if (!fl->file)
				goto oom;
			strcpy(fl->file, file);
			return fl->specind;
		}

		if (ino > fl->ino)
			break;
	}

	fl = malloc(sizeof(file_spec_t));
	if (!fl)
		goto oom;
	fl->ino = ino;
	fl->specind = specind;
	fl->file = malloc(strlen(file) + 1);
	if (!fl->file)
		goto oom_freefl;
	strcpy(fl->file, file);
	fl->next = prevfl->next;
	prevfl->next = fl;
	return fl->specind;
      oom_freefl:
	free(fl);
      oom:
	myprintf("%s:  insufficient memory for file label entry for %s\n",
		 __FUNCTION__, file);
	return -1;
}

/*
 * Evaluate the association hash table distribution.
 */
void matchpathcon_filespec_eval(void)
{
	file_spec_t *fl;
	int h, used, nel, len, longest;

	if (!fl_head)
		return;

	used = 0;
	longest = 0;
	nel = 0;
	for (h = 0; h < HASH_BUCKETS; h++) {
		len = 0;
		for (fl = fl_head[h].next; fl; fl = fl->next) {
			len++;
		}
		if (len)
			used++;
		if (len > longest)
			longest = len;
		nel += len;
	}

	myprintf
	    ("%s:  hash table stats: %d elements, %d/%d buckets used, longest chain length %d\n",
	     __FUNCTION__, nel, used, HASH_BUCKETS, longest);
}

/*
 * Destroy the association hash table.
 */
void matchpathcon_filespec_destroy(void)
{
	file_spec_t *fl, *tmp;
	int h;

	free_array_elts();

	if (!fl_head)
		return;

	for (h = 0; h < HASH_BUCKETS; h++) {
		fl = fl_head[h].next;
		while (fl) {
			tmp = fl;
			fl = fl->next;
			free(tmp->file);
			free(tmp);
		}
		fl_head[h].next = NULL;
	}
	free(fl_head);
	fl_head = NULL;
}

static void matchpathcon_thread_destructor(void __attribute__((unused)) *ptr)
{
	matchpathcon_fini();
}

void __attribute__((destructor)) matchpathcon_lib_destructor(void);

void hidden __attribute__((destructor)) matchpathcon_lib_destructor(void)
{
	if (destructor_key_initialized)
		__selinux_key_delete(destructor_key);
}

static void matchpathcon_init_once(void)
{
	if (__selinux_key_create(&destructor_key, matchpathcon_thread_destructor) == 0)
		destructor_key_initialized = 1;
}

int matchpathcon_init_prefix(const char *path, const char *subset)
{
	if (!mycanoncon)
		mycanoncon = default_canoncon;

	__selinux_once(once, matchpathcon_init_once);
	__selinux_setspecific(destructor_key, (void *)1);

	options[SELABEL_OPT_SUBSET].type = SELABEL_OPT_SUBSET;
	options[SELABEL_OPT_SUBSET].value = subset;
	options[SELABEL_OPT_PATH].type = SELABEL_OPT_PATH;
	options[SELABEL_OPT_PATH].value = path;

	hnd = selabel_open(SELABEL_CTX_FILE, options, SELABEL_NOPT);
	return hnd ? 0 : -1;
}

hidden_def(matchpathcon_init_prefix)

int matchpathcon_init(const char *path)
{
	return matchpathcon_init_prefix(path, NULL);
}

void matchpathcon_fini(void)
{
	free_array_elts();

	if (hnd) {
		selabel_close(hnd);
		hnd = NULL;
	}
}

/*
 * We do not want to resolve a symlink to a real path if it is the final
 * component of the name.  Thus we split the pathname on the last "/" and
 * determine a real path component of the first portion.  We then have to
 * copy the last part back on to get the final real path.  Wheww.
 */
int realpath_not_final(const char *name, char *resolved_path)
{
	char *last_component;
	char *tmp_path, *p;
	size_t len = 0;
	int rc = 0;

	tmp_path = strdup(name);
	if (!tmp_path) {
		myprintf("symlink_realpath(%s) strdup() failed: %s\n",
			name, strerror(errno));
		rc = -1;
		goto out;
	}

	/* strip leading // */
	while (tmp_path[len] && tmp_path[len] == '/' &&
	       tmp_path[len+1] && tmp_path[len+1] == '/') {
		tmp_path++;
		len++;
	}
	last_component = strrchr(tmp_path, '/');

	if (last_component == tmp_path) {
		last_component++;
		p = strcpy(resolved_path, "");
	} else if (last_component) {
		*last_component = '\0';
		last_component++;
		p = realpath(tmp_path, resolved_path);
	} else {
		last_component = tmp_path;
		p = realpath("./", resolved_path);
	}

	if (!p) {
		myprintf("symlink_realpath(%s) realpath() failed: %s\n",
			name, strerror(errno));
		rc = -1;
		goto out;
	}

	len = strlen(p);
	if (len + strlen(last_component) + 2 > PATH_MAX) {
		myprintf("symlink_realpath(%s) failed: Filename too long \n",
			name);
		errno=ENAMETOOLONG;
		rc = -1;
		goto out;
	}

	resolved_path += len;
	strcpy(resolved_path, "/");
	resolved_path += 1;
	strcpy(resolved_path, last_component);
out:
	free(tmp_path);
	return rc;
}

int matchpathcon(const char *path, mode_t mode, char ** con)
{
	char stackpath[PATH_MAX + 1];
	char *p = NULL;
	if (!hnd && (matchpathcon_init_prefix(NULL, NULL) < 0))
			return -1;

	if (S_ISLNK(mode)) {
		if (!realpath_not_final(path, stackpath))
			path = stackpath;
	} else {
		p = realpath(path, stackpath);
		if (p)
			path = p;
	}

	return notrans ?
		selabel_lookup_raw(hnd, con, path, mode) :
		selabel_lookup(hnd, con, path, mode);
}

int matchpathcon_index(const char *name, mode_t mode, char ** con)
{
	int i = matchpathcon(name, mode, con);

	if (i < 0)
		return -1;

	return add_array_elt(*con);
}

void matchpathcon_checkmatches(char *str __attribute__((unused)))
{
	selabel_stats(hnd);
}

/* Compare two contexts to see if their differences are "significant",
 * or whether the only difference is in the user. */
int selinux_file_context_cmp(const char * a,
			     const char * b)
{
	char *rest_a, *rest_b;	/* Rest of the context after the user */
	if (!a && !b)
		return 0;
	if (!a)
		return -1;
	if (!b)
		return 1;
	rest_a = strchr((char *)a, ':');
	rest_b = strchr((char *)b, ':');
	if (!rest_a && !rest_b)
		return 0;
	if (!rest_a)
		return -1;
	if (!rest_b)
		return 1;
	return strcmp(rest_a, rest_b);
}

int selinux_file_context_verify(const char *path, mode_t mode)
{
	char * con = NULL;
	char * fcontext = NULL;
	int rc = 0;

	rc = lgetfilecon_raw(path, &con);
	if (rc == -1) {
		if (errno != ENOTSUP)
			return -1;
		else
			return 0;
	}
	
	if (!hnd && (matchpathcon_init_prefix(NULL, NULL) < 0))
			return -1;

	if (selabel_lookup_raw(hnd, &fcontext, path, mode) != 0) {
		if (errno != ENOENT)
			rc = -1;
		else
			rc = 0;
	} else {
		/*
		 * Need to set errno to 0 as it can be set to ENOENT if the
		 * file_contexts.subs file does not exist (see selabel_open in
		 * label.c), thus causing confusion if errno is checked on return.
		 */
		errno = 0;
		rc = (selinux_file_context_cmp(fcontext, con) == 0);
	}

	freecon(con);
	freecon(fcontext);
	return rc;
}

int selinux_lsetfilecon_default(const char *path)
{
	struct stat st;
	int rc = -1;
	char * scontext = NULL;
	if (lstat(path, &st) != 0)
		return rc;

	if (!hnd && (matchpathcon_init_prefix(NULL, NULL) < 0))
			return -1;

	/* If there's an error determining the context, or it has none, 
	   return to allow default context */
	if (selabel_lookup_raw(hnd, &scontext, path, st.st_mode)) {
		if (errno == ENOENT)
			rc = 0;
	} else {
		rc = lsetfilecon_raw(path, scontext);
		freecon(scontext);
	}
	return rc;
}

int compat_validate(struct selabel_handle *rec,
		    struct selabel_lookup_rec *contexts,
		    const char *path, unsigned lineno)
{
	int rc;
	char **ctx = &contexts->ctx_raw;

	if (myinvalidcon)
		rc = myinvalidcon(path, lineno, *ctx);
	else if (mycanoncon)
		rc = mycanoncon(path, lineno, ctx);
	else {
		rc = selabel_validate(rec, contexts);
		if (rc < 0) {
			if (lineno) {
				COMPAT_LOG(SELINUX_WARNING,
					    "%s: line %u has invalid context %s\n",
						path, lineno, *ctx);
			} else {
				COMPAT_LOG(SELINUX_WARNING,
					    "%s: has invalid context %s\n", path, *ctx);
			}
		}
	}

	return rc ? -1 : 0;
}
