/*
 * Author: Karl MacMillan <kmacmillan@tresys.com>
 *
 * Modified:  
 *   Dan Walsh <dwalsh@redhat.com> - Added security_load_booleans().
 */

#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <unistd.h>
#include <fnmatch.h>
#include <limits.h>
#include <ctype.h>
#include <errno.h>

#include "selinux_internal.h"
#include "policy.h"

#define SELINUX_BOOL_DIR "/booleans/"

static int filename_select(const struct dirent *d)
{
	if (d->d_name[0] == '.'
	    && (d->d_name[1] == '\0'
		|| (d->d_name[1] == '.' && d->d_name[2] == '\0')))
		return 0;
	return 1;
}

int security_get_boolean_names(char ***names, int *len)
{
	char path[PATH_MAX];
	int i, rc;
	struct dirent **namelist;
	char **n;

	if (!len || names == NULL) {
		errno = EINVAL;
		return -1;
	}
	if (!selinux_mnt) {
		errno = ENOENT;
		return -1;
	}

	snprintf(path, sizeof path, "%s%s", selinux_mnt, SELINUX_BOOL_DIR);
	*len = scandir(path, &namelist, &filename_select, alphasort);
	if (*len <= 0) {
		return -1;
	}

	n = (char **)malloc(sizeof(char *) * *len);
	if (!n) {
		rc = -1;
		goto bad;
	}

	for (i = 0; i < *len; i++) {
		n[i] = (char *)malloc(_D_ALLOC_NAMLEN(namelist[i]));
		if (!n[i]) {
			rc = -1;
			goto bad_freen;
		}
		strcpy(n[i], namelist[i]->d_name);
	}
	rc = 0;
	*names = n;
      out:
	for (i = 0; i < *len; i++) {
		free(namelist[i]);
	}
	free(namelist);
	return rc;
      bad_freen:
	for (--i; i >= 0; --i)
		free(n[i]);
	free(n);
      bad:
	goto out;
}

hidden_def(security_get_boolean_names)

char *selinux_boolean_sub(const char *name)
{
	char *sub = NULL;
	char *line_buf = NULL;
	size_t line_len;
	FILE *cfg;

	if (!name)
		return NULL;

	cfg = fopen(selinux_booleans_subs_path(), "r");
	if (!cfg)
		goto out;

	while (getline(&line_buf, &line_len, cfg) != -1) {
		char *ptr;
		char *src = line_buf;
		char *dst;
		while (*src && isspace(*src))
			src++;
		if (!*src)
			continue;
		if (src[0] == '#')
			continue;

		ptr = src;
		while (*ptr && !isspace(*ptr))
			ptr++;
		*ptr++ = '\0';
		if (strcmp(src, name) != 0)
			continue;

		dst = ptr;
		while (*dst && isspace(*dst))
			dst++;
		if (!*dst)
			continue;
		ptr=dst;
		while (*ptr && !isspace(*ptr))
			ptr++;
		*ptr='\0';

		sub = strdup(dst);

		break;
	}
	free(line_buf);
	fclose(cfg);
out:
	if (!sub)
		sub = strdup(name);
	return sub;
}

hidden_def(selinux_boolean_sub)

static int bool_open(const char *name, int flag) {
	char *fname = NULL;
	char *alt_name = NULL;
	int len;
	int fd = -1;
	int ret;
	char *ptr;

	if (!name) {
		errno = EINVAL;
		return -1;
	}

	/* note the 'sizeof' gets us enough room for the '\0' */
	len = strlen(name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR);
	fname = malloc(sizeof(char) * len);
	if (!fname)
		return -1;

	ret = snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, name);
	if (ret < 0)
		goto out;
	assert(ret < len);

	fd = open(fname, flag);
	if (fd >= 0 || errno != ENOENT)
		goto out;

	alt_name = selinux_boolean_sub(name);
	if (!alt_name)
		goto out;

	/* note the 'sizeof' gets us enough room for the '\0' */
	len = strlen(alt_name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR);
	ptr = realloc(fname, len);
	if (!ptr)
		goto out;
	fname = ptr;

	ret = snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, alt_name);
	if (ret < 0)
		goto out;
	assert(ret < len);

	fd = open(fname, flag);
out:
	free(fname);
	free(alt_name);

	return fd;
}

#define STRBUF_SIZE 3
static int get_bool_value(const char *name, char **buf)
{
	int fd, len;
	int errno_tmp;

	if (!selinux_mnt) {
		errno = ENOENT;
		return -1;
	}

	*buf = malloc(sizeof(char) * (STRBUF_SIZE + 1));
	if (!*buf)
		return -1;

	(*buf)[STRBUF_SIZE] = 0;

	fd = bool_open(name, O_RDONLY);
	if (fd < 0)
		goto out_err;

	len = read(fd, *buf, STRBUF_SIZE);
	errno_tmp = errno;
	close(fd);
	errno = errno_tmp;
	if (len != STRBUF_SIZE)
		goto out_err;

	return 0;
out_err:
	free(*buf);
	return -1;
}

int security_get_boolean_pending(const char *name)
{
	char *buf;
	int val;

	if (get_bool_value(name, &buf))
		return -1;

	if (atoi(&buf[1]))
		val = 1;
	else
		val = 0;
	free(buf);
	return val;
}

int security_get_boolean_active(const char *name)
{
	char *buf;
	int val;

	if (get_bool_value(name, &buf))
		return -1;

	buf[1] = '\0';
	if (atoi(buf))
		val = 1;
	else
		val = 0;
	free(buf);
	return val;
}

hidden_def(security_get_boolean_active)

int security_set_boolean(const char *name, int value)
{
	int fd, ret;
	char buf[2];

	if (!selinux_mnt) {
		errno = ENOENT;
		return -1;
	}
	if (value < 0 || value > 1) {
		errno = EINVAL;
		return -1;
	}

	fd = bool_open(name, O_WRONLY);
	if (fd < 0)
		return -1;

	if (value)
		buf[0] = '1';
	else
		buf[0] = '0';
	buf[1] = '\0';

	ret = write(fd, buf, 2);
	close(fd);

	if (ret > 0)
		return 0;
	else
		return -1;
}

hidden_def(security_set_boolean)

int security_commit_booleans(void)
{
	int fd, ret;
	char buf[2];
	char path[PATH_MAX];

	if (!selinux_mnt) {
		errno = ENOENT;
		return -1;
	}

	snprintf(path, sizeof path, "%s/commit_pending_bools", selinux_mnt);
	fd = open(path, O_WRONLY);
	if (fd < 0)
		return -1;

	buf[0] = '1';
	buf[1] = '\0';

	ret = write(fd, buf, 2);
	close(fd);

	if (ret > 0)
		return 0;
	else
		return -1;
}

hidden_def(security_commit_booleans)

static char *strtrim(char *dest, char *source, int size)
{
	int i = 0;
	char *ptr = source;
	i = 0;
	while (isspace(*ptr) && i < size) {
		ptr++;
		i++;
	}
	strncpy(dest, ptr, size);
	for (i = strlen(dest) - 1; i > 0; i--) {
		if (!isspace(dest[i]))
			break;
	}
	dest[i + 1] = '\0';
	return dest;
}
static int process_boolean(char *buffer, char *name, int namesize, int *val)
{
	char name1[BUFSIZ];
	char *ptr = NULL;
	char *tok = strtok_r(buffer, "=", &ptr);
	if (tok) {
		strncpy(name1, tok, BUFSIZ - 1);
		strtrim(name, name1, namesize - 1);
		if (name[0] == '#')
			return 0;
		tok = strtok_r(NULL, "\0", &ptr);
		if (tok) {
			while (isspace(*tok))
				tok++;
			*val = -1;
			if (isdigit(tok[0]))
				*val = atoi(tok);
			else if (!strncasecmp(tok, "true", sizeof("true") - 1))
				*val = 1;
			else if (!strncasecmp
				 (tok, "false", sizeof("false") - 1))
				*val = 0;
			if (*val != 0 && *val != 1) {
				errno = EINVAL;
				return -1;
			}

		}
	}
	return 1;
}
static int save_booleans(size_t boolcnt, SELboolean * boollist)
{
	ssize_t len;
	size_t i;
	char outbuf[BUFSIZ];
	char *inbuf = NULL;

	/* Open file */
	const char *bool_file = selinux_booleans_path();
	char local_bool_file[PATH_MAX];
	char tmp_bool_file[PATH_MAX];
	FILE *boolf;
	int fd;
	int *used = (int *)malloc(sizeof(int) * boolcnt);
	if (!used) {
		return -1;
	}
	/* zero out used field */
	for (i = 0; i < boolcnt; i++)
		used[i] = 0;

	snprintf(tmp_bool_file, sizeof(tmp_bool_file), "%s.XXXXXX", bool_file);
	fd = mkstemp(tmp_bool_file);
	if (fd < 0) {
		free(used);
		return -1;
	}

	snprintf(local_bool_file, sizeof(local_bool_file), "%s.local",
		 bool_file);
	boolf = fopen(local_bool_file, "r");
	if (boolf != NULL) {
		ssize_t ret;
		size_t size = 0;
		int val;
		char boolname[BUFSIZ];
		char *buffer;
		inbuf = NULL;
		__fsetlocking(boolf, FSETLOCKING_BYCALLER);
		while ((len = getline(&inbuf, &size, boolf)) > 0) {
			buffer = strdup(inbuf);
			if (!buffer)
				goto close_remove_fail;
			ret =
			    process_boolean(inbuf, boolname, sizeof(boolname),
					    &val);
			if (ret != 1) {
				ret = write(fd, buffer, len);
				free(buffer);
				if (ret != len)
					goto close_remove_fail;
			} else {
				free(buffer);
				for (i = 0; i < boolcnt; i++) {
					if (strcmp(boollist[i].name, boolname)
					    == 0) {
						snprintf(outbuf, sizeof(outbuf),
							 "%s=%d\n", boolname,
							 boollist[i].value);
						len = strlen(outbuf);
						used[i] = 1;
						if (write(fd, outbuf, len) !=
						    len)
							goto close_remove_fail;
						else
							break;
					}
				}
				if (i == boolcnt) {
					snprintf(outbuf, sizeof(outbuf),
						 "%s=%d\n", boolname, val);
					len = strlen(outbuf);
					if (write(fd, outbuf, len) != len)
						goto close_remove_fail;
				}
			}
			free(inbuf);
			inbuf = NULL;
		}
		fclose(boolf);
	}

	for (i = 0; i < boolcnt; i++) {
		if (used[i] == 0) {
			snprintf(outbuf, sizeof(outbuf), "%s=%d\n",
				 boollist[i].name, boollist[i].value);
			len = strlen(outbuf);
			if (write(fd, outbuf, len) != len) {
			      close_remove_fail:
				free(inbuf);
				close(fd);
			      remove_fail:
				unlink(tmp_bool_file);
				free(used);
				return -1;
			}
		}

	}
	if (fchmod(fd, S_IRUSR | S_IWUSR) != 0)
		goto close_remove_fail;
	close(fd);
	if (rename(tmp_bool_file, local_bool_file) != 0)
		goto remove_fail;

	free(used);
	return 0;
}
static void rollback(SELboolean * boollist, int end)
{
	int i;

	for (i = 0; i < end; i++)
		security_set_boolean(boollist[i].name,
				     security_get_boolean_active(boollist[i].
								 name));
}

int security_set_boolean_list(size_t boolcnt, SELboolean * boollist,
			      int permanent)
{

	size_t i;
	for (i = 0; i < boolcnt; i++) {
		if (security_set_boolean(boollist[i].name, boollist[i].value)) {
			rollback(boollist, i);
			return -1;
		}
	}

	/* OK, let's do the commit */
	if (security_commit_booleans()) {
		return -1;
	}

	if (permanent)
		return save_booleans(boolcnt, boollist);

	return 0;
}
int security_load_booleans(char *path)
{
	FILE *boolf;
	char *inbuf;
	char localbools[BUFSIZ];
	size_t len = 0, errors = 0;
	int val;
	char name[BUFSIZ];

	boolf = fopen(path ? path : selinux_booleans_path(), "r");
	if (boolf == NULL)
		goto localbool;

	__fsetlocking(boolf, FSETLOCKING_BYCALLER);
	while (getline(&inbuf, &len, boolf) > 0) {
		int ret = process_boolean(inbuf, name, sizeof(name), &val);
		if (ret == -1)
			errors++;
		if (ret == 1)
			if (security_set_boolean(name, val) < 0) {
				errors++;
			}
	}
	fclose(boolf);
      localbool:
	snprintf(localbools, sizeof(localbools), "%s.local",
		 (path ? path : selinux_booleans_path()));
	boolf = fopen(localbools, "r");

	if (boolf != NULL) {
		int ret;
		__fsetlocking(boolf, FSETLOCKING_BYCALLER);
		while (getline(&inbuf, &len, boolf) > 0) {
			ret = process_boolean(inbuf, name, sizeof(name), &val);
			if (ret == -1)
				errors++;
			if (ret == 1)
				if (security_set_boolean(name, val) < 0) {
					errors++;
				}
		}
		fclose(boolf);
	}
	if (security_commit_booleans() < 0)
		return -1;

	if (errors)
		errno = EINVAL;
	return errors ? -1 : 0;
}
