113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/*
213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Author: Karl MacMillan <kmacmillan@tresys.com>
313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *
413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Modified:
513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *   Dan Walsh <dwalsh@redhat.com> - Added security_load_booleans().
613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */
713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8a79621874991f3bffd1a15ea70d7fd6ed9f0019bWilliam Roberts#ifndef DISABLE_BOOL
9a79621874991f3bffd1a15ea70d7fd6ed9f0019bWilliam Roberts
1088c35241535803247bd3044187c6c3b3c7f02c79Eric Paris#include <assert.h>
1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/types.h>
1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/stat.h>
1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <fcntl.h>
1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h>
1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <dirent.h>
1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <string.h>
1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdio.h>
1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdio_ext.h>
1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <unistd.h>
2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <fnmatch.h>
2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <limits.h>
2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <ctype.h>
2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <errno.h>
2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "selinux_internal.h"
2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "policy.h"
2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define SELINUX_BOOL_DIR "/booleans/"
2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int filename_select(const struct dirent *d)
3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (d->d_name[0] == '.'
3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	    && (d->d_name[1] == '\0'
3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		|| (d->d_name[1] == '.' && d->d_name[2] == '\0')))
3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 0;
3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 1;
3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint security_get_boolean_names(char ***names, int *len)
4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char path[PATH_MAX];
4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int i, rc;
4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	struct dirent **namelist;
4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char **n;
4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4698234cf543474b8998c654cfc5b1d1cbc738c38bRichard Haines	if (!len || names == NULL) {
4798234cf543474b8998c654cfc5b1d1cbc738c38bRichard Haines		errno = EINVAL;
4898234cf543474b8998c654cfc5b1d1cbc738c38bRichard Haines		return -1;
4998234cf543474b8998c654cfc5b1d1cbc738c38bRichard Haines	}
5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!selinux_mnt) {
5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		errno = ENOENT;
5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	snprintf(path, sizeof path, "%s%s", selinux_mnt, SELINUX_BOOL_DIR);
5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*len = scandir(path, &namelist, &filename_select, alphasort);
5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (*len <= 0) {
5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	n = (char **)malloc(sizeof(char *) * *len);
6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!n) {
6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		rc = -1;
6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto bad;
6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (i = 0; i < *len; i++) {
68d88597798fdb1a2b344ca47e48f2f80ad433fd95William Roberts		n[i] = strdup(namelist[i]->d_name);
6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (!n[i]) {
7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			rc = -1;
7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto bad_freen;
7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	rc = 0;
7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	*names = n;
7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      out:
7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (i = 0; i < *len; i++) {
7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		free(namelist[i]);
7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(namelist);
8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return rc;
8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      bad_freen:
8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (--i; i >= 0; --i)
8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		free(n[i]);
8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(n);
8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      bad:
8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	goto out;
8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
90ee6901618c9da360515474145504c7b58258441fDan Walshchar *selinux_boolean_sub(const char *name)
9188c35241535803247bd3044187c6c3b3c7f02c79Eric Paris{
9288c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	char *sub = NULL;
9388c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	char *line_buf = NULL;
9488c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	size_t line_len;
9588c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	FILE *cfg;
9688c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
9788c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	if (!name)
9888c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		return NULL;
9988c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
10064afa1aff1cd610d2493f780e2a44b551f668b84Nick Kralevich	cfg = fopen(selinux_booleans_subs_path(), "re");
10188c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	if (!cfg)
10288c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		goto out;
10388c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
10488c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	while (getline(&line_buf, &line_len, cfg) != -1) {
10588c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		char *ptr;
10688c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		char *src = line_buf;
10788c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		char *dst;
10888c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		while (*src && isspace(*src))
10988c35241535803247bd3044187c6c3b3c7f02c79Eric Paris			src++;
11088c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		if (!*src)
11188c35241535803247bd3044187c6c3b3c7f02c79Eric Paris			continue;
11288c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		if (src[0] == '#')
11388c35241535803247bd3044187c6c3b3c7f02c79Eric Paris			continue;
11488c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
11588c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		ptr = src;
11688c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		while (*ptr && !isspace(*ptr))
11788c35241535803247bd3044187c6c3b3c7f02c79Eric Paris			ptr++;
11888c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		*ptr++ = '\0';
11988c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		if (strcmp(src, name) != 0)
12088c35241535803247bd3044187c6c3b3c7f02c79Eric Paris			continue;
12188c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
12288c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		dst = ptr;
12388c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		while (*dst && isspace(*dst))
12488c35241535803247bd3044187c6c3b3c7f02c79Eric Paris			dst++;
12588c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		if (!*dst)
12688c35241535803247bd3044187c6c3b3c7f02c79Eric Paris			continue;
12788c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		ptr=dst;
12888c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		while (*ptr && !isspace(*ptr))
12988c35241535803247bd3044187c6c3b3c7f02c79Eric Paris			ptr++;
13088c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		*ptr='\0';
13188c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
13288c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		sub = strdup(dst);
13388c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
13488c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		break;
13588c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	}
13688c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	free(line_buf);
13788c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	fclose(cfg);
13888c35241535803247bd3044187c6c3b3c7f02c79Eric Parisout:
13988c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	if (!sub)
14088c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		sub = strdup(name);
14188c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	return sub;
14288c35241535803247bd3044187c6c3b3c7f02c79Eric Paris}
14388c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
14488c35241535803247bd3044187c6c3b3c7f02c79Eric Parisstatic int bool_open(const char *name, int flag) {
14588c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	char *fname = NULL;
14688c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	char *alt_name = NULL;
14788c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	int len;
14888c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	int fd = -1;
14988c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	int ret;
15088c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	char *ptr;
15188c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
15288c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	if (!name) {
15388c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		errno = EINVAL;
15488c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		return -1;
15588c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	}
15688c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
15788c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	/* note the 'sizeof' gets us enough room for the '\0' */
15888c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	len = strlen(name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR);
15988c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	fname = malloc(sizeof(char) * len);
16088c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	if (!fname)
16188c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		return -1;
16288c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
16388c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	ret = snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, name);
16488c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	if (ret < 0)
16588c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		goto out;
16688c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	assert(ret < len);
16788c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
16888c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	fd = open(fname, flag);
16988c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	if (fd >= 0 || errno != ENOENT)
17088c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		goto out;
17188c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
172ee6901618c9da360515474145504c7b58258441fDan Walsh	alt_name = selinux_boolean_sub(name);
17388c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	if (!alt_name)
17488c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		goto out;
17588c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
17688c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	/* note the 'sizeof' gets us enough room for the '\0' */
17788c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	len = strlen(alt_name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR);
17888c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	ptr = realloc(fname, len);
17988c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	if (!ptr)
18088c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		goto out;
18188c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	fname = ptr;
18288c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
18388c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	ret = snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, alt_name);
18488c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	if (ret < 0)
18588c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		goto out;
18688c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	assert(ret < len);
18788c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
18888c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	fd = open(fname, flag);
18988c35241535803247bd3044187c6c3b3c7f02c79Eric Parisout:
19088c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	free(fname);
19188c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	free(alt_name);
19288c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
19388c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	return fd;
19488c35241535803247bd3044187c6c3b3c7f02c79Eric Paris}
19588c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define STRBUF_SIZE 3
19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int get_bool_value(const char *name, char **buf)
19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int fd, len;
20088c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	int errno_tmp;
20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
20213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!selinux_mnt) {
20313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		errno = ENOENT;
20413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
20788c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	*buf = malloc(sizeof(char) * (STRBUF_SIZE + 1));
20813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!*buf)
20988c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		return -1;
21013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
21188c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	(*buf)[STRBUF_SIZE] = 0;
21213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
21364afa1aff1cd610d2493f780e2a44b551f668b84Nick Kralevich	fd = bool_open(name, O_RDONLY | O_CLOEXEC);
21413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (fd < 0)
21588c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		goto out_err;
21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
21713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	len = read(fd, *buf, STRBUF_SIZE);
21888c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	errno_tmp = errno;
21913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	close(fd);
22088c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	errno = errno_tmp;
22113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (len != STRBUF_SIZE)
22288c35241535803247bd3044187c6c3b3c7f02c79Eric Paris		goto out_err;
22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 0;
22588c35241535803247bd3044187c6c3b3c7f02c79Eric Parisout_err:
22688c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	free(*buf);
22713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return -1;
22813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
22913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
23013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint security_get_boolean_pending(const char *name)
23113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
23213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *buf;
23313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int val;
23413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
23513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (get_bool_value(name, &buf))
23613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
23713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
23813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (atoi(&buf[1]))
23913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		val = 1;
24013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	else
24113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		val = 0;
24213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(buf);
24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return val;
24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
24513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
24613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint security_get_boolean_active(const char *name)
24713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
24813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *buf;
24913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int val;
25013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
25113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (get_bool_value(name, &buf))
25213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
25313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
25413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	buf[1] = '\0';
25513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (atoi(buf))
25613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		val = 1;
25713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	else
25813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		val = 0;
25913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(buf);
26013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return val;
26113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
26213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
26313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint security_set_boolean(const char *name, int value)
26413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
26588c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	int fd, ret;
26688c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	char buf[2];
26713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
26813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!selinux_mnt) {
26913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		errno = ENOENT;
27013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
27113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
27213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (value < 0 || value > 1) {
27313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		errno = EINVAL;
27413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
27513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
27613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
27764afa1aff1cd610d2493f780e2a44b551f668b84Nick Kralevich	fd = bool_open(name, O_WRONLY | O_CLOEXEC);
27888c35241535803247bd3044187c6c3b3c7f02c79Eric Paris	if (fd < 0)
27913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
28013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
28113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (value)
28213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		buf[0] = '1';
28313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	else
28413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		buf[0] = '0';
28513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	buf[1] = '\0';
28613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
28713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ret = write(fd, buf, 2);
28813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	close(fd);
28988c35241535803247bd3044187c6c3b3c7f02c79Eric Paris
29013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (ret > 0)
29113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 0;
29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	else
29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
29413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
29513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
29613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint security_commit_booleans(void)
29713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
29813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int fd, ret;
29913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char buf[2];
30013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char path[PATH_MAX];
30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
30213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!selinux_mnt) {
30313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		errno = ENOENT;
30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
30513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
30613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
30713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	snprintf(path, sizeof path, "%s/commit_pending_bools", selinux_mnt);
30864afa1aff1cd610d2493f780e2a44b551f668b84Nick Kralevich	fd = open(path, O_WRONLY | O_CLOEXEC);
30913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (fd < 0)
31013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
31113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
31213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	buf[0] = '1';
31313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	buf[1] = '\0';
31413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
31513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ret = write(fd, buf, 2);
31613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	close(fd);
31713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
31813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (ret > 0)
31913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return 0;
32013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	else
32113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
32213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
32313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
32413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic char *strtrim(char *dest, char *source, int size)
32513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
32613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int i = 0;
32713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *ptr = source;
32813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	i = 0;
32913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	while (isspace(*ptr) && i < size) {
33013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ptr++;
33113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		i++;
33213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
33313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	strncpy(dest, ptr, size);
33413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (i = strlen(dest) - 1; i > 0; i--) {
33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (!isspace(dest[i]))
33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			break;
33713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
33813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	dest[i + 1] = '\0';
33913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return dest;
34013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
34113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int process_boolean(char *buffer, char *name, int namesize, int *val)
34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char name1[BUFSIZ];
344b2d86f82196e26e6d62443a6e216c5c807d03018Eric Paris	char *ptr = NULL;
345c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	char *tok;
34613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
347c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	/* Skip spaces */
348c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	while (isspace(buffer[0]))
349c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss		buffer++;
350c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	/* Ignore comments */
351c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	if (buffer[0] == '#')
352c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss		return 0;
353c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss
354c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	tok = strtok_r(buffer, "=", &ptr);
355c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	if (!tok) {
356c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss		errno = EINVAL;
357c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss		return -1;
358c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	}
359c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	strncpy(name1, tok, BUFSIZ - 1);
360c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	strtrim(name, name1, namesize - 1);
361c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss
362c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	tok = strtok_r(NULL, "\0", &ptr);
363c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	if (!tok) {
364c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss		errno = EINVAL;
365c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss		return -1;
366c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	}
367c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss
368c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	while (isspace(*tok))
369c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss		tok++;
370c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss
371c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	*val = -1;
372c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	if (isdigit(tok[0]))
373c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss		*val = atoi(tok);
374c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	else if (!strncasecmp(tok, "true", sizeof("true") - 1))
375c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss		*val = 1;
376c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	else if (!strncasecmp(tok, "false", sizeof("false") - 1))
377c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss		*val = 0;
378c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss	if (*val != 0 && *val != 1) {
379c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss		errno = EINVAL;
380c09fb32384ec3808a9dd668bed4c605f4c28f420Nicolas Iooss		return -1;
38113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
38213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 1;
38313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
38413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int save_booleans(size_t boolcnt, SELboolean * boollist)
38513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
38613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ssize_t len;
38713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	size_t i;
38813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char outbuf[BUFSIZ];
38913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *inbuf = NULL;
39013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
39113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Open file */
39213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	const char *bool_file = selinux_booleans_path();
39313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char local_bool_file[PATH_MAX];
39413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char tmp_bool_file[PATH_MAX];
39513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	FILE *boolf;
39613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int fd;
39713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int *used = (int *)malloc(sizeof(int) * boolcnt);
39813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!used) {
39913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
40013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
40113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* zero out used field */
40213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (i = 0; i < boolcnt; i++)
40313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		used[i] = 0;
40413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
40513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	snprintf(tmp_bool_file, sizeof(tmp_bool_file), "%s.XXXXXX", bool_file);
40613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	fd = mkstemp(tmp_bool_file);
40713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (fd < 0) {
40813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		free(used);
40913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
41013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
41113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
41213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	snprintf(local_bool_file, sizeof(local_bool_file), "%s.local",
41313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		 bool_file);
41464afa1aff1cd610d2493f780e2a44b551f668b84Nick Kralevich	boolf = fopen(local_bool_file, "re");
41513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (boolf != NULL) {
41613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		ssize_t ret;
41713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		size_t size = 0;
41813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		int val;
41913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		char boolname[BUFSIZ];
42013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		char *buffer;
42113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		inbuf = NULL;
42213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		__fsetlocking(boolf, FSETLOCKING_BYCALLER);
42313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		while ((len = getline(&inbuf, &size, boolf)) > 0) {
42413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			buffer = strdup(inbuf);
42513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (!buffer)
42613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				goto close_remove_fail;
42713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			ret =
42813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			    process_boolean(inbuf, boolname, sizeof(boolname),
42913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					    &val);
43013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (ret != 1) {
43113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				ret = write(fd, buffer, len);
43213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				free(buffer);
43313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				if (ret != len)
43413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					goto close_remove_fail;
43513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			} else {
43613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				free(buffer);
43713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				for (i = 0; i < boolcnt; i++) {
43813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					if (strcmp(boollist[i].name, boolname)
43913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					    == 0) {
44013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle						snprintf(outbuf, sizeof(outbuf),
44113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle							 "%s=%d\n", boolname,
44213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle							 boollist[i].value);
44313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle						len = strlen(outbuf);
44413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle						used[i] = 1;
44513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle						if (write(fd, outbuf, len) !=
44613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle						    len)
44713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle							goto close_remove_fail;
44813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle						else
44913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle							break;
45013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					}
45113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				}
45213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				if (i == boolcnt) {
45313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					snprintf(outbuf, sizeof(outbuf),
45413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle						 "%s=%d\n", boolname, val);
45513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					len = strlen(outbuf);
45613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					if (write(fd, outbuf, len) != len)
45713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle						goto close_remove_fail;
45813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				}
45913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
46013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			free(inbuf);
46113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			inbuf = NULL;
46213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
46313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fclose(boolf);
46413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
46513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
46613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (i = 0; i < boolcnt; i++) {
46713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (used[i] == 0) {
46813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			snprintf(outbuf, sizeof(outbuf), "%s=%d\n",
46913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				 boollist[i].name, boollist[i].value);
47013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			len = strlen(outbuf);
47113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (write(fd, outbuf, len) != len) {
47213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			      close_remove_fail:
47313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				free(inbuf);
47413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				close(fd);
47513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			      remove_fail:
47613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				unlink(tmp_bool_file);
47713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				free(used);
47813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				return -1;
47913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
48013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
48113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
48213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
48313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (fchmod(fd, S_IRUSR | S_IWUSR) != 0)
48413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto close_remove_fail;
48513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	close(fd);
48613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (rename(tmp_bool_file, local_bool_file) != 0)
48713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto remove_fail;
48813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
48913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	free(used);
49013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 0;
49113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
49213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic void rollback(SELboolean * boollist, int end)
49313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
49413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int i;
49513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
49613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (i = 0; i < end; i++)
49713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		security_set_boolean(boollist[i].name,
49813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				     security_get_boolean_active(boollist[i].
49913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle								 name));
50013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
50113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
50213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint security_set_boolean_list(size_t boolcnt, SELboolean * boollist,
50313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			      int permanent)
50413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
50513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
50613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	size_t i;
50713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	for (i = 0; i < boolcnt; i++) {
50813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (security_set_boolean(boollist[i].name, boollist[i].value)) {
50913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			rollback(boollist, i);
51013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			return -1;
51113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
51213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
51313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
51413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* OK, let's do the commit */
51513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (security_commit_booleans()) {
51613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
51713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
51813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
51913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (permanent)
52013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return save_booleans(boolcnt, boollist);
52113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
52213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 0;
52313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
52413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint security_load_booleans(char *path)
52513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
52613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	FILE *boolf;
52713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *inbuf;
52813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char localbools[BUFSIZ];
52913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	size_t len = 0, errors = 0;
53013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int val;
53113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char name[BUFSIZ];
53213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
53364afa1aff1cd610d2493f780e2a44b551f668b84Nick Kralevich	boolf = fopen(path ? path : selinux_booleans_path(), "re");
53413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (boolf == NULL)
53513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto localbool;
53613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
53713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	__fsetlocking(boolf, FSETLOCKING_BYCALLER);
53813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	while (getline(&inbuf, &len, boolf) > 0) {
53913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		int ret = process_boolean(inbuf, name, sizeof(name), &val);
54013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (ret == -1)
54113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			errors++;
54213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (ret == 1)
54313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (security_set_boolean(name, val) < 0) {
54413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				errors++;
54513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
54613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
54713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	fclose(boolf);
54813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      localbool:
54913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	snprintf(localbools, sizeof(localbools), "%s.local",
55013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		 (path ? path : selinux_booleans_path()));
55164afa1aff1cd610d2493f780e2a44b551f668b84Nick Kralevich	boolf = fopen(localbools, "re");
55213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
55313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (boolf != NULL) {
55413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		int ret;
55513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		__fsetlocking(boolf, FSETLOCKING_BYCALLER);
55613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		while (getline(&inbuf, &len, boolf) > 0) {
55713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			ret = process_boolean(inbuf, name, sizeof(name), &val);
55813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (ret == -1)
55913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				errors++;
56013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (ret == 1)
56113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				if (security_set_boolean(name, val) < 0) {
56213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					errors++;
56313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				}
56413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
56513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fclose(boolf);
56613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
56713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (security_commit_booleans() < 0)
56813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
56913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
57013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (errors)
57113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		errno = EINVAL;
57213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return errors ? -1 : 0;
57313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
574adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts
575adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts#else
576a79621874991f3bffd1a15ea70d7fd6ed9f0019bWilliam Roberts
577a79621874991f3bffd1a15ea70d7fd6ed9f0019bWilliam Roberts#include <stdlib.h>
578a79621874991f3bffd1a15ea70d7fd6ed9f0019bWilliam Roberts#include "selinux_internal.h"
579a79621874991f3bffd1a15ea70d7fd6ed9f0019bWilliam Roberts
580adca103639923216475714b08b89c4ee3d88ef6bWilliam Robertsint security_set_boolean_list(size_t boolcnt __attribute__((unused)),
581adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts	SELboolean * boollist __attribute__((unused)),
582adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts	int permanent __attribute__((unused)))
583adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts{
584adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts	return -1;
585adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts}
586adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts
587adca103639923216475714b08b89c4ee3d88ef6bWilliam Robertsint security_load_booleans(char *path __attribute__((unused)))
588adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts{
589adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts	return -1;
590adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts}
591adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts
592adca103639923216475714b08b89c4ee3d88ef6bWilliam Robertsint security_get_boolean_names(char ***names __attribute__((unused)),
593adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts	int *len __attribute__((unused)))
594adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts{
595adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts	return -1;
596adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts}
597adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts
598adca103639923216475714b08b89c4ee3d88ef6bWilliam Robertsint security_get_boolean_pending(const char *name __attribute__((unused)))
599adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts{
600adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts	return -1;
601adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts}
602adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts
603adca103639923216475714b08b89c4ee3d88ef6bWilliam Robertsint security_get_boolean_active(const char *name __attribute__((unused)))
604adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts{
605adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts	return -1;
606adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts}
607adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts
608adca103639923216475714b08b89c4ee3d88ef6bWilliam Robertsint security_set_boolean(const char *name __attribute__((unused)),
609adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts	int value __attribute__((unused)))
610adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts{
611adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts	return -1;
612adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts}
613adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts
614adca103639923216475714b08b89c4ee3d88ef6bWilliam Robertsint security_commit_booleans(void)
615adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts{
616adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts	return -1;
617adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts}
618adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts
619adca103639923216475714b08b89c4ee3d88ef6bWilliam Robertschar *selinux_boolean_sub(const char *name __attribute__((unused)))
620adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts{
621adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts	return NULL;
622adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts}
623adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts#endif
624adca103639923216475714b08b89c4ee3d88ef6bWilliam Roberts
625adca103639923216475714b08b89c4ee3d88ef6bWilliam Robertshidden_def(security_get_boolean_names)
626adca103639923216475714b08b89c4ee3d88ef6bWilliam Robertshidden_def(selinux_boolean_sub)
627adca103639923216475714b08b89c4ee3d88ef6bWilliam Robertshidden_def(security_get_boolean_active)
628adca103639923216475714b08b89c4ee3d88ef6bWilliam Robertshidden_def(security_set_boolean)
629adca103639923216475714b08b89c4ee3d88ef6bWilliam Robertshidden_def(security_commit_booleans)
630