Chris PeBenito 473ea7
/*
Chris PeBenito 473ea7
 * Author: Karl MacMillan <kmacmillan@tresys.com>
Chris PeBenito 473ea7
 *
Chris PeBenito 473ea7
 * Modified:  
Chris PeBenito 473ea7
 *   Dan Walsh <dwalsh@redhat.com> - Added security_load_booleans().
Chris PeBenito 473ea7
 */
Chris PeBenito 473ea7
Chris PeBenito 473ea7
#include <sys/types.h>
Chris PeBenito 473ea7
#include <sys/stat.h>
Chris PeBenito 473ea7
#include <fcntl.h>
Chris PeBenito 473ea7
#include <assert.h>
Chris PeBenito 473ea7
#include <stdlib.h>
Chris PeBenito 473ea7
#include <dirent.h>
Chris PeBenito 473ea7
#include <string.h>
Chris PeBenito 473ea7
#include <stdio.h>
Chris PeBenito 473ea7
#include <unistd.h>
Chris PeBenito 473ea7
#include <fnmatch.h>
Chris PeBenito 473ea7
#include <limits.h>
Chris PeBenito 473ea7
#include <ctype.h>
Chris PeBenito 473ea7
#include <errno.h>
Chris PeBenito 473ea7
Chris PeBenito 473ea7
#include "selinux_internal.h"
Chris PeBenito 473ea7
#include "policy.h"
Chris PeBenito 473ea7
Chris PeBenito 473ea7
#define SELINUX_BOOL_DIR "/booleans/"
Chris PeBenito 473ea7
Chris PeBenito 473ea7
static int filename_select(const struct dirent *d)
Chris PeBenito 473ea7
{
Chris PeBenito 473ea7
	int len;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	len = strlen(d->d_name);
Chris PeBenito 473ea7
	if (len == 1 && d->d_name[0] == '.')
Chris PeBenito 473ea7
		return 0;
Chris PeBenito 473ea7
	if (len == 2 && d->d_name[0] == '.' &&
Chris PeBenito 473ea7
	    d->d_name[1] == '.')
Chris PeBenito 473ea7
		return 0;
Chris PeBenito 473ea7
	return 1;
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
int security_get_boolean_names(char ***names, int *len)
Chris PeBenito 473ea7
{
Chris PeBenito 473ea7
	char path[PATH_MAX];
Chris PeBenito 473ea7
	int i, rc;
Chris PeBenito 473ea7
	struct dirent **namelist;
Chris PeBenito 473ea7
	char **n;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	assert(len);
Chris PeBenito 473ea7
	if (!selinux_mnt) {
Chris PeBenito 473ea7
		errno = ENOENT;
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	snprintf(path, sizeof path, "%s%s", selinux_mnt, SELINUX_BOOL_DIR);
Chris PeBenito 473ea7
	*len = scandir(path, &namelist, &filename_select,
Chris PeBenito 473ea7
		       alphasort);
Chris PeBenito 473ea7
	if (*len <= 0) {
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	n = (char**)malloc(sizeof(char*) * *len);
Chris PeBenito 473ea7
	if (!n) {
Chris PeBenito 473ea7
		rc = -1;
Chris PeBenito 473ea7
		goto bad;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	memset(n, 0, sizeof(char*) * *len);
Chris PeBenito 473ea7
	
Chris PeBenito 473ea7
	for (i = 0; i < *len; i++) {
Chris PeBenito 473ea7
		n[i] = (char*)malloc(sizeof(char)
Chris PeBenito 473ea7
				     * (namelist[i]->d_reclen + 1));
Chris PeBenito 473ea7
		if (!n[i]) {
Chris PeBenito 473ea7
			rc = -1;
Chris PeBenito 473ea7
			goto bad_freen;
Chris PeBenito 473ea7
		}
Chris PeBenito 473ea7
		strncpy(n[i], namelist[i]->d_name, namelist[i]->d_reclen + 1);
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	rc = 0;
Chris PeBenito 473ea7
	*names = n;
Chris PeBenito 473ea7
out:
Chris PeBenito 473ea7
	for (i = 0; i < *len; i++) {
Chris PeBenito 473ea7
		free(namelist[i]);
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	free(namelist);
Chris PeBenito 473ea7
	return rc;
Chris PeBenito 473ea7
bad_freen:
Chris PeBenito 473ea7
	for (i = 0; i < *len; i++) {
Chris PeBenito 473ea7
		if (n[i])
Chris PeBenito 473ea7
			free(n[i]);
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	free(n);
Chris PeBenito 473ea7
bad:
Chris PeBenito 473ea7
	goto out;
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
hidden_def(security_get_boolean_names)
Chris PeBenito 473ea7
Chris PeBenito 473ea7
#define STRBUF_SIZE 3 
Chris PeBenito 473ea7
static int get_bool_value(const char *name, char **buf)
Chris PeBenito 473ea7
{
Chris PeBenito 473ea7
	int fd, len;
Chris PeBenito 473ea7
	char *fname = NULL;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (!selinux_mnt) {
Chris PeBenito 473ea7
		errno = ENOENT;
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	*buf = (char*)malloc(sizeof(char) * (STRBUF_SIZE + 1));
Chris PeBenito 473ea7
	if (!*buf)
Chris PeBenito 473ea7
		goto out;
Chris PeBenito 473ea7
	(*buf)[STRBUF_SIZE] = 0;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	len = strlen(name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR);
Chris PeBenito 473ea7
	fname = (char*)malloc(sizeof(char) * len);
Chris PeBenito 473ea7
	if (!fname)
Chris PeBenito 473ea7
		goto out;
Chris PeBenito 473ea7
	snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, name);
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	fd = open(fname, O_RDONLY);
Chris PeBenito 473ea7
	if (fd < 0)
Chris PeBenito 473ea7
		goto out;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	len = read(fd, *buf, STRBUF_SIZE);
Chris PeBenito 473ea7
	close(fd);
Chris PeBenito 473ea7
	if (len != STRBUF_SIZE)
Chris PeBenito 473ea7
		goto out;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	free(fname);
Chris PeBenito 473ea7
	return 0;
Chris PeBenito 473ea7
out:
Chris PeBenito 473ea7
	if (*buf)
Chris PeBenito 473ea7
		free(*buf);
Chris PeBenito 473ea7
	if (fname)
Chris PeBenito 473ea7
		free(fname);
Chris PeBenito 473ea7
	return -1;
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
int security_get_boolean_pending(const char *name)
Chris PeBenito 473ea7
{
Chris PeBenito 473ea7
	char *buf;
Chris PeBenito 473ea7
	int val;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (get_bool_value(name, &buf))
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (atoi(&buf[1]))
Chris PeBenito 473ea7
		val = 1;
Chris PeBenito 473ea7
	else
Chris PeBenito 473ea7
		val = 0;
Chris PeBenito 473ea7
	free(buf);
Chris PeBenito 473ea7
	return val;
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
int security_get_boolean_active(const char *name)
Chris PeBenito 473ea7
{
Chris PeBenito 473ea7
	char *buf;
Chris PeBenito 473ea7
	int val;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (get_bool_value(name, &buf))
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	buf[1] = '\0';
Chris PeBenito 473ea7
	if (atoi(buf))
Chris PeBenito 473ea7
		val = 1;
Chris PeBenito 473ea7
	else
Chris PeBenito 473ea7
		val = 0;
Chris PeBenito 473ea7
	free(buf);
Chris PeBenito 473ea7
	return val;
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
hidden_def(security_get_boolean_active)
Chris PeBenito 473ea7
Chris PeBenito 473ea7
int security_set_boolean(const char *name, int value)
Chris PeBenito 473ea7
{
Chris PeBenito 473ea7
	int fd, ret, len;
Chris PeBenito 473ea7
	char buf[2], *fname;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (!selinux_mnt) {
Chris PeBenito 473ea7
		errno = ENOENT;
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	if ( value < 0 || value > 1 ) {
Chris PeBenito 473ea7
		errno = EINVAL;
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	len = strlen(name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR);
Chris PeBenito 473ea7
	fname = (char*)malloc(sizeof(char) * len);
Chris PeBenito 473ea7
	if (!fname)
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
	snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, name);
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	fd = open(fname, O_WRONLY);
Chris PeBenito 473ea7
	if (fd < 0) {
Chris PeBenito 473ea7
		ret = -1;
Chris PeBenito 473ea7
		goto out;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (value)
Chris PeBenito 473ea7
		buf[0] = '1';
Chris PeBenito 473ea7
	else
Chris PeBenito 473ea7
		buf[0] = '0';
Chris PeBenito 473ea7
	buf[1] = '\0';
Chris PeBenito 473ea7
	
Chris PeBenito 473ea7
	ret = write(fd, buf, 2);
Chris PeBenito 473ea7
	close(fd);
Chris PeBenito 473ea7
out:
Chris PeBenito 473ea7
	free(fname);
Chris PeBenito 473ea7
	if (ret > 0)
Chris PeBenito 473ea7
		return 0;
Chris PeBenito 473ea7
	else
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
hidden_def(security_set_boolean)
Chris PeBenito 473ea7
Chris PeBenito 473ea7
int security_commit_booleans(void)
Chris PeBenito 473ea7
{
Chris PeBenito 473ea7
	int fd, ret;
Chris PeBenito 473ea7
	char buf[2];
Chris PeBenito 473ea7
	char path[PATH_MAX];
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (!selinux_mnt) {
Chris PeBenito 473ea7
		errno = ENOENT;
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	snprintf(path, sizeof path, "%s/commit_pending_bools", selinux_mnt);
Chris PeBenito 473ea7
	fd = open(path, O_WRONLY);
Chris PeBenito 473ea7
	if (fd < 0)
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	buf[0] = '1';
Chris PeBenito 473ea7
	buf[1] = '\0';
Chris PeBenito 473ea7
	
Chris PeBenito 473ea7
	ret = write(fd, buf, 2);
Chris PeBenito 473ea7
	close(fd);
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (ret > 0)
Chris PeBenito 473ea7
		return 0;
Chris PeBenito 473ea7
	else
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
hidden_def(security_commit_booleans)
Chris PeBenito 473ea7
Chris PeBenito 473ea7
static char *strtrim(char *dest, char *source, int size) {
Chris PeBenito 473ea7
	int i=0;
Chris PeBenito 473ea7
	char *ptr=source;
Chris PeBenito 473ea7
	i=0;
Chris PeBenito 473ea7
	while(isspace(*ptr) && i < size) {
Chris PeBenito 473ea7
		ptr++;
Chris PeBenito 473ea7
		i++;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	strncpy(dest,ptr,size);
Chris PeBenito 473ea7
	for(i=strlen(dest)-1; i> 0; i--) {
Chris PeBenito 473ea7
		if (!isspace(dest[i])) break;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	dest[i+1]='\0';
Chris PeBenito 473ea7
	return dest;
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
static int process_boolean(char *buffer, char *name, int namesize, int *val) {
Chris PeBenito 473ea7
	char name1[BUFSIZ];
Chris PeBenito 473ea7
	char *ptr;
Chris PeBenito 473ea7
	char *tok=strtok_r(buffer,"=",&ptr);
Chris PeBenito 473ea7
	if (tok) {
Chris PeBenito 473ea7
		strncpy(name1,tok, BUFSIZ-1);
Chris PeBenito 473ea7
		strtrim(name,name1,namesize-1);
Chris PeBenito 473ea7
		if ( name[0]=='#' ) return 0;
Chris PeBenito 473ea7
		tok=strtok_r(NULL,"\0",&ptr);
Chris PeBenito 473ea7
		if (tok) {
Chris PeBenito 473ea7
			while (isspace(*tok)) tok++;
Chris PeBenito 473ea7
			*val = -1;
Chris PeBenito 473ea7
			if (isdigit(tok[0]))
Chris PeBenito 473ea7
				*val=atoi(tok);
Chris PeBenito 473ea7
			else if (!strncasecmp(tok, "true", sizeof("true")-1))
Chris PeBenito 473ea7
				*val = 1;
Chris PeBenito 473ea7
			else if (!strncasecmp(tok, "false", sizeof("false")-1))
Chris PeBenito 473ea7
				*val = 0;
Chris PeBenito 473ea7
			if (*val != 0 && *val != 1) {
Chris PeBenito 473ea7
				errno=EINVAL;
Chris PeBenito 473ea7
				return -1;
Chris PeBenito 473ea7
			}
Chris PeBenito 473ea7
			
Chris PeBenito 473ea7
		}
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	return 1;
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
static int save_booleans(size_t boolcnt, SELboolean *boollist) {
Chris PeBenito 473ea7
	ssize_t len;
Chris PeBenito 473ea7
	size_t i;
Chris PeBenito 473ea7
	char outbuf[BUFSIZ];
Chris PeBenito 473ea7
	char *inbuf=NULL;
Chris PeBenito 473ea7
	
Chris PeBenito 473ea7
	/* Open file */
Chris PeBenito 473ea7
	const char *bool_file = selinux_booleans_path();
Chris PeBenito 473ea7
	char local_bool_file[PATH_MAX];
Chris PeBenito 473ea7
	char tmp_bool_file[PATH_MAX]; 
Chris PeBenito 473ea7
	FILE *boolf;
Chris PeBenito 473ea7
	int fd;
Chris PeBenito 473ea7
	int *used= (int *) malloc (sizeof(int) * boolcnt);
Chris PeBenito 473ea7
	if (! used) {
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	/* zero out used field */
Chris PeBenito 473ea7
	for (i=0; i < boolcnt; i++)
Chris PeBenito 473ea7
		used[i]=0;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	snprintf(tmp_bool_file,sizeof(tmp_bool_file),"%s.XXXXXX", bool_file);
Chris PeBenito 473ea7
	fd = mkstemp(tmp_bool_file);
Chris PeBenito 473ea7
	if (fd < 0) { 
Chris PeBenito 473ea7
		free(used);
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	snprintf(local_bool_file,sizeof(local_bool_file),"%s.local", bool_file);	boolf = fopen(local_bool_file,"r");
Chris PeBenito 473ea7
	if (boolf != NULL) {
Chris PeBenito 473ea7
		ssize_t ret;
Chris PeBenito 473ea7
		size_t size=0;
Chris PeBenito 473ea7
		int val;
Chris PeBenito 473ea7
		char boolname[BUFSIZ];
Chris PeBenito 473ea7
		char *buffer;
Chris PeBenito 473ea7
		char *inbuf=NULL;
Chris PeBenito 473ea7
		while ((len=getline(&inbuf, &size, boolf)) > 0) {
Chris PeBenito 473ea7
			buffer=strdup(inbuf);
Chris PeBenito 473ea7
			if (!buffer) goto close_remove_fail;
Chris PeBenito 473ea7
			ret=process_boolean(inbuf, boolname, sizeof(boolname), &val;;
Chris PeBenito 473ea7
			if (ret!=1) { 
Chris PeBenito 473ea7
				ret=write(fd, buffer, len);
Chris PeBenito 473ea7
				free(buffer);
Chris PeBenito 473ea7
				if (ret != len) 
Chris PeBenito 473ea7
					goto close_remove_fail;
Chris PeBenito 473ea7
			} else {
Chris PeBenito 473ea7
				free(buffer);
Chris PeBenito 473ea7
				for (i=0; i < boolcnt; i++) {
Chris PeBenito 473ea7
					if (strcmp(boollist[i].name, boolname)==0) {
Chris PeBenito 473ea7
						snprintf(outbuf,sizeof(outbuf), "%s=%d\n", boolname, boollist[i].value); 
Chris PeBenito 473ea7
						len=strlen(outbuf);
Chris PeBenito 473ea7
						used[i]=1;
Chris PeBenito 473ea7
						if (write(fd, outbuf, len) != len) 
Chris PeBenito 473ea7
							goto close_remove_fail;
Chris PeBenito 473ea7
						else 
Chris PeBenito 473ea7
							break;
Chris PeBenito 473ea7
					}
Chris PeBenito 473ea7
				}
Chris PeBenito 473ea7
				if ( i == boolcnt ) {
Chris PeBenito 473ea7
					snprintf(outbuf,sizeof(outbuf), "%s=%d\n", boolname, val); 
Chris PeBenito 473ea7
					len=strlen(outbuf);
Chris PeBenito 473ea7
					if (write(fd, outbuf, len) != len) 
Chris PeBenito 473ea7
						goto close_remove_fail;
Chris PeBenito 473ea7
				}
Chris PeBenito 473ea7
			}
Chris PeBenito 473ea7
			free(inbuf);
Chris PeBenito 473ea7
			inbuf=NULL;
Chris PeBenito 473ea7
		}
Chris PeBenito 473ea7
		fclose(boolf);
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	
Chris PeBenito 473ea7
	for (i=0; i < boolcnt; i++) {
Chris PeBenito 473ea7
		if (used[i]==0) {
Chris PeBenito 473ea7
			snprintf(outbuf,sizeof(outbuf), "%s=%d\n", boollist[i].name, boollist[i].value); 
Chris PeBenito 473ea7
			len=strlen(outbuf);
Chris PeBenito 473ea7
			if (write(fd, outbuf, len) != len) {
Chris PeBenito 473ea7
			close_remove_fail:
Chris PeBenito 473ea7
				free(inbuf);
Chris PeBenito 473ea7
				close(fd);
Chris PeBenito 473ea7
			remove_fail:
Chris PeBenito 473ea7
				unlink(tmp_bool_file);
Chris PeBenito 473ea7
				free(used);
Chris PeBenito 473ea7
				return -1;
Chris PeBenito 473ea7
			}
Chris PeBenito 473ea7
		}
Chris PeBenito 473ea7
		
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	if (fchmod(fd, S_IRUSR | S_IWUSR) != 0)
Chris PeBenito 473ea7
		goto close_remove_fail;
Chris PeBenito 473ea7
	close(fd);
Chris PeBenito 473ea7
	if (rename(tmp_bool_file, local_bool_file) != 0)
Chris PeBenito 473ea7
		goto remove_fail;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	free(used);
Chris PeBenito 473ea7
	return 0;
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
static void rollback(SELboolean *boollist, int end)
Chris PeBenito 473ea7
{
Chris PeBenito 473ea7
	int i;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
        for(i=0; i
Chris PeBenito 473ea7
                security_set_boolean(boollist[i].name,
Chris PeBenito 473ea7
                        security_get_boolean_active(boollist[i].name));
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
Chris PeBenito 473ea7
int security_set_boolean_list(size_t boolcnt, SELboolean *boollist, int permanent) {
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	size_t i;
Chris PeBenito 473ea7
	for (i=0; i < boolcnt; i++) {
Chris PeBenito 473ea7
		if(security_set_boolean(boollist[i].name, boollist[i].value)) {
Chris PeBenito 473ea7
			rollback(boollist, i);
Chris PeBenito 473ea7
			return -1;
Chris PeBenito 473ea7
		}
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	/* OK, let's do the commit */
Chris PeBenito 473ea7
	if (security_commit_booleans()) {
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (permanent) 
Chris PeBenito 473ea7
		return save_booleans(boolcnt, boollist);
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	return 0;
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
int security_load_booleans(char *path) {
Chris PeBenito 473ea7
	FILE *boolf;
Chris PeBenito 473ea7
	char *inbuf;
Chris PeBenito 473ea7
	char localbools[BUFSIZ];
Chris PeBenito 473ea7
	size_t len=0, errors=0;
Chris PeBenito 473ea7
	int val;
Chris PeBenito 473ea7
	char name[BUFSIZ];
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	boolf = fopen(path ? path : selinux_booleans_path(),"r");
Chris PeBenito 473ea7
	if (boolf == NULL) 
Chris PeBenito 473ea7
	  goto localbool;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	while (getline(&inbuf, &len, boolf) > 0) {
Chris PeBenito 473ea7
		int ret=process_boolean(inbuf, name, sizeof(name), &val;;
Chris PeBenito 473ea7
		if (ret==-1) 
Chris PeBenito 473ea7
			errors++;
Chris PeBenito 473ea7
		if (ret==1) 
Chris PeBenito 473ea7
			if (security_set_boolean(name, val) < 0) {
Chris PeBenito 473ea7
				errors++;
Chris PeBenito 473ea7
			}
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	fclose(boolf);
Chris PeBenito 473ea7
localbool:
Chris PeBenito 473ea7
	snprintf(localbools,sizeof(localbools), "%s.local", (path ? path : selinux_booleans_path()));
Chris PeBenito 473ea7
	boolf = fopen(localbools,"r");
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (boolf != NULL) {
Chris PeBenito 473ea7
		int ret;
Chris PeBenito 473ea7
		while (getline(&inbuf, &len, boolf) > 0) {
Chris PeBenito 473ea7
			ret=process_boolean(inbuf, name, sizeof(name), &val;;
Chris PeBenito 473ea7
			if (ret==-1) 
Chris PeBenito 473ea7
				errors++;
Chris PeBenito 473ea7
			if (ret==1) 
Chris PeBenito 473ea7
				if (security_set_boolean(name, val) < 0) {
Chris PeBenito 473ea7
					errors++;
Chris PeBenito 473ea7
				}
Chris PeBenito 473ea7
		}
Chris PeBenito 473ea7
		fclose(boolf);
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	if (security_commit_booleans() < 0)
Chris PeBenito 473ea7
		return -1;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (errors)
Chris PeBenito 473ea7
		errno = EINVAL;
Chris PeBenito 473ea7
	return errors ? -1 : 0;
Chris PeBenito 473ea7
}