|
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 |
|