#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/utsname.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include "selinux_internal.h"
#ifndef ANDROID
#include <sepol/sepol.h>
#include <sepol/policydb.h>
#endif
#include <dlfcn.h>
#include "policy.h"
#include <limits.h>

#ifndef MNT_DETACH
#define MNT_DETACH 2
#endif

int security_load_policy(void *data, size_t len)
{
	char path[PATH_MAX];
	int fd, ret;

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

	snprintf(path, sizeof path, "%s/load", selinux_mnt);
	fd = open(path, O_RDWR | O_CLOEXEC);
	if (fd < 0)
		return -1;

	ret = write(fd, data, len);
	close(fd);
	if (ret < 0)
		return -1;
	return 0;
}

hidden_def(security_load_policy)

#ifndef ANDROID
int load_setlocaldefs hidden = 1;

#undef max
#define max(a, b) (((a) > (b)) ? (a) : (b))

int selinux_mkload_policy(int preservebools)
{	
	int kernvers = security_policyvers();
	int maxvers = kernvers, minvers = DEFAULT_POLICY_VERSION, vers;
	int setlocaldefs = load_setlocaldefs;
	char path[PATH_MAX];
	struct stat sb;
	struct utsname uts;
	size_t size;
	void *map, *data;
	int fd, rc = -1, prot;
	sepol_policydb_t *policydb;
	sepol_policy_file_t *pf;
	int usesepol = 0;
	int (*vers_max)(void) = NULL;
	int (*vers_min)(void) = NULL;
	int (*policy_file_create)(sepol_policy_file_t **) = NULL;
	void (*policy_file_free)(sepol_policy_file_t *) = NULL;
	void (*policy_file_set_mem)(sepol_policy_file_t *, char*, size_t) = NULL;
	int (*policydb_create)(sepol_policydb_t **) = NULL;
	void (*policydb_free)(sepol_policydb_t *) = NULL;
	int (*policydb_read)(sepol_policydb_t *, sepol_policy_file_t *) = NULL;
	int (*policydb_set_vers)(sepol_policydb_t *, unsigned int) = NULL;
	int (*policydb_to_image)(sepol_handle_t *, sepol_policydb_t *, void **, size_t *) = NULL;
	int (*genbools_array)(void *data, size_t len, char **names, int *values, int nel) = NULL;
	int (*genusers)(void *data, size_t len, const char *usersdir, void **newdata, size_t * newlen) = NULL;
	int (*genbools)(void *data, size_t len, const char *boolpath) = NULL;

#ifdef SHARED
	char *errormsg = NULL;
	void *libsepolh = NULL;
	libsepolh = dlopen("libsepol.so.1", RTLD_NOW);
	if (libsepolh) {
		usesepol = 1;
		dlerror();
#define DLERR() if ((errormsg = dlerror())) goto dlclose;
		vers_max = dlsym(libsepolh, "sepol_policy_kern_vers_max");
		DLERR();
		vers_min = dlsym(libsepolh, "sepol_policy_kern_vers_min");
		DLERR();

		policy_file_create = dlsym(libsepolh, "sepol_policy_file_create");
		DLERR();
		policy_file_free = dlsym(libsepolh, "sepol_policy_file_free");
		DLERR();
		policy_file_set_mem = dlsym(libsepolh, "sepol_policy_file_set_mem");
		DLERR();
		policydb_create = dlsym(libsepolh, "sepol_policydb_create");
		DLERR();
		policydb_free = dlsym(libsepolh, "sepol_policydb_free");
		DLERR();
		policydb_read = dlsym(libsepolh, "sepol_policydb_read");
		DLERR();
		policydb_set_vers = dlsym(libsepolh, "sepol_policydb_set_vers");
		DLERR();
		policydb_to_image = dlsym(libsepolh, "sepol_policydb_to_image");
		DLERR();
		genbools_array = dlsym(libsepolh, "sepol_genbools_array");
		DLERR();
		genusers = dlsym(libsepolh, "sepol_genusers");
		DLERR();
		genbools = dlsym(libsepolh, "sepol_genbools");
		DLERR();

#undef DLERR
	}
#else
	usesepol = 1;
	vers_max = sepol_policy_kern_vers_max;
	vers_min = sepol_policy_kern_vers_min;
	policy_file_create = sepol_policy_file_create;
	policy_file_free = sepol_policy_file_free;
	policy_file_set_mem = sepol_policy_file_set_mem;
	policydb_create = sepol_policydb_create;
	policydb_free = sepol_policydb_free;
	policydb_read = sepol_policydb_read;
	policydb_set_vers = sepol_policydb_set_vers;
	policydb_to_image = sepol_policydb_to_image;
	genbools_array = sepol_genbools_array;
	genusers = sepol_genusers;
	genbools = sepol_genbools;

#endif

	/*
	 * Check whether we need to support local boolean and user definitions.
	 */
	if (setlocaldefs) {
		if (access(selinux_booleans_path(), F_OK) == 0)
			goto checkbool;
		snprintf(path, sizeof path, "%s.local", selinux_booleans_path());
		if (access(path, F_OK) == 0)
			goto checkbool;
		snprintf(path, sizeof path, "%s/local.users", selinux_users_path());
		if (access(path, F_OK) == 0)
			goto checkbool;
		/* No local definition files, so disable setlocaldefs. */
		setlocaldefs = 0;
	}

checkbool:
	/* 
	 * As of Linux 2.6.22, the kernel preserves boolean
	 * values across a reload, so we do not need to 
	 * preserve them in userspace.
	 */
	if (preservebools && uname(&uts) == 0 && strverscmp(uts.release, "2.6.22") >= 0)
		preservebools = 0;

	if (usesepol) {
		maxvers = vers_max();
		minvers = vers_min();
		if (!setlocaldefs && !preservebools)
			maxvers = max(kernvers, maxvers);
	}

	vers = maxvers;
      search:
	snprintf(path, sizeof(path), "%s.%d",
		 selinux_binary_policy_path(), vers);
	fd = open(path, O_RDONLY | O_CLOEXEC);
	while (fd < 0 && errno == ENOENT
	       && --vers >= minvers) {
		/* Check prior versions to see if old policy is available */
		snprintf(path, sizeof(path), "%s.%d",
			 selinux_binary_policy_path(), vers);
		fd = open(path, O_RDONLY | O_CLOEXEC);
	}
	if (fd < 0) {
		fprintf(stderr,
			"SELinux:  Could not open policy file <= %s.%d:  %s\n",
			selinux_binary_policy_path(), maxvers, strerror(errno));
		goto dlclose;
	}

	if (fstat(fd, &sb) < 0) {
		fprintf(stderr,
			"SELinux:  Could not stat policy file %s:  %s\n",
			path, strerror(errno));
		goto close;
	}

	prot = PROT_READ;
	if (setlocaldefs || preservebools)
		prot |= PROT_WRITE;

	size = sb.st_size;
	data = map = mmap(NULL, size, prot, MAP_PRIVATE, fd, 0);
	if (map == MAP_FAILED) {
		fprintf(stderr,
			"SELinux:  Could not map policy file %s:  %s\n",
			path, strerror(errno));
		goto close;
	}

	if (vers > kernvers && usesepol) {
		/* Need to downgrade to kernel-supported version. */
		if (policy_file_create(&pf))
			goto unmap;
		if (policydb_create(&policydb)) {
			policy_file_free(pf);
			goto unmap;
		}
		policy_file_set_mem(pf, data, size);
		if (policydb_read(policydb, pf)) {
			policy_file_free(pf);
			policydb_free(policydb);
			goto unmap;
		}
		if (policydb_set_vers(policydb, kernvers) ||
		    policydb_to_image(NULL, policydb, &data, &size)) {
			/* Downgrade failed, keep searching. */
			fprintf(stderr,
				"SELinux:  Could not downgrade policy file %s, searching for an older version.\n",
				path);
			policy_file_free(pf);
			policydb_free(policydb);
			munmap(map, sb.st_size);
			close(fd);
			vers--;
			goto search;
		}
		policy_file_free(pf);
		policydb_free(policydb);
	}

	if (usesepol) {
		if (setlocaldefs) {
			void *olddata = data;
			size_t oldsize = size;
			rc = genusers(olddata, oldsize, selinux_users_path(),
				      &data, &size);
			if (rc < 0) {
				/* Fall back to the prior image if genusers failed. */
				data = olddata;
				size = oldsize;
				rc = 0;
			} else {
				if (olddata != map)
					free(olddata);
			}
		}
		
		if (preservebools) {
			int *values, len, i;
			char **names;
			rc = security_get_boolean_names(&names, &len);
			if (!rc) {
				values = malloc(sizeof(int) * len);
				if (!values)
					goto unmap;
				for (i = 0; i < len; i++)
					values[i] =
						security_get_boolean_active(names[i]);
				(void)genbools_array(data, size, names, values,
						     len);
				free(values);
				for (i = 0; i < len; i++)
					free(names[i]);
				free(names);
			}
		} else if (setlocaldefs) {
			(void)genbools(data, size, selinux_booleans_path());
		}
	}


	rc = security_load_policy(data, size);
	
	if (rc)
		fprintf(stderr,
			"SELinux:  Could not load policy file %s:  %s\n",
			path, strerror(errno));

      unmap:
	if (data != map)
		free(data);
	munmap(map, sb.st_size);
      close:
	close(fd);
      dlclose:
#ifdef SHARED
	if (errormsg)
		fprintf(stderr, "libselinux:  %s\n", errormsg);
	if (libsepolh)
		dlclose(libsepolh);
#endif
	return rc;
}

hidden_def(selinux_mkload_policy)

/*
 * Mount point for selinuxfs. 
 * This definition is private to the function below.
 * Everything else uses the location determined during 
 * libselinux startup via /proc/mounts (see init_selinuxmnt).  
 * We only need the hardcoded definition for the initial mount 
 * required for the initial policy load.
 */
int selinux_init_load_policy(int *enforce)
{
	int rc = 0, orig_enforce = 0, seconfig = -2, secmdline = -1;
	FILE *cfg;
	char *buf;

	/*
	 * Reread the selinux configuration in case it has changed.
	 * Example:  Caller has chroot'd and is now loading policy from
	 * chroot'd environment.
	 */
	selinux_reset_config();

	/*
	 * Get desired mode (disabled, permissive, enforcing) from 
	 * /etc/selinux/config. 
	 */
	selinux_getenforcemode(&seconfig);

	/* Check for an override of the mode via the kernel command line. */
	rc = mount("proc", "/proc", "proc", 0, 0);
	cfg = fopen("/proc/cmdline", "re");
	if (cfg) {
		char *tmp;
		buf = malloc(selinux_page_size);
		if (!buf) {
			fclose(cfg);
			return -1;
		}
		if (fgets(buf, selinux_page_size, cfg) &&
		    (tmp = strstr(buf, "enforcing="))) {
			if (tmp == buf || isspace(*(tmp - 1))) {
				secmdline =
				    atoi(tmp + sizeof("enforcing=") - 1);
			}
		}
		fclose(cfg);
		free(buf);
	}

	/* 
	 * Determine the final desired mode.
	 * Command line argument takes precedence, then config file. 
	 */
	if (secmdline >= 0)
		*enforce = secmdline;
	else if (seconfig >= 0)
		*enforce = seconfig;
	else
		*enforce = 0;	/* unspecified or disabled */

	/*
	 * Check for the existence of SELinux via selinuxfs, and 
	 * mount it if present for use in the calls below.  
	 */
	const char *mntpoint = NULL;
	/* First make sure /sys is mounted */
	if (mount("sysfs", "/sys", "sysfs", 0, 0) == 0 || errno == EBUSY) {
		if (mount(SELINUXFS, SELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) {
			mntpoint = SELINUXMNT;
		} else {
			/* check old mountpoint */
			if (mount(SELINUXFS, OLDSELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) {
				mntpoint = OLDSELINUXMNT;
			}
		}
	} else {
		/* check old mountpoint */
		if (mount(SELINUXFS, OLDSELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) {
			mntpoint = OLDSELINUXMNT;
		}
	}

	if (! mntpoint ) {
		if (errno == ENODEV || !selinuxfs_exists()) {
			/*
			 * SELinux was disabled in the kernel, either
			 * omitted entirely or disabled at boot via selinux=0.
			 * This takes precedence over any config or
			 * commandline enforcing setting.
			 */
			*enforce = 0;
		} else {
			/* Only emit this error if selinux was not disabled */
			fprintf(stderr, "Mount failed for selinuxfs on %s:  %s\n", SELINUXMNT, strerror(errno));
		}

		if (rc == 0)
			umount2("/proc", MNT_DETACH);
                
		goto noload;
	}
	set_selinuxmnt(mntpoint);

	if (rc == 0)
		umount2("/proc", MNT_DETACH);

	/*
	 * Note:  The following code depends on having selinuxfs 
	 * already mounted and selinuxmnt set above.
	 */

	if (seconfig == -1) {
		/* Runtime disable of SELinux. */
		rc = security_disable();
		if (rc == 0) {
			/* Successfully disabled, so umount selinuxfs too. */
			umount(selinux_mnt);
			fini_selinuxmnt();
			goto noload;
		} else {
			/*
			 * It's possible that this failed because policy has
			 * already been loaded. We can't disable SELinux now,
			 * so the best we can do is force it to be permissive.
			 */
			*enforce = 0;
		}
	}

	/*
	 * If necessary, change the kernel enforcing status to match 
	 * the desired mode. 
	 */
	orig_enforce = rc = security_getenforce();
	if (rc < 0)
		goto noload;
	if (orig_enforce != *enforce) {
		rc = security_setenforce(*enforce);
		if (rc < 0) {
			fprintf(stderr, "SELinux:  Unable to switch to %s mode:  %s\n", (*enforce ? "enforcing" : "permissive"), strerror(errno));
			if (*enforce)
				goto noload;
		}
	}

	if (seconfig == -1) {
		umount(selinux_mnt);
		fini_selinuxmnt();
		goto noload;
	}

	/* Load the policy. */
	return selinux_mkload_policy(0);

      noload:
	/*
	 * Only return 0 on a successful completion of policy load.
	 * In any other case, we want to return an error so that init
	 * knows not to proceed with the re-exec for the domain transition.
	 * Depending on the *enforce setting, init will halt (> 0) or proceed
	 * normally (otherwise).
	 */
	return -1;
}
#endif
