d4088bfa91
- Stop syslogging when restorecon is not changing values
1578 lines
54 KiB
Diff
1578 lines
54 KiB
Diff
diff --git a/policycoreutils/Makefile b/policycoreutils/Makefile
|
|
index 9cfe3bc..e31f7d3 100644
|
|
--- a/policycoreutils/Makefile
|
|
+++ b/policycoreutils/Makefile
|
|
@@ -1,4 +1,4 @@
|
|
-SUBDIRS = setfiles semanage load_policy newrole run_init sandbox secon audit2allow audit2why scripts sestatus semodule_package semodule semodule_link semodule_expand semodule_deps sepolgen-ifgen setsebool po man
|
|
+SUBDIRS = setfiles semanage semanage/default_encoding load_policy newrole run_init sandbox secon audit2allow audit2why scripts sestatus semodule_package semodule semodule_link semodule_expand semodule_deps sepolgen-ifgen setsebool po man
|
|
|
|
INOTIFYH = $(shell ls /usr/include/sys/inotify.h 2>/dev/null)
|
|
|
|
diff --git a/policycoreutils/load_policy/Makefile b/policycoreutils/load_policy/Makefile
|
|
index c90d4dd..37a7a7a 100644
|
|
--- a/policycoreutils/load_policy/Makefile
|
|
+++ b/policycoreutils/load_policy/Makefile
|
|
@@ -18,8 +18,6 @@ install: all
|
|
install -m 755 $(TARGETS) $(SBINDIR)
|
|
test -d $(MANDIR)/man8 || install -m 755 -d $(MANDIR)/man8
|
|
install -m 644 load_policy.8 $(MANDIR)/man8/
|
|
- -mkdir -p $(USRSBINDIR)
|
|
- ln -sf /sbin/load_policy $(USRSBINDIR)/load_policy
|
|
|
|
clean:
|
|
-rm -f $(TARGETS) *.o
|
|
diff --git a/policycoreutils/newrole/newrole.c b/policycoreutils/newrole/newrole.c
|
|
index 99d0ed7..19e20a8 100644
|
|
--- a/policycoreutils/newrole/newrole.c
|
|
+++ b/policycoreutils/newrole/newrole.c
|
|
@@ -543,13 +543,13 @@ static int restore_environment(int preserve_environment,
|
|
#if defined(AUDIT_LOG_PRIV) && !defined(NAMESPACE_PRIV)
|
|
static int drop_capabilities(int full)
|
|
{
|
|
+ uid_t uid = getuid();
|
|
+ if (!uid) return 0;
|
|
+
|
|
capng_clear(CAPNG_SELECT_BOTH);
|
|
if (capng_lock() < 0)
|
|
return -1;
|
|
|
|
- uid_t uid = getuid();
|
|
- if (!uid) return 0;
|
|
-
|
|
/* Change uid */
|
|
if (setresuid(uid, uid, uid)) {
|
|
fprintf(stderr, _("Error changing uid, aborting.\n"));
|
|
@@ -1030,10 +1030,11 @@ int main(int argc, char *argv[])
|
|
* if it makes sense to continue to run newrole, and setting up
|
|
* a scrubbed environment.
|
|
*/
|
|
- if (drop_capabilities(FALSE)) {
|
|
+/* if (drop_capabilities(FALSE)) {
|
|
perror(_("Sorry, newrole failed to drop capabilities\n"));
|
|
return -1;
|
|
}
|
|
+*/
|
|
if (set_signal_handles())
|
|
return -1;
|
|
|
|
diff --git a/policycoreutils/restorecond/restorecond.8 b/policycoreutils/restorecond/restorecond.8
|
|
index 4622d2b..bf8ec87 100644
|
|
--- a/policycoreutils/restorecond/restorecond.8
|
|
+++ b/policycoreutils/restorecond/restorecond.8
|
|
@@ -3,7 +3,7 @@
|
|
restorecond \- daemon that watches for file creation and then sets the default SELinux file context
|
|
|
|
.SH "SYNOPSIS"
|
|
-.B restorecond [\-d] [\-f restorecond_file ] [\-u] [\-v]
|
|
+.B restorecond [\-d] [-h] [\-f restorecond_file ] [\-u] [\-v]
|
|
.P
|
|
|
|
.SH "DESCRIPTION"
|
|
@@ -20,6 +20,9 @@ the correct file context associated with the policy.
|
|
Turns on debugging mode. Application will stay in the foreground and lots of
|
|
debugs messages start printing.
|
|
.TP
|
|
+. B \-h
|
|
+Print usage statement.
|
|
+.TP
|
|
.B \-f restorecond_file
|
|
Use alternative restorecond.conf file.
|
|
.TP
|
|
diff --git a/policycoreutils/restorecond/restorecond.c b/policycoreutils/restorecond/restorecond.c
|
|
index 89f5d97..1762850 100644
|
|
--- a/policycoreutils/restorecond/restorecond.c
|
|
+++ b/policycoreutils/restorecond/restorecond.c
|
|
@@ -121,7 +121,6 @@ static void term_handler()
|
|
static void usage(char *program)
|
|
{
|
|
printf("%s [-d] [-f restorecond_file ] [-u] [-v] \n", program);
|
|
- exit(0);
|
|
}
|
|
|
|
void exitApp(const char *msg)
|
|
@@ -140,6 +139,7 @@ int main(int argc, char **argv)
|
|
{
|
|
int opt;
|
|
struct sigaction sa;
|
|
+ const char *null_array[1] = { NULL };
|
|
|
|
memset(&r_opts, 0, sizeof(r_opts));
|
|
|
|
@@ -160,6 +160,7 @@ int main(int argc, char **argv)
|
|
r_opts.fts_flags = FTS_PHYSICAL;
|
|
r_opts.selabel_opt_validate = NULL;
|
|
r_opts.selabel_opt_path = NULL;
|
|
+ r_opts.selabel_opt_prefixes = null_array;
|
|
r_opts.ignore_enoent = 1;
|
|
|
|
restore_init(&r_opts);
|
|
@@ -176,7 +177,7 @@ int main(int argc, char **argv)
|
|
|
|
exclude_non_seclabel_mounts();
|
|
atexit( done );
|
|
- while ((opt = getopt(argc, argv, "df:uv")) > 0) {
|
|
+ while ((opt = getopt(argc, argv, "hdf:uv")) > 0) {
|
|
switch (opt) {
|
|
case 'd':
|
|
debug_mode = 1;
|
|
@@ -187,11 +188,16 @@ int main(int argc, char **argv)
|
|
case 'u':
|
|
run_as_user = 1;
|
|
break;
|
|
+ case 'h':
|
|
+ usage(argv[0]);
|
|
+ exit(0);
|
|
+ break;
|
|
case 'v':
|
|
r_opts.verbose++;
|
|
break;
|
|
case '?':
|
|
usage(argv[0]);
|
|
+ exit(-1);
|
|
}
|
|
}
|
|
|
|
diff --git a/policycoreutils/restorecond/user.c b/policycoreutils/restorecond/user.c
|
|
index 4257058..f3e431e 100644
|
|
--- a/policycoreutils/restorecond/user.c
|
|
+++ b/policycoreutils/restorecond/user.c
|
|
@@ -118,10 +118,10 @@ io_channel_callback
|
|
|
|
if (condition & G_IO_IN) {
|
|
/* Data is available. */
|
|
- g_io_channel_read
|
|
+ g_io_channel_read_chars
|
|
(source, buffer,
|
|
sizeof (buffer),
|
|
- &bytes_read);
|
|
+ &bytes_read, NULL);
|
|
|
|
if (! bytes_read) {
|
|
/* Sesssion/Terminal Ended */
|
|
@@ -152,7 +152,7 @@ io_channel_callback
|
|
file. */
|
|
|
|
if (condition & G_IO_HUP) {
|
|
- g_io_channel_close (source);
|
|
+ g_io_channel_shutdown (source, 0, NULL);
|
|
exit(0);
|
|
return FALSE;
|
|
}
|
|
diff --git a/policycoreutils/run_init/run_init.c b/policycoreutils/run_init/run_init.c
|
|
index 9db766c..92034be 100644
|
|
--- a/policycoreutils/run_init/run_init.c
|
|
+++ b/policycoreutils/run_init/run_init.c
|
|
@@ -406,6 +406,13 @@ int main(int argc, char *argv[])
|
|
new_context);
|
|
exit(-1);
|
|
}
|
|
+ if (! access("/usr/sbin/open_init_pty", X_OK)) {
|
|
+ if (execvp(argv[1], argv + 1)) {
|
|
+ perror("execvp");
|
|
+ exit(-1);
|
|
+ }
|
|
+ return 0;
|
|
+ }
|
|
/*
|
|
* Do not execvp the command directly from run_init; since it would run
|
|
* under with a pty under sysadm_devpts_t. Instead, we call open_init_tty,
|
|
diff --git a/policycoreutils/sandbox/Makefile b/policycoreutils/sandbox/Makefile
|
|
index b817364..981c56c 100644
|
|
--- a/policycoreutils/sandbox/Makefile
|
|
+++ b/policycoreutils/sandbox/Makefile
|
|
@@ -1,6 +1,5 @@
|
|
# Installation directories.
|
|
PREFIX ?= $(DESTDIR)/usr
|
|
-INITDIR ?= $(DESTDIR)/etc/rc.d/init.d/
|
|
SYSCONFDIR ?= $(DESTDIR)/etc/sysconfig
|
|
LIBDIR ?= $(PREFIX)/lib
|
|
BINDIR ?= $(PREFIX)/bin
|
|
@@ -29,8 +28,6 @@ install: all
|
|
-mkdir -p $(SHAREDIR)
|
|
install -m 755 sandboxX.sh $(SHAREDIR)
|
|
install -m 755 start $(SHAREDIR)
|
|
- -mkdir -p $(INITDIR)
|
|
- install -m 755 sandbox.init $(INITDIR)/sandbox
|
|
-mkdir -p $(SYSCONFDIR)
|
|
install -m 644 sandbox.conf $(SYSCONFDIR)/sandbox
|
|
|
|
diff --git a/policycoreutils/sandbox/sandbox.conf b/policycoreutils/sandbox/sandbox.conf
|
|
index 7c35808..cbab91d 100644
|
|
--- a/policycoreutils/sandbox/sandbox.conf
|
|
+++ b/policycoreutils/sandbox/sandbox.conf
|
|
@@ -1,5 +1,3 @@
|
|
-# Space separate list of homedirs
|
|
-HOMEDIRS="/home"
|
|
# Control group configuration
|
|
NAME=sandbox
|
|
CPUAFFINITY=ALL
|
|
diff --git a/policycoreutils/sandbox/seunshare.c b/policycoreutils/sandbox/seunshare.c
|
|
index c493e98..a084e0e 100644
|
|
--- a/policycoreutils/sandbox/seunshare.c
|
|
+++ b/policycoreutils/sandbox/seunshare.c
|
|
@@ -43,8 +43,8 @@
|
|
#define MS_REC 1<<14
|
|
#endif
|
|
|
|
-#ifndef MS_PRIVATE
|
|
-#define MS_PRIVATE 1<<18
|
|
+#ifndef MS_SLAVE
|
|
+#define MS_SLAVE 1<<19
|
|
#endif
|
|
|
|
#ifndef PACKAGE
|
|
@@ -255,7 +255,7 @@ static int verify_shell(const char *shell_name)
|
|
*/
|
|
static int seunshare_mount(const char *src, const char *dst, struct stat *src_st)
|
|
{
|
|
- int flags = MS_REC;
|
|
+ int flags = 0;
|
|
int is_tmp = 0;
|
|
|
|
if (verbose)
|
|
@@ -267,14 +267,6 @@ static int seunshare_mount(const char *src, const char *dst, struct stat *src_st
|
|
}
|
|
|
|
/* mount directory */
|
|
- if (mount(dst, dst, NULL, MS_BIND | flags, NULL) < 0) {
|
|
- fprintf(stderr, _("Failed to mount %s on %s: %s\n"), dst, dst, strerror(errno));
|
|
- return -1;
|
|
- }
|
|
- if (mount(dst, dst, NULL, MS_PRIVATE | flags, NULL) < 0) {
|
|
- fprintf(stderr, _("Failed to make %s private: %s\n"), dst, strerror(errno));
|
|
- return -1;
|
|
- }
|
|
if (mount(src, dst, NULL, MS_BIND | flags, NULL) < 0) {
|
|
fprintf(stderr, _("Failed to mount %s on %s: %s\n"), src, dst, strerror(errno));
|
|
return -1;
|
|
@@ -288,14 +280,6 @@ static int seunshare_mount(const char *src, const char *dst, struct stat *src_st
|
|
if (verbose)
|
|
printf(_("Mounting /tmp on /var/tmp\n"));
|
|
|
|
- if (mount("/var/tmp", "/var/tmp", NULL, MS_BIND | flags, NULL) < 0) {
|
|
- fprintf(stderr, _("Failed to mount /var/tmp on /var/tmp: %s\n"), strerror(errno));
|
|
- return -1;
|
|
- }
|
|
- if (mount("/var/tmp", "/var/tmp", NULL, MS_PRIVATE | flags, NULL) < 0) {
|
|
- fprintf(stderr, _("Failed to make /var/tmp private: %s\n"), strerror(errno));
|
|
- return -1;
|
|
- }
|
|
if (mount("/tmp", "/var/tmp", NULL, MS_BIND | flags, NULL) < 0) {
|
|
fprintf(stderr, _("Failed to mount /tmp on /var/tmp: %s\n"), strerror(errno));
|
|
return -1;
|
|
@@ -967,6 +951,13 @@ int main(int argc, char **argv) {
|
|
goto childerr;
|
|
}
|
|
|
|
+ /* Remount / as SLAVE so that nothing mounted in the namespace
|
|
+ shows up in the parent */
|
|
+ if (mount("none", "/", NULL, MS_SLAVE | MS_REC , NULL) < 0) {
|
|
+ perror(_("Failed to make / a SLAVE mountpoint\n"));
|
|
+ goto childerr;
|
|
+ }
|
|
+
|
|
/* assume fsuid==ruid after this point */
|
|
setfsuid(uid);
|
|
|
|
diff --git a/policycoreutils/scripts/Makefile b/policycoreutils/scripts/Makefile
|
|
index 17ad6ca..fe6427c 100644
|
|
--- a/policycoreutils/scripts/Makefile
|
|
+++ b/policycoreutils/scripts/Makefile
|
|
@@ -1,7 +1,8 @@
|
|
# Installation directories.
|
|
PREFIX ?= $(DESTDIR)/usr
|
|
BINDIR ?= $(PREFIX)/bin
|
|
-SBINDIR ?= $(PREFIX)/sbin
|
|
+USRSBINDIR ?= $(PREFIX)/sbin
|
|
+SBINDIR ?= $(DESTDIR)/sbin
|
|
MANDIR ?= $(PREFIX)/share/man
|
|
LOCALEDIR ?= /usr/share/locale
|
|
|
|
@@ -10,8 +11,8 @@ all: fixfiles genhomedircon chcat
|
|
install: all
|
|
-mkdir -p $(BINDIR)
|
|
install -m 755 chcat $(BINDIR)
|
|
- install -m 755 fixfiles $(DESTDIR)/sbin
|
|
- install -m 755 genhomedircon $(SBINDIR)
|
|
+ install -m 755 fixfiles $(SBINDIR)
|
|
+ install -m 755 genhomedircon $(USRSBINDIR)
|
|
-mkdir -p $(MANDIR)/man8
|
|
install -m 644 fixfiles.8 $(MANDIR)/man8/
|
|
install -m 644 genhomedircon.8 $(MANDIR)/man8/
|
|
diff --git a/policycoreutils/scripts/fixfiles b/policycoreutils/scripts/fixfiles
|
|
index 27dcccf..445353e 100755
|
|
--- a/policycoreutils/scripts/fixfiles
|
|
+++ b/policycoreutils/scripts/fixfiles
|
|
@@ -121,7 +121,6 @@ LOGFILE=`tty`
|
|
if [ $? != 0 ]; then
|
|
LOGFILE="/dev/null"
|
|
fi
|
|
-SYSLOGFLAG="-l"
|
|
LOGGER=/usr/sbin/logger
|
|
SETFILES=/sbin/setfiles
|
|
RESTORECON=/sbin/restorecon
|
|
@@ -234,7 +233,7 @@ then
|
|
done
|
|
FC=$TEMPFCFILE
|
|
fi
|
|
-${SETFILES} -q ${SYSLOGFLAG} ${FORCEFLAG} $* ${FC} ${FILESYSTEMSRW} 2>&1 | cat >> $LOGFILE
|
|
+${SETFILES} -q ${FORCEFLAG} $* ${FC} ${FILESYSTEMSRW} 2>&1 | cat >> $LOGFILE
|
|
rm -rf /tmp/gconfd-* /tmp/pulse-* /tmp/orbit-* $TEMPFCFILE
|
|
|
|
UNDEFINED=`get_undefined_type` || exit $?
|
|
diff --git a/policycoreutils/scripts/genhomedircon b/policycoreutils/scripts/genhomedircon
|
|
index ab696a7..58b19cd 100644
|
|
--- a/policycoreutils/scripts/genhomedircon
|
|
+++ b/policycoreutils/scripts/genhomedircon
|
|
@@ -1,2 +1,3 @@
|
|
#!/bin/sh
|
|
+
|
|
/usr/sbin/semodule -Bn
|
|
diff --git a/policycoreutils/semanage/default_encoding/Makefile b/policycoreutils/semanage/default_encoding/Makefile
|
|
new file mode 100644
|
|
index 0000000..e15a877
|
|
--- /dev/null
|
|
+++ b/policycoreutils/semanage/default_encoding/Makefile
|
|
@@ -0,0 +1,8 @@
|
|
+all:
|
|
+ LDFLAGS="" python setup.py build
|
|
+
|
|
+install: all
|
|
+ LDFLAGS="" python setup.py install --root=$(DESTDIR)/
|
|
+
|
|
+clean:
|
|
+ rm -rf build *~
|
|
diff --git a/policycoreutils/semanage/default_encoding/default_encoding.c b/policycoreutils/semanage/default_encoding/default_encoding.c
|
|
new file mode 100644
|
|
index 0000000..023b8f4
|
|
--- /dev/null
|
|
+++ b/policycoreutils/semanage/default_encoding/default_encoding.c
|
|
@@ -0,0 +1,57 @@
|
|
+/*
|
|
+ * Authors:
|
|
+ * John Dennis <jdennis@redhat.com>
|
|
+ *
|
|
+ * Copyright (C) 2009 Red Hat
|
|
+ * see file 'COPYING' for use and warranty information
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU General Public License as
|
|
+ * published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
+ */
|
|
+
|
|
+#include <Python.h>
|
|
+
|
|
+PyDoc_STRVAR(setdefaultencoding_doc,
|
|
+"setdefaultencoding(encoding='utf-8')\n\
|
|
+\n\
|
|
+Set the current default string encoding used by the Unicode implementation.\n\
|
|
+Defaults to utf-8."
|
|
+);
|
|
+
|
|
+static PyObject *
|
|
+setdefaultencoding(PyObject *self, PyObject *args, PyObject *kwds)
|
|
+{
|
|
+ static char *kwlist[] = {"utf-8", NULL};
|
|
+ char *encoding;
|
|
+
|
|
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s:setdefaultencoding", kwlist, &encoding))
|
|
+ return NULL;
|
|
+
|
|
+ if (PyUnicode_SetDefaultEncoding(encoding))
|
|
+ return NULL;
|
|
+
|
|
+ Py_RETURN_NONE;
|
|
+}
|
|
+
|
|
+static PyMethodDef methods[] = {
|
|
+ {"setdefaultencoding", (PyCFunction)setdefaultencoding, METH_VARARGS|METH_KEYWORDS, setdefaultencoding_doc},
|
|
+ {NULL, NULL} /* sentinel */
|
|
+};
|
|
+
|
|
+
|
|
+PyMODINIT_FUNC
|
|
+initdefault_encoding_utf8(void)
|
|
+{
|
|
+ PyUnicode_SetDefaultEncoding("utf-8");
|
|
+ Py_InitModule3("default_encoding_utf8", methods, "Forces the default encoding to utf-8");
|
|
+}
|
|
diff --git a/policycoreutils/semanage/default_encoding/policycoreutils/__init__.py b/policycoreutils/semanage/default_encoding/policycoreutils/__init__.py
|
|
new file mode 100644
|
|
index 0000000..ccb6b8b
|
|
--- /dev/null
|
|
+++ b/policycoreutils/semanage/default_encoding/policycoreutils/__init__.py
|
|
@@ -0,0 +1,17 @@
|
|
+#
|
|
+# Copyright (C) 2006,2007,2008, 2009 Red Hat, Inc.
|
|
+#
|
|
+# This program is free software; you can redistribute it and/or modify
|
|
+# it under the terms of the GNU General Public License as published by
|
|
+# the Free Software Foundation; either version 2 of the License, or
|
|
+# (at your option) any later version.
|
|
+#
|
|
+# This program is distributed in the hope that it will be useful,
|
|
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+# GNU General Public License for more details.
|
|
+#
|
|
+# You should have received a copy of the GNU General Public License
|
|
+# along with this program; if not, write to the Free Software
|
|
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
+#
|
|
diff --git a/policycoreutils/semanage/default_encoding/setup.py b/policycoreutils/semanage/default_encoding/setup.py
|
|
new file mode 100644
|
|
index 0000000..e2befdb
|
|
--- /dev/null
|
|
+++ b/policycoreutils/semanage/default_encoding/setup.py
|
|
@@ -0,0 +1,38 @@
|
|
+# Authors:
|
|
+# John Dennis <jdennis@redhat.com>
|
|
+#
|
|
+# Copyright (C) 2009 Red Hat
|
|
+# see file 'COPYING' for use and warranty information
|
|
+#
|
|
+# This program is free software; you can redistribute it and/or
|
|
+# modify it under the terms of the GNU General Public License as
|
|
+# published by the Free Software Foundation.
|
|
+#
|
|
+# This program is distributed in the hope that it will be useful,
|
|
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+# GNU General Public License for more details.
|
|
+#
|
|
+# You should have received a copy of the GNU General Public License
|
|
+# along with this program; if not, write to the Free Software
|
|
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
+
|
|
+from distutils.core import setup, Extension
|
|
+
|
|
+default_encoding_utf8 = Extension('policycoreutils.default_encoding_utf8', ['default_encoding.c'])
|
|
+
|
|
+setup(name = 'policycoreutils-default-encoding',
|
|
+ version = '0.1',
|
|
+ description = 'Forces the default encoding in Python to be utf-8',
|
|
+ long_description = 'Forces the default encoding in Python to be utf-8',
|
|
+ author = 'John Dennis',
|
|
+ author_email = 'jdennis@redhat.com',
|
|
+ maintainer = 'John Dennis',
|
|
+ maintainer_email = 'jdennis@redhat.com',
|
|
+ license = 'GPLv3+',
|
|
+ platforms = 'posix',
|
|
+ url = '',
|
|
+ download_url = '',
|
|
+ ext_modules = [default_encoding_utf8],
|
|
+ packages=["policycoreutils"],
|
|
+)
|
|
diff --git a/policycoreutils/semanage/semanage b/policycoreutils/semanage/semanage
|
|
index 0c7c186..aaba8b1 100644
|
|
--- a/policycoreutils/semanage/semanage
|
|
+++ b/policycoreutils/semanage/semanage
|
|
@@ -20,6 +20,7 @@
|
|
# 02111-1307 USA
|
|
#
|
|
#
|
|
+import policycoreutils.default_encoding_utf8
|
|
import sys, getopt, re
|
|
import seobject
|
|
import selinux
|
|
@@ -32,7 +33,7 @@ gettext.textdomain(PROGNAME)
|
|
try:
|
|
gettext.install(PROGNAME,
|
|
localedir="/usr/share/locale",
|
|
- unicode=False,
|
|
+ unicode=True,
|
|
codeset = 'utf-8')
|
|
except IOError:
|
|
import __builtin__
|
|
diff --git a/policycoreutils/semanage/seobject.py b/policycoreutils/semanage/seobject.py
|
|
index 17afe23..12cd0fe 100644
|
|
--- a/policycoreutils/semanage/seobject.py
|
|
+++ b/policycoreutils/semanage/seobject.py
|
|
@@ -1,4 +1,4 @@
|
|
-#! /usr/bin/python -E
|
|
+#! /usr/bin/python -Es
|
|
# Copyright (C) 2005-2011 Red Hat
|
|
# see file 'COPYING' for use and warranty information
|
|
#
|
|
@@ -30,11 +30,10 @@ from IPy import IP
|
|
import gettext
|
|
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
|
|
gettext.textdomain(PROGNAME)
|
|
-try:
|
|
- gettext.install(PROGNAME, localedir = "/usr/share/locale", unicode = 1)
|
|
-except IOError:
|
|
- import __builtin__
|
|
- __builtin__.__dict__['_'] = unicode
|
|
+
|
|
+import gettext
|
|
+translation=gettext.translation(PROGNAME, localedir = "/usr/share/locale", fallback=True)
|
|
+_=translation.ugettext
|
|
|
|
import syslog
|
|
|
|
@@ -61,32 +60,67 @@ try:
|
|
class logger:
|
|
def __init__(self):
|
|
self.audit_fd = audit.audit_open()
|
|
-
|
|
- def log(self, success, msg, name = "", sename = "", serole = "", serange = "", old_sename = "", old_serole = "", old_serange = ""):
|
|
- audit.audit_log_semanage_message(self.audit_fd, audit.AUDIT_USER_ROLE_CHANGE, sys.argv[0], str(msg), name, 0, sename, serole, serange, old_sename, old_serole, old_serange, "", "", "", success);
|
|
+ self.log_list = []
|
|
+ def log(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
|
|
+
|
|
+ sep = "-"
|
|
+ if sename != oldsename:
|
|
+ msg += sep + "sename"; sep = ","
|
|
+ if serole != oldserole:
|
|
+ msg += sep + "role"; sep = ","
|
|
+ if serange != oldserange:
|
|
+ msg += sep + "range"; sep = ","
|
|
+
|
|
+ self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_ASSIGN, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
|
|
+
|
|
+ def log_remove(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
|
|
+ self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_REMOVE, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
|
|
+
|
|
+ def commit(self,success):
|
|
+ for l in self.log_list:
|
|
+ audit.audit_log_semanage_message(*(l + [success]))
|
|
+ self.log_list = []
|
|
except:
|
|
class logger:
|
|
- def log(self, success, msg, name = "", sename = "", serole = "", serange = "", old_sename = "", old_serole = "", old_serange = ""):
|
|
- if success == 1:
|
|
- message = "Successful: "
|
|
- else:
|
|
- message = "Failed: "
|
|
+ def __init__(self):
|
|
+ self.log_list=[]
|
|
+
|
|
+ def log(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
|
|
message += " %s name=%s" % (msg, name)
|
|
if sename != "":
|
|
message += " sename=" + sename
|
|
- if old_sename != "":
|
|
- message += " old_sename=" + old_sename
|
|
+ if oldsename != "":
|
|
+ message += " oldsename=" + oldsename
|
|
if serole != "":
|
|
message += " role=" + serole
|
|
- if old_serole != "":
|
|
- message += " old_role=" + old_serole
|
|
+ if oldserole != "":
|
|
+ message += " old_role=" + oldserole
|
|
if serange != "" and serange != None:
|
|
message += " MLSRange=" + serange
|
|
- if old_serange != "" and old_serange != None:
|
|
- message += " old_MLSRange=" + old_serange
|
|
- syslog.syslog(message);
|
|
-
|
|
-mylog = logger()
|
|
+ if oldserange != "" and oldserange != None:
|
|
+ message += " old_MLSRange=" + oldserange
|
|
+ self.log_list.append(message)
|
|
+
|
|
+ def log_remove(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
|
|
+ self.log(msg, name, sename, serole, serange, oldsename, oldserole, oldserange)
|
|
+
|
|
+ def commit(self,success):
|
|
+ if success == 1:
|
|
+ message = "Successful: "
|
|
+ else:
|
|
+ message = "Failed: "
|
|
+ for l in self.log_list:
|
|
+ syslog.syslog(syslog.LOG_INFO, message + l)
|
|
+
|
|
+class nulllogger:
|
|
+ def log(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
|
|
+ pass
|
|
+
|
|
+ def log_remove(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
|
|
+ pass
|
|
+
|
|
+ def commit(self,success):
|
|
+ pass
|
|
|
|
import xml.etree.ElementTree
|
|
|
|
@@ -168,44 +202,50 @@ class semanageRecords:
|
|
store = None
|
|
def __init__(self, store):
|
|
global handle
|
|
-
|
|
+
|
|
self.sh = self.get_handle(store)
|
|
|
|
+ rc, localstore = selinux.selinux_getpolicytype()
|
|
+ if store == "" or store == localstore:
|
|
+ self.mylog = logger()
|
|
+ else:
|
|
+ self.mylog = nulllogger()
|
|
+
|
|
def get_handle(self, store):
|
|
- global is_mls_enabled
|
|
+ global is_mls_enabled
|
|
|
|
- if semanageRecords.handle:
|
|
- return semanageRecords.handle
|
|
+ if semanageRecords.handle:
|
|
+ return semanageRecords.handle
|
|
|
|
- handle = semanage_handle_create()
|
|
- if not handle:
|
|
- raise ValueError(_("Could not create semanage handle"))
|
|
+ handle = semanage_handle_create()
|
|
+ if not handle:
|
|
+ raise ValueError(_("Could not create semanage handle"))
|
|
|
|
- if not semanageRecords.transaction and store != "":
|
|
- semanage_select_store(handle, store, SEMANAGE_CON_DIRECT);
|
|
- semanageRecords.store = store
|
|
+ if not semanageRecords.transaction and store != "":
|
|
+ semanage_select_store(handle, store, SEMANAGE_CON_DIRECT);
|
|
+ semanageRecords.store = store
|
|
|
|
- if not semanage_is_managed(handle):
|
|
- semanage_handle_destroy(handle)
|
|
- raise ValueError(_("SELinux policy is not managed or store cannot be accessed."))
|
|
+ if not semanage_is_managed(handle):
|
|
+ semanage_handle_destroy(handle)
|
|
+ raise ValueError(_("SELinux policy is not managed or store cannot be accessed."))
|
|
|
|
- rc = semanage_access_check(handle)
|
|
- if rc < SEMANAGE_CAN_READ:
|
|
- semanage_handle_destroy(handle)
|
|
- raise ValueError(_("Cannot read policy store."))
|
|
+ rc = semanage_access_check(handle)
|
|
+ if rc < SEMANAGE_CAN_READ:
|
|
+ semanage_handle_destroy(handle)
|
|
+ raise ValueError(_("Cannot read policy store."))
|
|
|
|
- rc = semanage_connect(handle)
|
|
- if rc < 0:
|
|
- semanage_handle_destroy(handle)
|
|
- raise ValueError(_("Could not establish semanage connection"))
|
|
+ rc = semanage_connect(handle)
|
|
+ if rc < 0:
|
|
+ semanage_handle_destroy(handle)
|
|
+ raise ValueError(_("Could not establish semanage connection"))
|
|
|
|
- is_mls_enabled = semanage_mls_enabled(handle)
|
|
- if is_mls_enabled < 0:
|
|
- semanage_handle_destroy(handle)
|
|
- raise ValueError(_("Could not test MLS enabled status"))
|
|
+ is_mls_enabled = semanage_mls_enabled(handle)
|
|
+ if is_mls_enabled < 0:
|
|
+ semanage_handle_destroy(handle)
|
|
+ raise ValueError(_("Could not test MLS enabled status"))
|
|
|
|
- semanageRecords.handle = handle
|
|
- return semanageRecords.handle
|
|
+ semanageRecords.handle = handle
|
|
+ return semanageRecords.handle
|
|
|
|
def deleteall(self):
|
|
raise ValueError(_("Not yet implemented"))
|
|
@@ -226,11 +266,13 @@ class semanageRecords:
|
|
raise ValueError(_("Not yet implemented"))
|
|
|
|
def commit(self):
|
|
- if semanageRecords.transaction:
|
|
- return
|
|
- rc = semanage_commit(self.sh)
|
|
- if rc < 0:
|
|
- raise ValueError(_("Could not commit semanage transaction"))
|
|
+ if semanageRecords.transaction:
|
|
+ return
|
|
+ rc = semanage_commit(self.sh)
|
|
+ if rc < 0:
|
|
+ self.mylog.commit(0)
|
|
+ raise ValueError(_("Could not commit semanage transaction"))
|
|
+ self.mylog.commit(1)
|
|
|
|
def finish(self):
|
|
if not semanageRecords.transaction:
|
|
@@ -412,17 +454,26 @@ permissive %s;
|
|
class loginRecords(semanageRecords):
|
|
def __init__(self, store = ""):
|
|
semanageRecords.__init__(self, store)
|
|
+ self.oldsename = None
|
|
+ self.oldserange = None
|
|
+ self.sename = None
|
|
+ self.serange = None
|
|
|
|
def __add(self, name, sename, serange):
|
|
- if is_mls_enabled == 1:
|
|
- if serange == "":
|
|
- serange = "s0"
|
|
- else:
|
|
- serange = untranslate(serange)
|
|
-
|
|
+ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
|
|
if sename == "":
|
|
sename = "user_u"
|
|
|
|
+ userrec = seluserRecords()
|
|
+ range, (rc, oldserole) = userrec.get(self.oldsename)
|
|
+ range, (rc, serole) = userrec.get(sename)
|
|
+
|
|
+ if is_mls_enabled == 1:
|
|
+ if serange != "":
|
|
+ serange = untranslate(serange)
|
|
+ else:
|
|
+ serange = range
|
|
+
|
|
(rc, k) = semanage_seuser_key_create(self.sh, name)
|
|
if rc < 0:
|
|
raise ValueError(_("Could not create a key for %s") % name)
|
|
@@ -431,7 +482,9 @@ class loginRecords(semanageRecords):
|
|
if rc < 0:
|
|
raise ValueError(_("Could not check if login mapping for %s is defined") % name)
|
|
if exists:
|
|
- raise ValueError(_("Login mapping for %s is already defined") % name)
|
|
+ semanage_seuser_key_free(k)
|
|
+ return self.__modify(name, sename, serange)
|
|
+
|
|
if name[0] == '%':
|
|
try:
|
|
grp.getgrnam(name[1:])
|
|
@@ -466,113 +519,132 @@ class loginRecords(semanageRecords):
|
|
|
|
semanage_seuser_key_free(k)
|
|
semanage_seuser_free(u)
|
|
+ self.mylog.log("login", name, sename=sename, serange=serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange);
|
|
|
|
def add(self, name, sename, serange):
|
|
try:
|
|
- self.begin()
|
|
- self.__add(name, sename, serange)
|
|
- self.commit()
|
|
-
|
|
+ self.begin()
|
|
+ self.__add(name, sename, serange)
|
|
+ self.commit()
|
|
except ValueError, error:
|
|
- mylog.log(0, _("add SELinux user mapping"), name, sename, "", serange);
|
|
+ self.mylog.commit(0)
|
|
raise error
|
|
-
|
|
- mylog.log(1, _("add SELinux user mapping"), name, sename, "", serange);
|
|
|
|
def __modify(self, name, sename = "", serange = ""):
|
|
- if sename == "" and serange == "":
|
|
+ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
|
|
+ if sename == "" and serange == "":
|
|
raise ValueError(_("Requires seuser or serange"))
|
|
|
|
- (rc, k) = semanage_seuser_key_create(self.sh, name)
|
|
- if rc < 0:
|
|
- raise ValueError(_("Could not create a key for %s") % name)
|
|
-
|
|
- (rc, exists) = semanage_seuser_exists(self.sh, k)
|
|
- if rc < 0:
|
|
- raise ValueError(_("Could not check if login mapping for %s is defined") % name)
|
|
- if not exists:
|
|
- raise ValueError(_("Login mapping for %s is not defined") % name)
|
|
+ userrec = seluserRecords()
|
|
+ range, (rc, oldserole) = userrec.get(self.oldsename)
|
|
|
|
- (rc, u) = semanage_seuser_query(self.sh, k)
|
|
- if rc < 0:
|
|
- raise ValueError(_("Could not query seuser for %s") % name)
|
|
+ if sename != "":
|
|
+ range, (rc, serole) = userrec.get(sename)
|
|
+ else:
|
|
+ serole=oldserole
|
|
|
|
- oldserange = semanage_seuser_get_mlsrange(u)
|
|
- oldsename = semanage_seuser_get_sename(u)
|
|
- if serange != "":
|
|
- semanage_seuser_set_mlsrange(self.sh, u, untranslate(serange))
|
|
- else:
|
|
- serange = oldserange
|
|
+ if serange != "":
|
|
+ self.serange=serange
|
|
+ else:
|
|
+ self.serange=range
|
|
|
|
- if sename != "":
|
|
- semanage_seuser_set_sename(self.sh, u, sename)
|
|
- else:
|
|
- sename = oldsename
|
|
+ (rc, k) = semanage_seuser_key_create(self.sh, name)
|
|
+ if rc < 0:
|
|
+ raise ValueError(_("Could not create a key for %s") % name)
|
|
|
|
- rc = semanage_seuser_modify_local(self.sh, k, u)
|
|
- if rc < 0:
|
|
- raise ValueError(_("Could not modify login mapping for %s") % name)
|
|
+ (rc, exists) = semanage_seuser_exists(self.sh, k)
|
|
+ if rc < 0:
|
|
+ raise ValueError(_("Could not check if login mapping for %s is defined") % name)
|
|
+ if not exists:
|
|
+ raise ValueError(_("Login mapping for %s is not defined") % name)
|
|
+
|
|
+ (rc, u) = semanage_seuser_query(self.sh, k)
|
|
+ if rc < 0:
|
|
+ raise ValueError(_("Could not query seuser for %s") % name)
|
|
+
|
|
+ self.oldserange = semanage_seuser_get_mlsrange(u)
|
|
+ self.oldsename = semanage_seuser_get_sename(u)
|
|
+ if serange != "":
|
|
+ semanage_seuser_set_mlsrange(self.sh, u, untranslate(serange))
|
|
|
|
- semanage_seuser_key_free(k)
|
|
- semanage_seuser_free(u)
|
|
+ if sename != "":
|
|
+ semanage_seuser_set_sename(self.sh, u, sename)
|
|
+ else:
|
|
+ self.sename = self.oldsename
|
|
+
|
|
+ rc = semanage_seuser_modify_local(self.sh, k, u)
|
|
+ if rc < 0:
|
|
+ raise ValueError(_("Could not modify login mapping for %s") % name)
|
|
|
|
- mylog.log(1, "modify selinux user mapping", name, sename, "", serange, oldsename, "", oldserange);
|
|
+ semanage_seuser_key_free(k)
|
|
+ semanage_seuser_free(u)
|
|
+ self.mylog.log("login", name,sename=self.sename,serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange);
|
|
|
|
def modify(self, name, sename = "", serange = ""):
|
|
try:
|
|
self.begin()
|
|
self.__modify(name, sename, serange)
|
|
self.commit()
|
|
-
|
|
except ValueError, error:
|
|
- mylog.log(0, "modify selinux user mapping", name, sename, "", serange, "", "", "");
|
|
+ self.mylog.commit(0)
|
|
raise error
|
|
-
|
|
+
|
|
def __delete(self, name):
|
|
- (rc, k) = semanage_seuser_key_create(self.sh, name)
|
|
- if rc < 0:
|
|
- raise ValueError(_("Could not create a key for %s") % name)
|
|
+ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
|
|
+ userrec = seluserRecords()
|
|
+ range, (rc, oldserole) = userrec.get(self.oldsename)
|
|
|
|
- (rc, exists) = semanage_seuser_exists(self.sh, k)
|
|
- if rc < 0:
|
|
- raise ValueError(_("Could not check if login mapping for %s is defined") % name)
|
|
- if not exists:
|
|
- raise ValueError(_("Login mapping for %s is not defined") % name)
|
|
+ (rc, k) = semanage_seuser_key_create(self.sh, name)
|
|
+ if rc < 0:
|
|
+ raise ValueError(_("Could not create a key for %s") % name)
|
|
|
|
- (rc, exists) = semanage_seuser_exists_local(self.sh, k)
|
|
- if rc < 0:
|
|
- raise ValueError(_("Could not check if login mapping for %s is defined") % name)
|
|
- if not exists:
|
|
- raise ValueError(_("Login mapping for %s is defined in policy, cannot be deleted") % name)
|
|
+ (rc, exists) = semanage_seuser_exists(self.sh, k)
|
|
+ if rc < 0:
|
|
+ raise ValueError(_("Could not check if login mapping for %s is defined") % name)
|
|
+ if not exists:
|
|
+ raise ValueError(_("Login mapping for %s is not defined") % name)
|
|
+
|
|
+ (rc, exists) = semanage_seuser_exists_local(self.sh, k)
|
|
+ if rc < 0:
|
|
+ raise ValueError(_("Could not check if login mapping for %s is defined") % name)
|
|
+ if not exists:
|
|
+ raise ValueError(_("Login mapping for %s is defined in policy, cannot be deleted") % name)
|
|
+
|
|
+ rc = semanage_seuser_del_local(self.sh, k)
|
|
+ if rc < 0:
|
|
+ raise ValueError(_("Could not delete login mapping for %s") % name)
|
|
+
|
|
+ semanage_seuser_key_free(k)
|
|
|
|
- rc = semanage_seuser_del_local(self.sh, k)
|
|
- if rc < 0:
|
|
- raise ValueError(_("Could not delete login mapping for %s") % name)
|
|
+ rec, self.sename, self.serange = selinux.getseuserbyname("__default__")
|
|
+ range, (rc, serole) = userrec.get(self.sename)
|
|
|
|
- semanage_seuser_key_free(k)
|
|
+ self.mylog.log_remove("login", name, sename=self.sename, serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange);
|
|
|
|
def delete(self, name):
|
|
try:
|
|
- self.begin()
|
|
- self.__delete(name)
|
|
- self.commit()
|
|
+ self.begin()
|
|
+ self.__delete(name)
|
|
+ self.commit()
|
|
|
|
except ValueError, error:
|
|
- mylog.log(0, "delete SELinux user mapping", name);
|
|
+ self.mylog.commit(0)
|
|
raise error
|
|
|
|
- mylog.log(1, "delete SELinux user mapping", name);
|
|
-
|
|
def deleteall(self):
|
|
(rc, ulist) = semanage_seuser_list_local(self.sh)
|
|
if rc < 0:
|
|
raise ValueError(_("Could not list login mappings"))
|
|
|
|
- self.begin()
|
|
- for u in ulist:
|
|
- self.__delete(semanage_seuser_get_name(u))
|
|
- self.commit()
|
|
-
|
|
+ try:
|
|
+ self.begin()
|
|
+ for u in ulist:
|
|
+ self.__delete(semanage_seuser_get_name(u))
|
|
+ self.commit()
|
|
+ except ValueError, error:
|
|
+ self.mylog.commit(0)
|
|
+ raise error
|
|
+
|
|
def get_all(self, locallist = 0):
|
|
ddict = {}
|
|
if locallist:
|
|
@@ -618,6 +690,22 @@ class seluserRecords(semanageRecords):
|
|
def __init__(self, store = ""):
|
|
semanageRecords.__init__(self, store)
|
|
|
|
+ def get(self, name):
|
|
+ (rc, k) = semanage_user_key_create(self.sh, name)
|
|
+ if rc < 0:
|
|
+ raise ValueError(_("Could not create a key for %s") % name)
|
|
+ (rc, exists) = semanage_user_exists(self.sh, k)
|
|
+ if rc < 0:
|
|
+ raise ValueError(_("Could not check if SELinux user %s is defined") % name)
|
|
+ (rc, u) = semanage_user_query(self.sh, k)
|
|
+ if rc < 0:
|
|
+ raise ValueError(_("Could not query user for %s") % name)
|
|
+ serange = semanage_user_get_mlsrange(u)
|
|
+ serole = semanage_user_get_roles(self.sh,u)
|
|
+ semanage_user_key_free(k)
|
|
+ semanage_user_free(u)
|
|
+ return serange, serole
|
|
+
|
|
def __add(self, name, roles, selevel, serange, prefix):
|
|
if is_mls_enabled == 1:
|
|
if serange == "":
|
|
@@ -641,7 +729,8 @@ class seluserRecords(semanageRecords):
|
|
if rc < 0:
|
|
raise ValueError(_("Could not check if SELinux user %s is defined") % name)
|
|
if exists:
|
|
- raise ValueError(_("SELinux user %s is already defined") % name)
|
|
+ semanage_user_key_free(k)
|
|
+ return self.__modify(name, roles, selevel, serange, prefix)
|
|
|
|
(rc, u) = semanage_user_create(self.sh)
|
|
if rc < 0:
|
|
@@ -677,21 +766,20 @@ class seluserRecords(semanageRecords):
|
|
|
|
semanage_user_key_free(k)
|
|
semanage_user_free(u)
|
|
+ self.mylog.log("seuser", sename=name, serole=",".join(roles), serange=serange)
|
|
|
|
def add(self, name, roles, selevel, serange, prefix):
|
|
- seroles = " ".join(roles)
|
|
- try:
|
|
- self.begin()
|
|
- self.__add( name, roles, selevel, serange, prefix)
|
|
- self.commit()
|
|
+ serole = " ".join(roles)
|
|
+ try:
|
|
+ self.begin()
|
|
+ self.__add( name, roles, selevel, serange, prefix)
|
|
+ self.commit()
|
|
except ValueError, error:
|
|
- mylog.log(0,"add SELinux user record", name, name, seroles, serange)
|
|
+ self.mylog.commit(0)
|
|
raise error
|
|
-
|
|
- mylog.log(1,"add SELinux user record", name, name, seroles, serange)
|
|
|
|
def __modify(self, name, roles = [], selevel = "", serange = "", prefix = ""):
|
|
- oldroles = ""
|
|
+ oldserole = ""
|
|
oldserange = ""
|
|
newroles = string.join(roles, ' ');
|
|
if prefix == "" and len(roles) == 0 and serange == "" and selevel == "":
|
|
@@ -717,9 +805,7 @@ class seluserRecords(semanageRecords):
|
|
oldserange = semanage_user_get_mlsrange(u)
|
|
(rc, rlist) = semanage_user_get_roles(self.sh, u)
|
|
if rc >= 0:
|
|
- oldroles = string.join(rlist, ' ');
|
|
- newroles = newroles + ' ' + oldroles;
|
|
-
|
|
+ oldserole = string.join(rlist, ' ');
|
|
|
|
if serange != "":
|
|
semanage_user_set_mlsrange(self.sh, u, untranslate(serange))
|
|
@@ -743,8 +829,10 @@ class seluserRecords(semanageRecords):
|
|
|
|
semanage_user_key_free(k)
|
|
semanage_user_free(u)
|
|
-
|
|
- mylog.log(1,"modify SELinux user record", name, "", newroles, serange, "", oldroles, oldserange)
|
|
+
|
|
+ role=",".join(newroles.split())
|
|
+ oldserole=",".join(oldserole.split())
|
|
+ self.mylog.log("seuser", sename=name, oldsename=name, serole=role, serange=serange, oldserole=oldserole, oldserange=oldserange)
|
|
|
|
|
|
def modify(self, name, roles = [], selevel = "", serange = "", prefix = ""):
|
|
@@ -752,9 +840,8 @@ class seluserRecords(semanageRecords):
|
|
self.begin()
|
|
self.__modify(name, roles, selevel, serange, prefix)
|
|
self.commit()
|
|
-
|
|
except ValueError, error:
|
|
- mylog.log(0,"modify SELinux user record", name, "", " ".join(roles), serange, "", "", "")
|
|
+ self.mylog.commit(0)
|
|
raise error
|
|
|
|
def __delete(self, name):
|
|
@@ -774,11 +861,21 @@ class seluserRecords(semanageRecords):
|
|
if not exists:
|
|
raise ValueError(_("SELinux user %s is defined in policy, cannot be deleted") % name)
|
|
|
|
+ (rc, u) = semanage_user_query(self.sh, k)
|
|
+ if rc < 0:
|
|
+ raise ValueError(_("Could not query user for %s") % name)
|
|
+ oldserange = semanage_user_get_mlsrange(u)
|
|
+ (rc, rlist) = semanage_user_get_roles(self.sh, u)
|
|
+ oldserole = ",".join(rlist)
|
|
+
|
|
rc = semanage_user_del_local(self.sh, k)
|
|
if rc < 0:
|
|
raise ValueError(_("Could not delete SELinux user %s") % name)
|
|
|
|
semanage_user_key_free(k)
|
|
+ semanage_user_free(u)
|
|
+
|
|
+ self.mylog.log_remove("seuser", oldsename=name, oldserange=oldserange, oldserole=oldserole)
|
|
|
|
def delete(self, name):
|
|
try:
|
|
@@ -787,20 +884,22 @@ class seluserRecords(semanageRecords):
|
|
self.commit()
|
|
|
|
except ValueError, error:
|
|
- mylog.log(0,"delete SELinux user record", name)
|
|
+ self.mylog.commit(0)
|
|
raise error
|
|
|
|
- mylog.log(1,"delete SELinux user record", name)
|
|
-
|
|
def deleteall(self):
|
|
(rc, ulist) = semanage_user_list_local(self.sh)
|
|
if rc < 0:
|
|
raise ValueError(_("Could not list login mappings"))
|
|
|
|
- self.begin()
|
|
- for u in ulist:
|
|
- self.__delete(semanage_user_get_name(u))
|
|
- self.commit()
|
|
+ try:
|
|
+ self.begin()
|
|
+ for u in ulist:
|
|
+ self.__delete(semanage_user_get_name(u))
|
|
+ self.commit()
|
|
+ except ValueError, error:
|
|
+ self.mylog.commit(0)
|
|
+ raise error
|
|
|
|
def get_all(self, locallist = 0):
|
|
ddict = {}
|
|
@@ -1155,7 +1254,8 @@ class nodeRecords(semanageRecords):
|
|
|
|
(rc, exists) = semanage_node_exists(self.sh, k)
|
|
if exists:
|
|
- raise ValueError(_("Addr %s already defined") % addr)
|
|
+ semanage_node_key_free(k)
|
|
+ return self.__modify(addr, mask, self.protocol[proto], serange, ctype)
|
|
|
|
(rc, node) = semanage_node_create(self.sh)
|
|
if rc < 0:
|
|
@@ -1353,7 +1453,8 @@ class interfaceRecords(semanageRecords):
|
|
if rc < 0:
|
|
raise ValueError(_("Could not check if interface %s is defined") % interface)
|
|
if exists:
|
|
- raise ValueError(_("Interface %s already defined") % interface)
|
|
+ semanage_iface_key_free(k)
|
|
+ return self.__modify(interface, serange, ctype)
|
|
|
|
(rc, iface) = semanage_iface_create(self.sh)
|
|
if rc < 0:
|
|
@@ -1636,7 +1737,8 @@ class fcontextRecords(semanageRecords):
|
|
raise ValueError(_("Could not check if file context for %s is defined") % target)
|
|
|
|
if exists:
|
|
- raise ValueError(_("File context for %s already defined") % target)
|
|
+ semanage_fcontext_key_free(k)
|
|
+ return self.__modify(target, type, ftype, serange, seuser)
|
|
|
|
(rc, fcontext) = semanage_fcontext_create(self.sh)
|
|
if rc < 0:
|
|
diff --git a/policycoreutils/setfiles/restore.c b/policycoreutils/setfiles/restore.c
|
|
index 9a7d315..5ade9f1 100644
|
|
--- a/policycoreutils/setfiles/restore.c
|
|
+++ b/policycoreutils/setfiles/restore.c
|
|
@@ -1,5 +1,6 @@
|
|
#include "restore.h"
|
|
#include <glob.h>
|
|
+#include <selinux/context.h>
|
|
|
|
#define SKIP -2
|
|
#define ERR -1
|
|
@@ -33,7 +34,6 @@ struct edir {
|
|
|
|
static file_spec_t *fl_head;
|
|
static int filespec_add(ino_t ino, const security_context_t con, const char *file);
|
|
-static int only_changed_user(const char *a, const char *b);
|
|
struct restore_opts *r_opts = NULL;
|
|
static void filespec_destroy(void);
|
|
static void filespec_eval(void);
|
|
@@ -58,11 +58,16 @@ void remove_exclude(const char *directory)
|
|
void restore_init(struct restore_opts *opts)
|
|
{
|
|
r_opts = opts;
|
|
- struct selinux_opt selinux_opts[] = {
|
|
- { SELABEL_OPT_VALIDATE, r_opts->selabel_opt_validate },
|
|
- { SELABEL_OPT_PATH, r_opts->selabel_opt_path }
|
|
- };
|
|
- r_opts->hnd = selabel_open(SELABEL_CTX_FILE, selinux_opts, 2);
|
|
+ struct selinux_opt selinux_opts[3];
|
|
+
|
|
+ selinux_opts[0].type = SELABEL_OPT_VALIDATE;
|
|
+ selinux_opts[0].value = r_opts->selabel_opt_validate;
|
|
+ selinux_opts[1].type = SELABEL_OPT_PATH;
|
|
+ selinux_opts[1].value = r_opts->selabel_opt_path;
|
|
+ selinux_opts[2].type = SELABEL_OPT_PREFIXES;
|
|
+ selinux_opts[2].values = r_opts->selabel_opt_prefixes;
|
|
+
|
|
+ r_opts->hnd = selabel_open(SELABEL_CTX_FILE, selinux_opts, 3);
|
|
if (!r_opts->hnd) {
|
|
perror(r_opts->selabel_opt_path);
|
|
exit(1);
|
|
@@ -104,8 +109,7 @@ static int restore(FTSENT *ftsent)
|
|
{
|
|
char *my_file = strdupa(ftsent->fts_path);
|
|
int ret = -1;
|
|
- char *context, *newcon;
|
|
- int user_only_changed = 0;
|
|
+ security_context_t curcon = NULL, newcon = NULL;
|
|
|
|
if (match(my_file, ftsent->fts_statp, &newcon) < 0)
|
|
/* Check for no matching specification. */
|
|
@@ -139,74 +143,105 @@ static int restore(FTSENT *ftsent)
|
|
printf("%s: %s matched by %s\n", r_opts->progname, my_file, newcon);
|
|
}
|
|
|
|
+ /*
|
|
+ * Do not relabel if their is no default specification for this file
|
|
+ */
|
|
+
|
|
+ if (strcmp(newcon, "<<none>>") == 0) {
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
/* Get the current context of the file. */
|
|
- ret = lgetfilecon_raw(ftsent->fts_accpath, &context);
|
|
+ ret = lgetfilecon_raw(ftsent->fts_accpath, &curcon);
|
|
if (ret < 0) {
|
|
if (errno == ENODATA) {
|
|
- context = NULL;
|
|
+ curcon = NULL;
|
|
} else {
|
|
fprintf(stderr, "%s get context on %s failed: '%s'\n",
|
|
r_opts->progname, my_file, strerror(errno));
|
|
goto err;
|
|
}
|
|
- user_only_changed = 0;
|
|
- } else
|
|
- user_only_changed = only_changed_user(context, newcon);
|
|
+ }
|
|
+
|
|
/* lgetfilecon returns number of characters and ret needs to be reset
|
|
* to 0.
|
|
*/
|
|
ret = 0;
|
|
|
|
/*
|
|
- * Do not relabel the file if the matching specification is
|
|
- * <<none>> or the file is already labeled according to the
|
|
- * specification.
|
|
+ * Do not relabel the file if the file is already labeled according to
|
|
+ * the specification.
|
|
*/
|
|
- if ((strcmp(newcon, "<<none>>") == 0) ||
|
|
- (context && (strcmp(context, newcon) == 0))) {
|
|
- freecon(context);
|
|
+ if (curcon && (strcmp(curcon, newcon) == 0)) {
|
|
goto out;
|
|
}
|
|
|
|
- if (!r_opts->force && context && (is_context_customizable(context) > 0)) {
|
|
+ if (!r_opts->force && curcon && (is_context_customizable(curcon) > 0)) {
|
|
if (r_opts->verbose > 1) {
|
|
fprintf(stderr,
|
|
"%s: %s not reset customized by admin to %s\n",
|
|
- r_opts->progname, my_file, context);
|
|
+ r_opts->progname, my_file, curcon);
|
|
}
|
|
- freecon(context);
|
|
goto out;
|
|
}
|
|
|
|
- if (r_opts->verbose) {
|
|
- /* If we're just doing "-v", trim out any relabels where
|
|
- * the user has r_opts->changed but the role and type are the
|
|
- * same. For "-vv", emit everything. */
|
|
- if (r_opts->verbose > 1 || !user_only_changed) {
|
|
- printf("%s reset %s context %s->%s\n",
|
|
- r_opts->progname, my_file, context ?: "", newcon);
|
|
+ /*
|
|
+ * Do not change label unless this is a force or the type is different
|
|
+ */
|
|
+ if (!r_opts->force && curcon) {
|
|
+ int types_differ = 0;
|
|
+ context_t cona;
|
|
+ context_t conb;
|
|
+ int err = 0;
|
|
+ cona = context_new(curcon);
|
|
+ if (! cona) {
|
|
+ goto out;
|
|
+ }
|
|
+ conb = context_new(newcon);
|
|
+ if (! conb) {
|
|
+ context_free(cona);
|
|
+ goto out;
|
|
}
|
|
+
|
|
+ types_differ = strcmp(context_type_get(cona), context_type_get(conb));
|
|
+ if (types_differ) {
|
|
+ err |= context_user_set(conb, context_user_get(cona));
|
|
+ err |= context_role_set(conb, context_role_get(cona));
|
|
+ err |= context_range_set(conb, context_range_get(cona));
|
|
+ if (!err) {
|
|
+ freecon(newcon);
|
|
+ newcon = strdup(context_str(conb));
|
|
+ }
|
|
+ }
|
|
+ context_free(cona);
|
|
+ context_free(conb);
|
|
+
|
|
+ if (!types_differ || err) {
|
|
+ goto out;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (r_opts->verbose) {
|
|
+ printf("%s reset %s context %s->%s\n",
|
|
+ r_opts->progname, my_file, curcon ?: "", newcon);
|
|
}
|
|
|
|
- if (r_opts->logging && !user_only_changed) {
|
|
- if (context)
|
|
+ if (r_opts->logging && r_opts->change) {
|
|
+ if (curcon)
|
|
syslog(LOG_INFO, "relabeling %s from %s to %s\n",
|
|
- my_file, context, newcon);
|
|
+ my_file, curcon, newcon);
|
|
else
|
|
syslog(LOG_INFO, "labeling %s to %s\n",
|
|
my_file, newcon);
|
|
}
|
|
|
|
- if (r_opts->outfile && !user_only_changed)
|
|
+ if (r_opts->outfile)
|
|
fprintf(r_opts->outfile, "%s\n", my_file);
|
|
|
|
- if (context)
|
|
- freecon(context);
|
|
-
|
|
/*
|
|
* Do not relabel the file if -n was used.
|
|
*/
|
|
- if (!r_opts->change || user_only_changed)
|
|
+ if (!r_opts->change)
|
|
goto out;
|
|
|
|
/*
|
|
@@ -220,12 +255,15 @@ static int restore(FTSENT *ftsent)
|
|
}
|
|
ret = 1;
|
|
out:
|
|
+ freecon(curcon);
|
|
freecon(newcon);
|
|
return ret;
|
|
skip:
|
|
+ freecon(curcon);
|
|
freecon(newcon);
|
|
return SKIP;
|
|
err:
|
|
+ freecon(curcon);
|
|
freecon(newcon);
|
|
return ERR;
|
|
}
|
|
@@ -447,22 +485,6 @@ int add_exclude(const char *directory)
|
|
return 0;
|
|
}
|
|
|
|
-/* Compare two contexts to see if their differences are "significant",
|
|
- * or whether the only difference is in the user. */
|
|
-static int only_changed_user(const char *a, const char *b)
|
|
-{
|
|
- char *rest_a, *rest_b; /* Rest of the context after the user */
|
|
- if (r_opts->force)
|
|
- return 0;
|
|
- if (!a || !b)
|
|
- return 0;
|
|
- rest_a = strchr(a, ':');
|
|
- rest_b = strchr(b, ':');
|
|
- if (!rest_a || !rest_b)
|
|
- return 0;
|
|
- return (strcmp(rest_a, rest_b) == 0);
|
|
-}
|
|
-
|
|
/*
|
|
* Evaluate the association hash table distribution.
|
|
*/
|
|
diff --git a/policycoreutils/setfiles/restore.h b/policycoreutils/setfiles/restore.h
|
|
index ac27222..4b39972 100644
|
|
--- a/policycoreutils/setfiles/restore.h
|
|
+++ b/policycoreutils/setfiles/restore.h
|
|
@@ -40,6 +40,7 @@ struct restore_opts {
|
|
int fts_flags; /* Flags to fts, e.g. follow links, follow mounts */
|
|
const char *selabel_opt_validate;
|
|
const char *selabel_opt_path;
|
|
+ const char **selabel_opt_prefixes;
|
|
};
|
|
|
|
void restore_init(struct restore_opts *opts);
|
|
diff --git a/policycoreutils/setfiles/restorecon.8 b/policycoreutils/setfiles/restorecon.8
|
|
index c8ea4bb..65a59de 100644
|
|
--- a/policycoreutils/setfiles/restorecon.8
|
|
+++ b/policycoreutils/setfiles/restorecon.8
|
|
@@ -4,22 +4,27 @@ restorecon \- restore file(s) default SELinux security contexts.
|
|
|
|
.SH "SYNOPSIS"
|
|
.B restorecon
|
|
-.I [\-o outfilename ] [\-R] [\-n] [\-p] [\-v] [\-e directory ] pathname...
|
|
+.I [\-o outfilename ] [\-R] [\-n] [\-p] [\-v] [\-e directory ] [\-L labelprefix ] pathname...
|
|
.P
|
|
.B restorecon
|
|
-.I \-f infilename [\-o outfilename ] [\-e directory ] [\-R] [\-n] [\-p] [\-v] [\-F]
|
|
+.I \-f infilename [\-o outfilename ] [\-e directory ] [\-L labelprefix ] [\-R] [\-n] [\-p] [\-v] [\-F]
|
|
|
|
.SH "DESCRIPTION"
|
|
This manual page describes the
|
|
.BR restorecon
|
|
program.
|
|
.P
|
|
-This program is primarily used to set the security context
|
|
+This program is primarily used to reset the security context (type)
|
|
(extended attributes) on one or more files.
|
|
.P
|
|
It can be run at any time to correct errors, to add support for
|
|
new policy, or with the \-n option it can just check whether the file
|
|
contexts are all as you expect.
|
|
+.P
|
|
+If a file object does not have a context, restorecon will write the default
|
|
+context to the file object's extended attributes. If a file object has a
|
|
+context, restorecon will only modify the type portion of the security context.
|
|
+The -F option will force a replacement of the entire context.
|
|
|
|
.SH "OPTIONS"
|
|
.TP
|
|
@@ -32,6 +37,12 @@ infilename contains a list of files to be processed by application. Use \- for s
|
|
.B \-e directory
|
|
directory to exclude (repeat option for more than one directory.)
|
|
.TP
|
|
+.B \-L labelprefix
|
|
+Tells selinux to only use the file context that match this prefix for labeling, -L can be called multiple times. Can speed up labeling if you are only doing one directory.
|
|
+
|
|
+# restorecon -R -v -L /dev /dev
|
|
+
|
|
+.TP
|
|
.B \-R \-r
|
|
change files and directories file labels recursively
|
|
.TP
|
|
@@ -47,11 +58,8 @@ show progress by printing * every 1000 files.
|
|
.B \-v
|
|
show changes in file labels.
|
|
.TP
|
|
-.B \-vv
|
|
-show changes in file labels, if type, role, or user are changing.
|
|
-.TP
|
|
.B \-F
|
|
-Force reset of context to match file_context for customizable files, or the user section, if it has changed.
|
|
+Force reset of context to match file_context for customizable files, and the default file context, changing the user, role, range portion as well as the type.
|
|
.TP
|
|
.SH "ARGUMENTS"
|
|
.B pathname...
|
|
diff --git a/policycoreutils/setfiles/setfiles.8 b/policycoreutils/setfiles/setfiles.8
|
|
index 7f700ca..2741919 100644
|
|
--- a/policycoreutils/setfiles/setfiles.8
|
|
+++ b/policycoreutils/setfiles/setfiles.8
|
|
@@ -4,7 +4,7 @@ setfiles \- set file SELinux security contexts.
|
|
|
|
.SH "SYNOPSIS"
|
|
.B setfiles
|
|
-.I [\-c policy ] [\-d] [\-l] [\-n] [\-e directory ] [\-o filename ] [\-q] [\-s] [\-v] [\-vv] [\-W] [\-F] spec_file pathname...
|
|
+.I [\-c policy ] [\-d] [\-l] [\-n] [\-e directory ] [\-o filename ] [\-L labelprefix ] [\-q] [\-s] [\-v] [\-W] [\-F] spec_file pathname...
|
|
.SH "DESCRIPTION"
|
|
This manual page describes the
|
|
.BR setfiles
|
|
@@ -17,6 +17,11 @@ program is initially run as part of the SE Linux installation process.
|
|
It can also be run at any time to correct errors, to add support for
|
|
new policy, or with the \-n option it can just check whether the file
|
|
contexts are all as you expect.
|
|
+.P
|
|
+If a file object does not have a context, setfiles will write the default
|
|
+context to the file object's extended attributes. If a file object has a
|
|
+context, setfiles will only modify the type portion of the security context.
|
|
+The -F option will force a replacement of the entire context.
|
|
|
|
.SH "OPTIONS"
|
|
.TP
|
|
@@ -45,8 +50,11 @@ use an alternate root path
|
|
directory to exclude (repeat option for more than one directory.)
|
|
.TP
|
|
.B \-F
|
|
-Force reset of context to match file_context for customizable files
|
|
+Force reset of context to match file_context for customizable files, and the default file context, changing the user, role, range portion as well as the type.
|
|
.TP
|
|
+.B \-L labelprefix
|
|
+Tells selinux to only use the file context that match this prefix for labeling, -L can be called multiple times. Can speed up labeling if you are only doing one directory.
|
|
+.TP
|
|
.B \-o filename
|
|
save list of files with incorrect context in filename.
|
|
.TP
|
|
@@ -55,10 +63,7 @@ take a list of files from standard input instead of using a pathname on the
|
|
command line.
|
|
.TP
|
|
.B \-v
|
|
-show changes in file labels, if type or role are changing.
|
|
-.TP
|
|
-.B \-vv
|
|
-show changes in file labels, if type, role, or user are changing.
|
|
+show changes in file labels.
|
|
.TP
|
|
.B \-W
|
|
display warnings about entries that had no matching files.
|
|
diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c
|
|
index fa0cd6a..0ec0eff 100644
|
|
--- a/policycoreutils/setfiles/setfiles.c
|
|
+++ b/policycoreutils/setfiles/setfiles.c
|
|
@@ -39,7 +39,7 @@ void usage(const char *const name)
|
|
{
|
|
if (iamrestorecon) {
|
|
fprintf(stderr,
|
|
- "usage: %s [-iFnprRv0] [-e excludedir ] [-o filename ] [-f filename | pathname... ]\n",
|
|
+ "usage: %s [-iFnprRv0] [ -L labelprefix ] [-e excludedir ] [-o filename ] [-f filename | pathname... ]\n",
|
|
name);
|
|
} else {
|
|
fprintf(stderr,
|
|
@@ -137,7 +137,7 @@ static void maybe_audit_mass_relabel(int mass_relabel, int mass_relabel_errs)
|
|
int main(int argc, char **argv)
|
|
{
|
|
struct stat sb;
|
|
- int opt, i = 0;
|
|
+ int opt, i;
|
|
char *input_filename = NULL;
|
|
int use_input_file = 0;
|
|
char *buf = NULL;
|
|
@@ -145,6 +145,8 @@ int main(int argc, char **argv)
|
|
int recurse; /* Recursive descent. */
|
|
char *base;
|
|
int mass_relabel = 0, errors = 0;
|
|
+ int num_prefixes = 0;
|
|
+ const char *null_array[1] = { NULL };
|
|
|
|
memset(&r_opts, 0, sizeof(r_opts));
|
|
|
|
@@ -160,6 +162,7 @@ int main(int argc, char **argv)
|
|
r_opts.outfile = NULL;
|
|
r_opts.force = 0;
|
|
r_opts.hard_links = 1;
|
|
+ r_opts.selabel_opt_prefixes = null_array;
|
|
|
|
altpath = NULL;
|
|
|
|
@@ -217,7 +220,7 @@ int main(int argc, char **argv)
|
|
exclude_non_seclabel_mounts();
|
|
|
|
/* Process any options. */
|
|
- while ((opt = getopt(argc, argv, "c:de:f:ilnpqrsvo:FRW0")) > 0) {
|
|
+ while ((opt = getopt(argc, argv, "c:de:f:ilnpqrsvo:FL:RW0")) > 0) {
|
|
switch (opt) {
|
|
case 'c':
|
|
{
|
|
@@ -280,6 +283,35 @@ int main(int argc, char **argv)
|
|
case 'n':
|
|
r_opts.change = 0;
|
|
break;
|
|
+ case 'L':
|
|
+ {
|
|
+ char **new_prefixes;
|
|
+
|
|
+ /* we need 1 for this entry and 1 for the NULL entry */
|
|
+ new_prefixes = malloc(sizeof(*new_prefixes) * (num_prefixes + 2));
|
|
+ if (!new_prefixes) {
|
|
+ fprintf(stderr, "Can't allocate memory for labeling prefix %s:%s\n",
|
|
+ optarg, strerror(errno));
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ memcpy(new_prefixes, r_opts.selabel_opt_prefixes, sizeof(*new_prefixes) * num_prefixes);
|
|
+ new_prefixes[num_prefixes] = strdup(optarg);
|
|
+ if (!new_prefixes[num_prefixes]) {
|
|
+ fprintf(stderr, "Can't allocate memory for labeling prefix %s:%s\n",
|
|
+ optarg, strerror(errno));
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
+ new_prefixes[num_prefixes + 1] = NULL;
|
|
+ num_prefixes++;
|
|
+
|
|
+ if (r_opts.selabel_opt_prefixes != null_array)
|
|
+ free(r_opts.selabel_opt_prefixes);
|
|
+
|
|
+ r_opts.selabel_opt_prefixes = (const char **)new_prefixes;
|
|
+ break;
|
|
+ }
|
|
case 'o':
|
|
if (strcmp(optarg, "-") == 0) {
|
|
r_opts.outfile = stdout;
|
|
@@ -433,7 +465,15 @@ int main(int argc, char **argv)
|
|
if (r_opts.outfile)
|
|
fclose(r_opts.outfile);
|
|
|
|
- if (r_opts.progress && r_opts.count >= STAR_COUNT)
|
|
- printf("\n");
|
|
+ if (r_opts.progress && r_opts.count >= STAR_COUNT)
|
|
+ printf("\n");
|
|
+
|
|
+ free(r_opts.progname);
|
|
+ i = 0;
|
|
+ while (r_opts.selabel_opt_prefixes[i])
|
|
+ free((void *)r_opts.selabel_opt_prefixes[i++]);
|
|
+ if (r_opts.selabel_opt_prefixes != null_array)
|
|
+ free(r_opts.selabel_opt_prefixes);
|
|
+ free(r_opts.rootpath);
|
|
exit(errors);
|
|
}
|