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