Chris PeBenito 473ea7
#include <unistd.h>
Chris PeBenito 473ea7
#include <stdlib.h>
Chris PeBenito 473ea7
#include <stdio.h>
Chris PeBenito 473ea7
#include <string.h>
Chris PeBenito 473ea7
#include <sys/stat.h>
Chris PeBenito 473ea7
#include <fcntl.h>
Chris PeBenito 473ea7
#include <errno.h>
Chris PeBenito 473ea7
#include <syslog.h>
Chris PeBenito 473ea7
#include <pwd.h>
Chris PeBenito 473ea7
#include <selinux/selinux.h>
Chris PeBenito 473ea7
#include <errno.h>
Chris PeBenito 473ea7
Chris PeBenito 473ea7
int permanent = 0;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
int setbool(char **list, size_t start, size_t end);
Chris PeBenito 473ea7
Chris PeBenito 473ea7
Chris PeBenito 473ea7
void usage(void)
Chris PeBenito 473ea7
{
Chris PeBenito 473ea7
	fputs("\nUsage:  setsebool [ -P ] boolean value | bool1=val1 bool2=val2...\n\n", stderr);
Chris PeBenito 473ea7
	exit(1);
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
int main(int argc, char **argv)
Chris PeBenito 473ea7
{
Chris PeBenito 473ea7
	size_t rc, start;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (argc < 2) 
Chris PeBenito 473ea7
		usage();
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (is_selinux_enabled() <= 0) {
Chris PeBenito 473ea7
		fputs("setsebool:  SELinux is disabled.\n", stderr);
Chris PeBenito 473ea7
		return 1;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (strcmp(argv[1], "-P") == 0) {
Chris PeBenito 473ea7
		permanent = 1;
Chris PeBenito 473ea7
		if (argc < 3) 
Chris PeBenito 473ea7
			usage();
Chris PeBenito 473ea7
		start = 2;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	else
Chris PeBenito 473ea7
		start = 1;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	/* Check to see which way we are being called. If a '=' is passed,
Chris PeBenito 473ea7
	   we'll enforce the list syntax. If not we'll enforce the original
Chris PeBenito 473ea7
	   syntax for backward compatibility. */
Chris PeBenito 473ea7
	if (strchr(argv[start], '=') == 0) {
Chris PeBenito 473ea7
		int len;
Chris PeBenito 473ea7
		char *bool_list[1];
Chris PeBenito 473ea7
Chris PeBenito 473ea7
		if ((argc - start) != 2)
Chris PeBenito 473ea7
			usage();
Chris PeBenito 473ea7
Chris PeBenito 473ea7
		/* Add 1 for the '=' */
Chris PeBenito 473ea7
		len = strlen(argv[start]) + strlen(argv[start+1]) + 2;
Chris PeBenito 473ea7
		bool_list[0]=(char *)malloc(len);
Chris PeBenito 473ea7
		if (bool_list[0] == 0) {
Chris PeBenito 473ea7
			fputs("Out of memory - aborting\n", stderr);
Chris PeBenito 473ea7
			return 1;
Chris PeBenito 473ea7
		}
Chris PeBenito 473ea7
		snprintf(bool_list[0], len, "%s=%s", argv[start], 
Chris PeBenito 473ea7
							argv[start+1]);
Chris PeBenito 473ea7
		rc = setbool(bool_list, 0, 1);
Chris PeBenito 473ea7
		free(bool_list[0]);
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	else 
Chris PeBenito 473ea7
		rc = setbool(argv, start, argc);
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	return rc;
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
/* Given an array of strings in the form "boolname=value", a start index,
Chris PeBenito 473ea7
   and a finish index...walk the list and set the bool. */
Chris PeBenito 473ea7
int setbool(char **list, size_t start, size_t end)
Chris PeBenito 473ea7
{
Chris PeBenito 473ea7
	char *name, *value_ptr;
Chris PeBenito 473ea7
	int i=start, value;
Chris PeBenito 473ea7
	int ret=0;
Chris PeBenito 473ea7
	int j=0;
Chris PeBenito 473ea7
	size_t boolcnt=end-start;
Chris PeBenito 473ea7
	struct passwd *pwd;
Chris PeBenito 473ea7
	SELboolean *vallist=calloc(boolcnt, sizeof(SELboolean));
Chris PeBenito 473ea7
	if (!vallist) {
Chris PeBenito 473ea7
		fprintf(stderr, 
Chris PeBenito 473ea7
			"Error setting booleans: %s\n", strerror(errno));
Chris PeBenito 473ea7
		return 1;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
	while (i < end) {
Chris PeBenito 473ea7
		name = list[i];
Chris PeBenito 473ea7
		value_ptr = strchr(list[i], '=');
Chris PeBenito 473ea7
		if (value_ptr == 0) {
Chris PeBenito 473ea7
			fprintf(stderr, 
Chris PeBenito 473ea7
			"setsebool: '=' not found in boolean expression %s\n",
Chris PeBenito 473ea7
				list[i]);
Chris PeBenito 473ea7
			ret=4;
Chris PeBenito 473ea7
			goto error_label;
Chris PeBenito 473ea7
		}
Chris PeBenito 473ea7
		*value_ptr = 0;
Chris PeBenito 473ea7
		value_ptr++;
Chris PeBenito 473ea7
		if (strcmp(value_ptr, "1") == 0 || 
Chris PeBenito 473ea7
				strcasecmp(value_ptr, "true") == 0)
Chris PeBenito 473ea7
			value = 1;
Chris PeBenito 473ea7
		else if (strcmp(value_ptr, "0") == 0 || 
Chris PeBenito 473ea7
				strcasecmp(value_ptr, "false") == 0)
Chris PeBenito 473ea7
			value = 0;
Chris PeBenito 473ea7
		else {
Chris PeBenito 473ea7
			fprintf(stderr, "setsebool: illegal boolean value %s\n",
Chris PeBenito 473ea7
				value_ptr);
Chris PeBenito 473ea7
			ret=1;
Chris PeBenito 473ea7
			goto error_label;
Chris PeBenito 473ea7
		}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
		vallist[j].value = value;
Chris PeBenito 473ea7
		vallist[j].name = strdup(name);
Chris PeBenito 473ea7
		if (!vallist[j].name) {
Chris PeBenito 473ea7
			fprintf(stderr, 
Chris PeBenito 473ea7
				"Error setting boolean %s to value %d (%s)\n", 
Chris PeBenito 473ea7
				name, value, strerror(errno));
Chris PeBenito 473ea7
			ret= 2;
Chris PeBenito 473ea7
			goto error_label;
Chris PeBenito 473ea7
		}
Chris PeBenito 473ea7
		i++;
Chris PeBenito 473ea7
		j++;
Chris PeBenito 473ea7
Chris PeBenito 473ea7
		/* Now put it back */
Chris PeBenito 473ea7
		value_ptr--;
Chris PeBenito 473ea7
		*value_ptr = '=';
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	ret=security_set_boolean_list(boolcnt, vallist, permanent);
Chris PeBenito 473ea7
Chris PeBenito 473ea7
 error_label:
Chris PeBenito 473ea7
	for (i=0; i < boolcnt; i++) 
Chris PeBenito 473ea7
		if (vallist[i].name) free(vallist[i].name);
Chris PeBenito 473ea7
	free(vallist);
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	if (ret) {
Chris PeBenito 473ea7
		if (errno==ENOENT) {
Chris PeBenito 473ea7
			fprintf(stderr, 
Chris PeBenito 473ea7
				"Error setting boolean: Invalid boolean\n");
Chris PeBenito 473ea7
		} else {
Chris PeBenito 473ea7
			if (errno) 
Chris PeBenito 473ea7
				perror("Error setting booleans");
Chris PeBenito 473ea7
		}
Chris PeBenito 473ea7
		return ret;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	/* Now log what was done */
Chris PeBenito 473ea7
	pwd = getpwuid(getuid());
Chris PeBenito 473ea7
	i = start;
Chris PeBenito 473ea7
	while (i < end) {
Chris PeBenito 473ea7
		/* Error checking shouldn't be needed since we just did
Chris PeBenito 473ea7
		   this above and aborted if something went wrong. */
Chris PeBenito 473ea7
		name = list[i];
Chris PeBenito 473ea7
		value_ptr = strchr(name, '=');
Chris PeBenito 473ea7
		*value_ptr = 0;
Chris PeBenito 473ea7
		value_ptr++;
Chris PeBenito 473ea7
		if (pwd && pwd->pw_name)
Chris PeBenito 473ea7
			syslog(LOG_NOTICE, 
Chris PeBenito 473ea7
			    "The %s policy boolean was changed to %s by %s",
Chris PeBenito 473ea7
				name, value_ptr, pwd->pw_name);
Chris PeBenito 473ea7
		else
Chris PeBenito 473ea7
			syslog(LOG_NOTICE, 
Chris PeBenito 473ea7
			    "The %s policy boolean was changed to %s by uid:%d",
Chris PeBenito 473ea7
				name, value_ptr, getuid());
Chris PeBenito 473ea7
		i++;
Chris PeBenito 473ea7
	}
Chris PeBenito 473ea7
Chris PeBenito 473ea7
	return 0;
Chris PeBenito 473ea7
}
Chris PeBenito 473ea7