From 5d97d38d1b5c051b951555507e0a209eab36ad21 Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Fri, 15 Nov 2013 09:06:16 -0500 Subject: [PATCH] Speed up startup time of sepolicy gui - Clean up ports screen to only show enabled ports. - Update to upstream * Remove import policycoreutils.default_encoding_utf8 from semanage from Dan Walsh. * Make yum/extract_rpms optional for sepolicy generate from Dan Walsh. * Add test suite for audit2allow and sepolgen-ifgen from Dan Walsh. --- policycoreutils-rhat.patch | 6312 ++++++++++++++++++++++++------------ policycoreutils.spec | 99 +- sepolicy-icons.tgz | Bin 0 -> 31883 bytes sources | 4 +- 4 files changed, 4330 insertions(+), 2085 deletions(-) create mode 100644 sepolicy-icons.tgz diff --git a/policycoreutils-rhat.patch b/policycoreutils-rhat.patch index 8badd32..38b9846 100644 --- a/policycoreutils-rhat.patch +++ b/policycoreutils-rhat.patch @@ -8,121 +8,59 @@ index 83ebd45..bea9814 100644 INOTIFYH = $(shell ls /usr/include/sys/inotify.h 2>/dev/null) -diff --git a/policycoreutils/audit2allow/Makefile b/policycoreutils/audit2allow/Makefile -index fc290ea..f838b13 100644 ---- a/policycoreutils/audit2allow/Makefile -+++ b/policycoreutils/audit2allow/Makefile -@@ -4,12 +4,16 @@ BINDIR ?= $(PREFIX)/bin - LIBDIR ?= $(PREFIX)/lib - MANDIR ?= $(PREFIX)/share/man - LOCALEDIR ?= /usr/share/locale -+PYTHON ?= /usr/bin/python +diff --git a/policycoreutils/audit2allow/sepolgen-ifgen b/policycoreutils/audit2allow/sepolgen-ifgen +index 3967ba5..7f8caaf 100644 +--- a/policycoreutils/audit2allow/sepolgen-ifgen ++++ b/policycoreutils/audit2allow/sepolgen-ifgen +@@ -63,7 +63,7 @@ def parse_options(): - all: audit2why + def get_policy(): + p = selinux.selinux_current_policy_path() +- if os.path.exists(p): ++ if p and os.path.exists(p): + return p + i = selinux.security_policyvers() + p = selinux.selinux_binary_policy_path() + "." + str(i) +@@ -82,7 +82,7 @@ def get_attrs(policy_path): + sys.stderr.write("No installed policy to check\n") + return None + outfile = tempfile.NamedTemporaryFile() +- except IOError, e: ++ except IOError as e: + sys.stderr.write("could not open attribute output file\n") + return None + except OSError: +@@ -100,7 +100,7 @@ def get_attrs(policy_path): + try: + attrs.from_file(outfile) + except: +- print "error parsing attribute info" ++ print("error parsing attribute info") + return None - audit2why: - ln -sf audit2allow audit2why + return attrs +@@ -111,7 +111,7 @@ def main(): + # Open the output first to generate errors before parsing + try: + f = open(options.output, "w") +- except IOError, e: ++ except IOError as e: + sys.stderr.write("could not open output file [%s]\n" % options.output) + return 1 -+test: all -+ @$(PYTHON) test_audit2allow.py -v -+ - install: all - -mkdir -p $(BINDIR) - install -m 755 audit2allow $(BINDIR) -diff --git a/policycoreutils/audit2allow/test.log b/policycoreutils/audit2allow/test.log -new file mode 100644 -index 0000000..8d23541 ---- /dev/null -+++ b/policycoreutils/audit2allow/test.log -@@ -0,0 +1,36 @@ -+node=bill.example.com type=AVC_PATH msg=audit(1166045975.667:1128): path="/usr/lib/libGL.so.1.2" -+type=AVC msg=audit(1166045975.667:1129): avc: denied { write } for comm=local dev=dm-0 name=root.lock pid=10581 scontext=system_u:system_r:postfix_local_t:s0 tclass=file tcontext=system_u:object_r:mail_spool_t:s0 -+node=bob.example.com type=PATH msg=audit(1166111074.191:74): item=0 name="/etc/auto.net" inode=16483485 dev=fd:00 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:automount_lock_t:s0 type=CWD msg=audit(1166111074.191:74): cwd="/" -+node=bob.example.com type=SYSCALL msg=audit(1166111074.191:74): arch=40000003 syscall=33 success=no exit=-13 a0=92c5288 a1=1 a2=154d50 a3=92c5120 items=1 ppid=13935 pid=13944 auid=3267 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) comm="automount" exe="/usr/sbin/automount" subj=system_u:system_r:automount_t:s0 key=(null) -+node=bob.example.com type=AVC msg=audit(1166111074.191:74): avc: denied { execute } for pid=13944 comm="automount" name="auto.net" dev=dm-0 ino=16483485 scontext=system_u:system_r:automount_t:s0 tcontext=system_u:object_r:automount_lock_t:s0 tclass=file -+node=james.example.com type=SYSCALL msg=audit(1165963069.244:851): arch=40000003 syscall=102 success=no exit=-13 a0=2 a1=bf96a830 a2=b5b1e8 a3=9e58ac0 items=0 ppid=21133 pid=21134 auid=3267 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts10 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) -+node=james.example.com type=AVC msg=audit(1165963069.244:851): avc: denied { name_bind } for pid=21134 comm="httpd" src=81 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:reserved_port_t:s0 tclass=tcp_socket -+node=tom.example.com type=SYSCALL msg=audit(1165963069.244:852): arch=40000003 syscall=102 success=no exit=-13 a0=2 a1=bf96a830 a2=b5b1e8 a3=9e58ac0 items=0 ppid=21133 pid=21134 auid=3267 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts10 comm="smbd" exe="/usr/sbin/smbd" subj=system_u:system_r:smbd_t:s0 key=(null) -+node=tom.example.com type=AVC msg=audit(1165963069.244:852): avc: denied { name_connect } for pid=21134 comm="smbd" src=81 scontext=system_u:system_r:smbd_t:s0 tcontext=system_u:object_r:reserved_port_t:s0 tclass=tcp_socket -+node=mary.example.com type=SYSCALL msg=audit(1166023021.373:910): arch=40000003 syscall=12 success=no exit=-13 a0=8493cd8 a1=cc3 a2=3282ec a3=bf992a04 items=0 ppid=24423 pid=24427 auid=3267 uid=0 gid=0 euid=3267 suid=3267 fsuid=3267 egid=3267 sgid=3267 fsgid=3267 tty=(none) comm="vsftpd" exe="/usr/sbin/vsftpd" subj=system_u:system_r:ftpd_t:s0 key=(null) -+node=mary.example.com type=AVC msg=audit(1166023021.373:910): avc: denied { search } for pid=24427 comm="vsftpd" name="home" dev=dm-0 ino=9338881 scontext=system_u:system_r:ftpd_t:s0 tcontext=system_u:object_r:home_root_t:s0 tclass=dir -+node=tom.example.com type=SYSCALL msg=audit(1165963069.244:852): arch=40000003 syscall=102 success=no exit=-13 a0=2 a1=bf96a830 a2=b5b1e8 a3=9e58ac0 items=0 ppid=21133 pid=21134 auid=3267 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts10 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) -+node=tom.example.com type=AVC msg=audit(1165963069.244:852): avc: denied { name_connect } for pid=21134 comm="httpd" src=81 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:reserved_port_t:s0 tclass=tcp_socket -+node=dan.example.com type=AVC_PATH msg=audit(1166017682.366:877): path="/var/www/html/index.html" -+node=dan.example.com type=SYSCALL msg=audit(1166017682.366:877): arch=40000003 syscall=196 success=no exit=-13 a0=96226a8 a1=bf88b01c a2=31fff4 a3=2008171 items=0 ppid=23762 pid=23768 auid=3267 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) -+node=dan.example.com type=AVC msg=audit(1166017682.366:877): avc: denied { execute_no_trans } for pid=23768 comm="httpd" name="index.html" dev=dm-0 ino=7996439 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:var_t:s0 tclass=file -+node=judy.example.com type=SYSCALL msg=audit(1165963069.244:853): arch=40000003 syscall=102 success=no exit=-13 a0=2 a1=bf96a830 a2=b5b1e8 a3=9e58ac0 items=0 ppid=21133 pid=21134 auid=3267 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts10 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) -+node=judy.example.com type=AVC msg=audit(1165963069.244:853): avc: denied { name_connect } for pid=21134 comm="httpd" src=81 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:mysqld_port_t:s0 tclass=tcp_socket -+node=judy.example.com type=SYSCALL msg=audit(1165963069.244:853): arch=40000003 syscall=102 success=no exit=-13 a0=2 a1=bf96a830 a2=b5b1e8 a3=9e58ac0 items=0 ppid=21133 pid=21134 auid=3267 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts10 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) -+node=judy.example.com type=AVC msg=audit(1165963069.244:853): avc: denied { name_connect } for pid=21134 comm="httpd" src=81 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:reserved_port_t:s0 tclass=tcp_socket -+node=patty.example.com type=AVC_PATH msg=audit(1166036885.378:1097): path="/var/www/cgi-bin" -+node=patty.example.com type=SYSCALL msg=audit(1166036885.378:1097): arch=40000003 syscall=196 success=no exit=-13 a0=9624f38 a1=bf88b11c a2=31fff4 a3=2008171 items=0 ppid=23762 pid=23770 auid=3267 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) -+node=patty.example.com type=AVC msg=audit(1166036885.378:1097): avc: denied { execute } for pid=23770 comm="httpd" name="cgi-bin" dev=dm-0 ino=7995597 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_script_exec_t:s0 tclass=file -+node=sam.example.com type=SYSCALL msg=audit(1166038880.318:1103): arch=40000003 syscall=5 success=no exit=-13 a0=bf96f068 a1=18800 a2=0 a3=bf973110 items=0 ppid=23765 pid=12387 auid=3267 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) comm="sealert.cgi" exe="/usr/bin/perl" subj=system_u:system_r:httpd_sys_script_t:s0 key=(null) -+node=sam.example.com type=AVC msg=audit(1166038880.318:1103): avc: denied { write } for pid=12387 comm="sealert.cgi" name="sealert-upload" dev=dm-0 ino=8093724 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=file -+node=holycross.devel.redhat.com type=AVC_PATH msg=audit(1166027294.395:952): path="/home/devel/dwalsh/public_html" -+node=holycross.devel.redhat.com type=SYSCALL msg=audit(1166027294.395:952): arch=40000003 syscall=196 success=yes exit=0 a0=8495230 a1=849c830 a2=874ff4 a3=328d28 items=0 ppid=7234 pid=7236 auid=3267 uid=3267 gid=3267 euid=3267 suid=3267 fsuid=3267 egid=3267 sgid=3267 fsgid=3267 tty=(none) comm="vsftpd" exe="/usr/sbin/vsftpd" subj=system_u:system_r:ftpd_t:s0 key=(null) -+node=holycross.devel.redhat.com type=AVC msg=audit(1166027294.395:952): avc: denied { getattr } for pid=7236 comm="vsftpd" name="public_html" dev=dm-0 ino=9601649 scontext=system_u:system_r:ftpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=file -+host=dhcppc2 type=AVC msg=audit(1216729188.853:241): avc: denied { read } for pid=14066 comm="qemu-kvm" name="HelpdeskRHEL4-RHEL4.x86_64" dev=tmpfs ino=333 scontext=system_u:system_r:qemu_t:s0 tcontext=system_u:object_r:fixed_disk_device_t:s0 tclass=blk_file host=dhcppc2 type=SYSCALL msg=audit(1216729188.853:241): arch=c000003e syscall=2 success=no exit=-13 a0=7fff6f654680 a1=0 a2=1a4 a3=3342f67a70 items=0 ppid=2953 pid=14066 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="qemu-kvm" exe="/usr/bin/qemu-kvm" subj=system_u:system_r:qemu_t:s0 key=(null) -+node=mallorn.farre.nom type=AVC msg=audit(1228276291.360:466): avc: denied { execute } for pid=13015 comm="npviewer.bin" path="/opt/real/RealPlayer/mozilla/nphelix.so" dev=dm-0 ino=2850912 scontext=unconfined_u:unconfined_r:nsplugin_t:s0 tcontext=unconfined_u:object_r:usr_t:s0 tclass=file -+node=mallorn.farre.nom type=SYSCALL msg=audit(1228276291.360:466): arch=40000003 syscall=192 success=no exit=-13 a0=0 a1=9eec a2=5 a3=802 items=0 ppid=13014 pid=13015 auid=500 uid=500 gid=500 euid=500 suid=500 fsuid=500 egid=500 sgid=500 fsgid=500 tty=(none) ses=63 comm="npviewer.bin" exe="/usr/lib/nspluginwrapper/npviewer.bin" subj=unconfined_u:unconfined_r:nsplugin_t:s0 key=(null) -+node=mary.example.com type=SYSCALL msg=audit(1166023021.373:910): arch=40000003 syscall=12 success=no exit=-13 a0=8493cd8 a1=cc3 a2=3282ec a3=bf992a04 items=0 ppid=24423 pid=24427 auid=3267 uid=0 gid=0 euid=3267 suid=3267 fsuid=3267 egid=3267 sgid=3267 fsgid=3267 tty=(none) comm="vssmbd" exe="/usr/sbin/vssmbd" subj=system_u:system_r:smbd_t:s0 key=(null) -+node=mary.example.com type=AVC msg=audit(1166023021.373:910): avc: denied { read } for pid=24427 comm="vssmbd" name="home" dev=dm-0 ino=9338881 scontext=system_u:system_r:smbd_t:s0 tcontext=system_u:object_r:ssh_home_t:s0 tclass=file -+node=lilly.example.com type=AVC_PATH msg=audit(1164783469.561:109): path="/linuxtest/LVT/lvt/log.current" -+node=lilly.example.com type=SYSCALL msg=audit(1164783469.561:109): arch=14 syscall=11 success=yes exit=0 a0=10120520 a1=10120a78 a2=10120970 a3=118 items=0 ppid=8310 pid=8311 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) comm="smbd" exe="/usr/sbin/smbd" subj=root:system_r:smbd_t:s0 key=(null) -+node=lilly.example.com type=AVC msg=audit(1164783469.561:109): avc: denied { append } for pid=8311 comm="smbd" name="log.current" dev=dm-0 ino=130930 scontext=root:system_r:smbd_t:s0 tcontext=root:object_r:default_t:s0 tclass=dir -diff --git a/policycoreutils/audit2allow/test_audit2allow.py b/policycoreutils/audit2allow/test_audit2allow.py -new file mode 100644 -index 0000000..d7d872e ---- /dev/null -+++ b/policycoreutils/audit2allow/test_audit2allow.py -@@ -0,0 +1,46 @@ -+import unittest, os, shutil -+from tempfile import mkdtemp -+from subprocess import Popen, PIPE -+ -+class Audit2allowTests(unittest.TestCase): -+ def assertDenied(self, err): -+ self.assert_('Permission denied' in err, -+ '"Permission denied" not found in %r' % err) -+ def assertNotFound(self, err): -+ self.assert_('not found' in err, -+ '"not found" not found in %r' % err) -+ -+ def assertFailure(self, status): -+ self.assert_(status != 0, -+ '"Succeeded when it should have failed') -+ -+ def assertSuccess(self, cmd, status, err): -+ self.assert_(status == 0, -+ '"%s should have succeeded for this test %r' % (cmd, err)) -+ -+ def test_sepolgen_ifgen(self): -+ "Verify sepolgen-ifgen works" -+ p = Popen(['sudo', 'sepolgen-ifgen'], stdout = PIPE) -+ out, err = p.communicate() -+ if err: -+ print(out, err) -+ self.assertSuccess("sepolgen-ifgen", p.returncode, err) -+ -+ def test_audit2allow(self): -+ "Verify audit2allow works" -+ p = Popen(['audit2allow',"-i","test.log"], stdout = PIPE) -+ out, err = p.communicate() -+ if err: -+ print(out, err) -+ self.assertSuccess("audit2allow", p.returncode, err) -+ -+ def test_audit2why(self): -+ "Verify audit2why works" -+ p = Popen(['audit2why',"-i","test.log"], stdout = PIPE) -+ out, err = p.communicate() -+ if err: -+ print(out, err) -+ self.assertSuccess("audit2why", p.returncode, err) -+ -+if __name__ == "__main__": -+ unittest.main() +@@ -130,9 +130,9 @@ def main(): + # Parse the headers + try: + headers = refparser.parse_headers(options.headers, output=log, debug=options.debug) +- except ValueError, e: +- print "error parsing headers" +- print str(e) ++ except ValueError as e: ++ print("error parsing headers") ++ print(str(e)) + return 1 + + if_set = interfaces.InterfaceSet(output=log) diff --git a/policycoreutils/gui/Makefile b/policycoreutils/gui/Makefile index 9d9f820..0c2b390 100644 --- a/policycoreutils/gui/Makefile @@ -253273,6 +253211,30 @@ index fb5a24c..3668abe 100644 if self.__options.setype: self.setype = self.__options.setype +diff --git a/policycoreutils/semanage/Makefile b/policycoreutils/semanage/Makefile +index 8fc8e0b..9bb4f24 100644 +--- a/policycoreutils/semanage/Makefile ++++ b/policycoreutils/semanage/Makefile +@@ -3,8 +3,7 @@ PREFIX ?= $(DESTDIR)/usr + LIBDIR ?= $(PREFIX)/lib + SBINDIR ?= $(PREFIX)/sbin + MANDIR = $(PREFIX)/share/man +-PYLIBVER ?= $(shell python -c 'import sys;print "python%d.%d" % sys.version_info[0:2]') +-PYTHONLIBDIR ?= $(LIBDIR)/$(PYLIBVER) ++PYTHON ?= /usr/bin/python + BASHCOMPLETIONDIR ?= $(DESTDIR)/usr/share/bash-completion/completions + + TARGETS=semanage +@@ -18,8 +17,7 @@ install: all + -mkdir -p $(SBINDIR) + install -m 755 semanage $(SBINDIR) + install -m 644 *.8 $(MANDIR)/man8 +- test -d $(PYTHONLIBDIR)/site-packages || install -m 755 -d $(PYTHONLIBDIR)/site-packages +- install -m 755 seobject.py $(PYTHONLIBDIR)/site-packages ++ LDFLAGS="" ${PYTHON} setup.py install --root=$(DESTDIR)/ + -mkdir -p $(BASHCOMPLETIONDIR) + install -m 644 $(BASHCOMPLETIONS) $(BASHCOMPLETIONDIR)/semanage + diff --git a/policycoreutils/semanage/default_encoding/Makefile b/policycoreutils/semanage/default_encoding/Makefile new file mode 100644 index 0000000..e15a877 @@ -253418,10 +253380,10 @@ index 0000000..e2befdb + packages=["policycoreutils"], +) diff --git a/policycoreutils/semanage/semanage b/policycoreutils/semanage/semanage -index bd6c526..9204622 100644 +index 36b41cd..c46c9e5 100644 --- a/policycoreutils/semanage/semanage +++ b/policycoreutils/semanage/semanage -@@ -18,25 +18,33 @@ +@@ -18,24 +18,34 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software @@ -253431,11 +253393,11 @@ index bd6c526..9204622 100644 # # --import policycoreutils.default_encoding_utf8 +try: + import policycoreutils.default_encoding_utf8 +except ImportError: + pass ++ import argparse import seobject import sys @@ -253463,7 +253425,7 @@ index bd6c526..9204622 100644 # define custom usages for selected main actions usage_login = "semanage login [-h] [-n] [-N] [-s STORE] [" -@@ -62,16 +70,16 @@ usage_boolean_dict = {' --modify':('(','--on','|','--off',')','boolean'), ' --li +@@ -61,16 +71,16 @@ usage_boolean_dict = {' --modify':('(','--on','|','--off',')','boolean'), ' --li import sepolicy class CheckRole(argparse.Action): @@ -253490,7 +253452,7 @@ index bd6c526..9204622 100644 store = '' class SetStore(argparse.Action): -@@ -104,7 +112,7 @@ class SetImportFile(argparse.Action): +@@ -103,7 +113,7 @@ class SetImportFile(argparse.Action): if values and values is not "-": try: sys.stdin = open(values, 'r') @@ -253499,7 +253461,7 @@ index bd6c526..9204622 100644 sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) sys.exit(1) setattr(namespace, self.dest, values) -@@ -156,7 +164,7 @@ object_dict = {'login':login_ini, 'user':user_ini, 'port':port_ini, 'module':mod +@@ -155,7 +165,7 @@ object_dict = {'login':login_ini, 'user':user_ini, 'port':port_ini, 'module':mod def generate_custom_usage(usage_text,usage_dict): # generate custom usage from given text and dictonary sorted_keys = [] @@ -253508,7 +253470,7 @@ index bd6c526..9204622 100644 sorted_keys.append(i) sorted_keys.sort() for k in sorted_keys: -@@ -171,18 +179,18 @@ def handle_opts(args,dict,target_key): +@@ -170,18 +180,18 @@ def handle_opts(args,dict,target_key): # {action:[conflict_opts,require_opts]} # first we need to catch conflicts @@ -253531,7 +253493,7 @@ index bd6c526..9204622 100644 sys.exit(2) except KeyError: continue -@@ -208,7 +216,7 @@ def handleLogin(args): +@@ -207,7 +217,7 @@ def handleLogin(args): OBJECT.deleteall() if args.action is "extract": for i in OBJECT.customized(): @@ -253540,7 +253502,16 @@ index bd6c526..9204622 100644 def parser_add_store(parser, name): parser.add_argument('-S', '--store', action=SetStore, help=_("Select an alternate SELinux Policy Store to manage")) -@@ -290,7 +298,7 @@ def handleFcontext(args): +@@ -229,7 +239,7 @@ def parser_add_type(parser, name): + def parser_add_level(parser, name): + parser.add_argument('-L', '--level', default='s0', help=_('Default SELinux Level for SELinux user, s0 Default. (MLS/MCS Systems only)')) + def parser_add_range(parser, name): +- parser.add_argument('-r', '--range', default="s0", ++ parser.add_argument('-r', '--range', default=None, + help=_(''' + MLS/MCS Security Range (MLS/MCS Systems only) + SELinux Range for SELinux login mapping +@@ -289,7 +299,7 @@ def handleFcontext(args): fcontext_equal_args = {'equal':[('list','locallist','type','ftype','seuser','deleteall','extract'),()]} if args.action is None: @@ -253549,7 +253520,7 @@ index bd6c526..9204622 100644 sys.exit(2) elif args.action and args.equal: handle_opts(args, fcontext_equal_args, "equal") -@@ -321,7 +329,7 @@ def handleFcontext(args): +@@ -320,7 +330,7 @@ def handleFcontext(args): OBJECT.deleteall() if args.action is "extract": for i in OBJECT.customized(): @@ -253558,7 +253529,7 @@ index bd6c526..9204622 100644 def setupFcontextParser(subparsers): ftype_help = ''' -@@ -379,7 +387,7 @@ def handleUser(args): +@@ -378,7 +388,7 @@ def handleUser(args): OBJECT.deleteall() if args.action is "extract": for i in OBJECT.customized(): @@ -253567,7 +253538,7 @@ index bd6c526..9204622 100644 def setupUserParser(subparsers): generated_usage = generate_custom_usage(usage_user, usage_user_dict) -@@ -428,7 +436,7 @@ def handlePort(args): +@@ -427,7 +437,7 @@ def handlePort(args): OBJECT.deleteall() if args.action is "extract": for i in OBJECT.customized(): @@ -253576,7 +253547,7 @@ index bd6c526..9204622 100644 def setupPortParser(subparsers): generated_usage = generate_custom_usage(usage_port, usage_port_dict) -@@ -471,7 +479,7 @@ def handleInterface(args): +@@ -470,7 +480,7 @@ def handleInterface(args): OBJECT.deleteall() if args.action is "extract": for i in OBJECT.customized(): @@ -253585,7 +253556,7 @@ index bd6c526..9204622 100644 def setupInterfaceParser(subparsers): generated_usage = generate_custom_usage(usage_interface, usage_interface_dict) -@@ -510,7 +518,7 @@ def handleModule(args): +@@ -509,7 +519,7 @@ def handleModule(args): OBJECT.list(args.noheading, args.locallist) if args.action is "extract": for i in OBJECT.customized(): @@ -253594,7 +253565,7 @@ index bd6c526..9204622 100644 def setupModuleParser(subparsers): moduleParser = subparsers.add_parser('module', help=_('Manage SELinux policy modules')) -@@ -549,7 +557,7 @@ def handleNode(args): +@@ -548,7 +558,7 @@ def handleNode(args): OBJECT.deleteall() if args.action is "extract": for i in OBJECT.customized(): @@ -253603,7 +253574,7 @@ index bd6c526..9204622 100644 def setupNodeParser(subparsers): generated_usage = generate_custom_usage(usage_node, usage_node_dict) -@@ -577,14 +585,14 @@ def setupNodeParser(subparsers): +@@ -576,14 +586,14 @@ def setupNodeParser(subparsers): def handleBoolean(args): boolean_args = {'list':[('state','boolean'),('')],'modify':[('localist'),('')], 'extract':[('locallist','state','boolean'),('')],'deleteall':[('locallist'),('')],'state':[('locallist','list','extract','deleteall'),('modify')]} if args.action is None: @@ -253621,7 +253592,7 @@ index bd6c526..9204622 100644 sys.exit(1) else: handle_opts(args,boolean_args,args.action) -@@ -601,7 +609,7 @@ def handleBoolean(args): +@@ -600,7 +610,7 @@ def handleBoolean(args): OBJECT.deleteall() if args.action is "extract": for i in OBJECT.customized(): @@ -253630,7 +253601,7 @@ index bd6c526..9204622 100644 def setupBooleanParser(subparsers): generated_usage = generate_custom_usage(usage_boolean, usage_boolean_dict) -@@ -667,11 +675,11 @@ def setupDontauditParser(subparsers): +@@ -666,11 +676,11 @@ def setupDontauditParser(subparsers): def handleExport(args): manageditems=[ "boolean", "login", "interface", "user", "port", "node", "fcontext", "module"] for i in manageditems: @@ -253644,7 +253615,7 @@ index bd6c526..9204622 100644 sys.exit(0) -@@ -740,10 +748,10 @@ def handleImport(args): +@@ -739,10 +749,10 @@ def handleImport(args): commandParser = createCommandParser() args = commandParser.parse_args(mkargv(l)) args.func(args) @@ -253657,7 +253628,7 @@ index bd6c526..9204622 100644 sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) sys.exit(1) except KeyboardInterrupt: -@@ -761,11 +769,11 @@ def setupImportParser(subparsers): +@@ -760,11 +770,11 @@ def setupImportParser(subparsers): def createCommandParser(): commandParser = seParser(prog='semanage', @@ -253674,7 +253645,7 @@ index bd6c526..9204622 100644 #To add a new subcommand define the parser for it in a function above and call it here. subparsers = commandParser.add_subparsers(dest='subcommand') setupImportParser(subparsers) -@@ -805,6 +813,8 @@ def make_io_args(args): +@@ -804,6 +814,8 @@ def make_io_args(args): return args_subcommand+args_ie+args_file def make_args(sys_args): @@ -253683,7 +253654,7 @@ index bd6c526..9204622 100644 args = [] if "-o" in sys_args[1:] or "-i" in sys_args[1:]: args=make_io_args(sys_args[1:]) -@@ -819,21 +829,21 @@ def do_parser(): +@@ -818,21 +830,21 @@ def do_parser(): args = commandParser.parse_args(make_args(sys.argv)) args.func(args) sys.exit(0) @@ -253711,56 +253682,87 @@ index bd6c526..9204622 100644 sys.exit(1) diff --git a/policycoreutils/semanage/seobject.py b/policycoreutils/semanage/seobject.py -index b3018f3..06c36c5 100644 +deleted file mode 100644 +index b3018f3..0000000 --- a/policycoreutils/semanage/seobject.py -+++ b/policycoreutils/semanage/seobject.py -@@ -16,12 +16,12 @@ - # - # You should have received a copy of the GNU General Public License - # along with this program; if not, write to the Free Software ++++ /dev/null +@@ -1,2223 +0,0 @@ +-#! /usr/bin/python -Es +-# Copyright (C) 2005-2013 Red Hat +-# see file 'COPYING' for use and warranty information +-# +-# semanage is a tool for managing SELinux configuration files +-# +-# 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., 59 Temple Place, Suite 330, Boston, MA -+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - # 02111-1307 USA - # +-# 02111-1307 USA +-# -# -+# - +- -import pwd, grp, string, selinux, tempfile, os, re, sys, stat -+import pwd, grp, string, selinux, os, re, sys, stat - from semanage import *; - PROGNAME = "policycoreutils" - import sepolicy -@@ -30,12 +30,22 @@ gen_bool_dict() - from IPy import IP - - import gettext -+PROGNAME="policycoreutils" - gettext.bindtextdomain(PROGNAME, "/usr/share/locale") - gettext.textdomain(PROGNAME) +-from semanage import *; +-PROGNAME = "policycoreutils" +-import sepolicy +-from sepolicy import boolean_desc, boolean_category, gen_bool_dict +-gen_bool_dict() +-from IPy import IP +- +-import gettext +-gettext.bindtextdomain(PROGNAME, "/usr/share/locale") +-gettext.textdomain(PROGNAME) - -import gettext -translation=gettext.translation(PROGNAME, localedir = "/usr/share/locale", fallback=True) -_=translation.ugettext -+try: -+ gettext.install(PROGNAME, -+ unicode=True, -+ codeset = 'utf-8') -+except TypeError: -+ # Failover to python3 install -+ gettext.install(PROGNAME, -+ codeset = 'utf-8') -+except IOError: -+ import builtins -+ builtins.__dict__['_'] = str -+ -+is_mls_enabled = True - - import syslog - -@@ -74,112 +84,112 @@ file_type_str_to_option = { "all files": "a", - "symbolic link":"l", - "named pipe":"p" } - try: +- +-import syslog +- +-file_types = {} +-file_types[""] = SEMANAGE_FCONTEXT_ALL; +-file_types["all files"] = SEMANAGE_FCONTEXT_ALL; +-file_types["a"] = SEMANAGE_FCONTEXT_ALL; +-file_types["regular file"] = SEMANAGE_FCONTEXT_REG; +-file_types["--"] = SEMANAGE_FCONTEXT_REG; +-file_types["f"] = SEMANAGE_FCONTEXT_REG; +-file_types["-d"] = SEMANAGE_FCONTEXT_DIR; +-file_types["directory"] = SEMANAGE_FCONTEXT_DIR; +-file_types["d"] = SEMANAGE_FCONTEXT_DIR; +-file_types["-c"] = SEMANAGE_FCONTEXT_CHAR; +-file_types["character device"] = SEMANAGE_FCONTEXT_CHAR; +-file_types["c"] = SEMANAGE_FCONTEXT_CHAR; +-file_types["-b"] = SEMANAGE_FCONTEXT_BLOCK; +-file_types["block device"] = SEMANAGE_FCONTEXT_BLOCK; +-file_types["b"] = SEMANAGE_FCONTEXT_BLOCK; +-file_types["-s"] = SEMANAGE_FCONTEXT_SOCK; +-file_types["socket"] = SEMANAGE_FCONTEXT_SOCK; +-file_types["s"] = SEMANAGE_FCONTEXT_SOCK; +-file_types["-l"] = SEMANAGE_FCONTEXT_LINK; +-file_types["l"] = SEMANAGE_FCONTEXT_LINK; +-file_types["symbolic link"] = SEMANAGE_FCONTEXT_LINK; +-file_types["p"] = SEMANAGE_FCONTEXT_PIPE; +-file_types["-p"] = SEMANAGE_FCONTEXT_PIPE; +-file_types["named pipe"] = SEMANAGE_FCONTEXT_PIPE; +- +-file_type_str_to_option = { "all files": "a", +- "regular file":"f", +- "directory":"d", +- "character device":"c", +- "block device":"b", +- "socket file":"s", +- "symbolic link":"l", +- "named pipe":"p" } +-try: - import audit - class logger: - def __init__(self): @@ -253785,31 +253787,7 @@ index b3018f3..06c36c5 100644 - for l in self.log_list: - audit.audit_log_semanage_message(*(l + [success])) - self.log_list = [] -+ import audit -+ class logger: -+ def __init__(self): -+ self.audit_fd = audit.audit_open() -+ 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: +-except: - class logger: - def __init__(self): - self.log_list=[] @@ -253840,70 +253818,28 @@ index b3018f3..06c36c5 100644 - message = "Failed: " - for l in self.log_list: - syslog.syslog(syslog.LOG_INFO, message + l) -+ class logger: -+ 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 oldsename != "": -+ message += " oldsename=" + oldsename -+ if serole != "": -+ message += " role=" + serole -+ if oldserole != "": -+ message += " old_role=" + oldserole -+ if serange != "" and serange != None: -+ message += " MLSRange=" + serange -+ 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: +- +-class nulllogger: - def log(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""): - pass -+ 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 log_remove(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""): -+ pass - +- - def commit(self,success): - pass -+ def commit(self,success): -+ pass - - def validate_level(raw): +- +-def validate_level(raw): - sensitivity = "s[0-9]*" - category = "c[0-9]*" - cat_range = category + "(\." + category +")?" - categories = cat_range + "(\," + cat_range + ")*" - reg = sensitivity + "(-" + sensitivity + ")?" + "(:" + categories + ")?" - return re.search("^" + reg +"$", raw) -+ sensitivity = "s[0-9]*" -+ category = "c[0-9]*" -+ cat_range = category + "(\." + category +")?" -+ categories = cat_range + "(\," + cat_range + ")*" -+ reg = sensitivity + "(-" + sensitivity + ")?" + "(:" + categories + ")?" -+ return re.search("^" + reg +"$", raw) - - def translate(raw, prepend = 1): - filler = "a:b:c:" - if prepend == 1: +- +-def translate(raw, prepend = 1): +- filler = "a:b:c:" +- if prepend == 1: - context = "%s%s" % (filler, raw) - else: - context = raw @@ -253917,21 +253853,8 @@ index b3018f3..06c36c5 100644 - else: - return trans - -+ context = "%s%s" % (filler, raw) -+ else: -+ context = raw -+ (rc, trans) = selinux.selinux_raw_to_trans_context(context) -+ if rc != 0: -+ return raw -+ if prepend: -+ trans = trans[len(filler):] -+ if trans == "": -+ return raw -+ else: -+ return trans -+ - def untranslate(trans, prepend = 1): - filler = "a:b:c:" +-def untranslate(trans, prepend = 1): +- filler = "a:b:c:" - if prepend == 1: - context = "%s%s" % (filler, trans) - else: @@ -253946,153 +253869,112 @@ index b3018f3..06c36c5 100644 - return trans - else: - return raw -+ if prepend == 1: -+ context = "%s%s" % (filler, trans) -+ else: -+ context = trans -+ -+ (rc, raw) = selinux.selinux_trans_to_raw_context(context) -+ if rc != 0: -+ return trans -+ if prepend: -+ raw = raw[len(filler):] -+ if raw == "": -+ return trans -+ else: -+ return raw - - class semanageRecords: - transaction = False -@@ -187,53 +197,53 @@ class semanageRecords: - store = None - def __init__(self, store): - global handle +- +-class semanageRecords: +- transaction = False +- handle = None +- store = None +- def __init__(self, store): +- global handle - self.load = True -+ self.load = True - self.sh = self.get_handle(store) - +- self.sh = self.get_handle(store) +- - rc, localstore = selinux.selinux_getpolicytype() - if store == "" or store == localstore: - self.mylog = logger() - else: - self.mylog = nulllogger() -+ rc, localstore = selinux.selinux_getpolicytype() -+ if store == "" or store == localstore: -+ self.mylog = logger() -+ else: -+ self.mylog = nulllogger() - +- - def set_reload(self, load): - self.load = load -+ def set_reload(self, load): -+ self.load = load - - def get_handle(self, store): +- +- 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")) -@@ -254,15 +264,15 @@ class semanageRecords: - raise ValueError(_("Not yet implemented")) - - def commit(self): +- +- def deleteall(self): +- raise ValueError(_("Not yet implemented")) +- +- def start(self): +- if semanageRecords.transaction: +- raise ValueError(_("Semanage transaction already in progress")) +- self.begin() +- semanageRecords.transaction = True +- +- def begin(self): +- if semanageRecords.transaction: +- return +- rc = semanage_begin_transaction(self.sh) +- if rc < 0: +- raise ValueError(_("Could not start semanage transaction")) +- def customized(self): +- raise ValueError(_("Not yet implemented")) +- +- def commit(self): - if semanageRecords.transaction: - return -+ if semanageRecords.transaction: -+ return - +- - semanage_set_reload(self.sh, self.load) - rc = semanage_commit(self.sh) - if rc < 0: - self.mylog.commit(0) - raise ValueError(_("Could not commit semanage transaction")) - self.mylog.commit(1) -+ semanage_set_reload(self.sh, self.load) -+ 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: -@@ -271,10 +281,10 @@ class semanageRecords: - self.commit() - - class moduleRecords(semanageRecords): +- +- def finish(self): +- if not semanageRecords.transaction: +- raise ValueError(_("Semanage transaction not in progress")) +- semanageRecords.transaction = False +- self.commit() +- +-class moduleRecords(semanageRecords): - def __init__(self, store): - semanageRecords.__init__(self, store) -+ def __init__(self, store): -+ semanageRecords.__init__(self, store) - +- - def get_all(self): -+ def get_all(self): - l = [] - (rc, mlist, number) = semanage_module_list(self.sh) - if rc < 0: -@@ -286,35 +296,35 @@ class moduleRecords(semanageRecords): - return l - - def customized(self): +- l = [] +- (rc, mlist, number) = semanage_module_list(self.sh) +- if rc < 0: +- raise ValueError(_("Could not list SELinux modules")) +- +- for i in range(number): +- mod = semanage_module_list_nth(mlist, i) +- l.append((semanage_module_get_name(mod), semanage_module_get_version(mod), semanage_module_get_enabled(mod))) +- return l +- +- def customized(self): - all = self.get_all() - if len(all) == 0: - return @@ -254106,186 +253988,168 @@ index b3018f3..06c36c5 100644 - if heading: - print "\n%-25s%-10s\n" % (_("Modules Name"), _("Version")) - for t in all: -+ ALL = self.get_all() -+ if len(ALL) == 0: -+ return -+ return ["-d %s" % x[0] for x in [t for t in ALL if t[2] == 0]] -+ -+ def list(self, heading = True, locallist = False): -+ ALL = self.get_all() -+ if len(ALL) == 0: -+ return -+ -+ if heading: -+ print("\n%-25s%-10s\n" % (_("Modules Name"), _("Version"))) -+ for t in ALL: - if t[2] == 0: - disabled = _("Disabled") - else: - if locallist: - continue - disabled = "" +- if t[2] == 0: +- disabled = _("Disabled") +- else: +- if locallist: +- continue +- disabled = "" - print "%-25s%-10s%s" % (t[0], t[1], disabled) -+ print("%-25s%-10s%s" % (t[0], t[1], disabled)) - +- - def add(self, file): -+ def add(self, file): - if not os.path.exists(file): - raise ValueError(_("Module does not exists %s ") % file) - rc = semanage_module_install_file(self.sh, file); - if rc >= 0: - self.commit() - +- if not os.path.exists(file): +- raise ValueError(_("Module does not exists %s ") % file) +- rc = semanage_module_install_file(self.sh, file); +- if rc >= 0: +- self.commit() +- - def disable(self, module): -+ def disable(self, module): - need_commit = False - for m in module.split(): - rc = semanage_module_disable(self.sh, m) -@@ -325,7 +335,7 @@ class moduleRecords(semanageRecords): - if need_commit: - self.commit() - +- need_commit = False +- for m in module.split(): +- rc = semanage_module_disable(self.sh, m) +- if rc < 0 and rc != -3: +- raise ValueError(_("Could not disable module %s (remove failed)") % m) +- if rc != -3: +- need_commit = True +- if need_commit: +- self.commit() +- - def enable(self, module): -+ def enable(self, module): - need_commit = False - for m in module.split(): - rc = semanage_module_enable(self.sh, m) -@@ -336,12 +346,12 @@ class moduleRecords(semanageRecords): - if need_commit: - self.commit() - +- need_commit = False +- for m in module.split(): +- rc = semanage_module_enable(self.sh, m) +- if rc < 0 and rc != -3: +- raise ValueError(_("Could not enable module %s (remove failed)") % m) +- if rc != -3: +- need_commit = True +- if need_commit: +- self.commit() +- - def modify(self, file): - rc = semanage_module_update_file(self.sh, file); -+ def modify(self, file): -+ rc = semanage_module_upgrade_file(self.sh, file); - if rc >= 0: - self.commit() - +- if rc >= 0: +- self.commit() +- - def delete(self, module): -+ def delete(self, module): - for m in module.split(): - rc = semanage_module_remove(self.sh, m) - if rc < 0 and rc != -2: -@@ -349,27 +359,27 @@ class moduleRecords(semanageRecords): - - self.commit() - +- for m in module.split(): +- rc = semanage_module_remove(self.sh, m) +- if rc < 0 and rc != -2: +- raise ValueError(_("Could not remove module %s (remove failed)") % m) +- +- self.commit() +- - def deleteall(self): - l = map(lambda x: x[0], filter(lambda t: t[2] == 0, self.get_all())) -+ def deleteall(self): -+ l = [x[0] for x in [t for t in self.get_all() if t[2] == 0]] - for m in l: - self.enable(m) - - class dontauditClass(semanageRecords): +- for m in l: +- self.enable(m) +- +-class dontauditClass(semanageRecords): - def __init__(self, store): -+ def __init__(self, store): - semanageRecords.__init__(self, store) - +- semanageRecords.__init__(self, store) +- - def toggle(self, dontaudit): -+ def toggle(self, dontaudit): - if dontaudit not in [ "on", "off" ]: - raise ValueError(_("dontaudit requires either 'on' or 'off'")) - self.begin() +- if dontaudit not in [ "on", "off" ]: +- raise ValueError(_("dontaudit requires either 'on' or 'off'")) +- self.begin() - rc = semanage_set_disable_dontaudit(self.sh, dontaudit == "off") -+ semanage_set_disable_dontaudit(self.sh, dontaudit == "off") - self.commit() +- self.commit() - -+ - class permissiveRecords(semanageRecords): +-class permissiveRecords(semanageRecords): - def __init__(self, store): -+ def __init__(self, store): - semanageRecords.__init__(self, store) - +- semanageRecords.__init__(self, store) +- - def get_all(self): -+ def get_all(self): - l = [] - (rc, mlist, number) = semanage_module_list(self.sh) - if rc < 0: -@@ -382,33 +392,34 @@ class permissiveRecords(semanageRecords): - l.append(name.split("permissive_")[1]) - return l - +- l = [] +- (rc, mlist, number) = semanage_module_list(self.sh) +- if rc < 0: +- raise ValueError(_("Could not list SELinux modules")) +- +- for i in range(number): +- mod = semanage_module_list_nth(mlist, i) +- name = semanage_module_get_name(mod) +- if name and name.startswith("permissive_"): +- l.append(name.split("permissive_")[1]) +- return l +- - def list(self, heading = 1, locallist = 0): - all = map(lambda y: y["name"], filter(lambda x: x["permissive"], sepolicy.info(sepolicy.TYPE))) - if len(all) == 0: - return -+ def list(self, heading = True, locallist = False): -+ ALL = [y["name"] for y in [x for x in sepolicy.info(sepolicy.TYPE) if x["permissive"]]] -+ if len(ALL) == 0: -+ return -+ -+ customized = self.get_all() -+ if heading: -+ print("\n%-25s\n" % (_("Customized Permissive Types"))) -+ for t in customized: -+ print(t) - +- - if heading: - print "\n%-25s\n" % (_("Builtin Permissive Types")) - customized = self.get_all() - for t in all: - if t not in customized: - print t -+ if locallist: -+ return - +- - if len(customized) == 0: - return -+ if heading: -+ print("\n%-25s\n" % (_("Builtin Permissive Types"))) - +- - if heading: - print "\n%-25s\n" % (_("Customized Permissive Types")) - for t in customized: - print t -+ for t in ALL: -+ if t not in customized: -+ print(t) - +- - def add(self, type): -+ def add(self, type): - import glob +- import glob - try: - import sepolgen.module as module - except ImportError: - raise ValueError(_("The sepolgen python module is required to setup permissive domains.\nIn some distributions it is included in the policycoreutils-devel patckage.\n# yum install policycoreutils-devel\nOr similar for your distro.")) - -+ try: -+ import sepolgen.module as module -+ except ImportError: -+ raise ValueError(_("The sepolgen python module is required to setup permissive domains.\nIn some distributions it is included in the policycoreutils-devel patckage.\n# yum install policycoreutils-devel\nOr similar for your distro.")) -+ - name = "permissive_%s" % type - dirname = "/var/lib/selinux" - os.chdir(dirname) -@@ -444,54 +455,55 @@ permissive %s; - for i in glob.glob("permissive_%s.*" % type): - os.remove(i) - if rc < 0: +- name = "permissive_%s" % type +- dirname = "/var/lib/selinux" +- os.chdir(dirname) +- filename = "%s.te" % name +- modtxt = """ +-module %s 1.0; +- +-require { +- type %s; +-} +- +-permissive %s; +-""" % (name, type, type) +- fd = open(filename, 'w') +- fd.write(modtxt) +- fd.close() +- mc = module.ModuleCompiler() +- mc.create_module_package(filename, 1) +- fd = open("permissive_%s.pp" % type) +- data = fd.read() +- fd.close() +- +- rc = semanage_module_install(self.sh, data, len(data)); +- if rc >= 0: +- self.commit() +- +- for root, dirs, files in os.walk("tmp", topdown = False): +- for name in files: +- os.remove(os.path.join(root, name)) +- for name in dirs: +- os.rmdir(os.path.join(root, name)) +- os.removedirs("tmp") +- for i in glob.glob("permissive_%s.*" % type): +- os.remove(i) +- if rc < 0: - raise ValueError(_("Could not set permissive domain %s (module installation failed)") % name) -+ raise ValueError(_("Could not set permissive domain %s (module installation failed)") % name) - +- - def delete(self, name): -+ def delete(self, name): - for n in name.split(): - rc = semanage_module_remove(self.sh, "permissive_%s" % n) - if rc < 0: - raise ValueError(_("Could not remove permissive domain %s (remove failed)") % name) +- for n in name.split(): +- rc = semanage_module_remove(self.sh, "permissive_%s" % n) +- if rc < 0: +- raise ValueError(_("Could not remove permissive domain %s (remove failed)") % name) - -+ - self.commit() +- self.commit() - - def deleteall(self): -+ -+ def deleteall(self): - l = self.get_all() - if len(l) > 0: +- l = self.get_all() +- if len(l) > 0: - all = " ".join(l) - self.delete(all) -+ self.delete(" ".join(l)) - - class loginRecords(semanageRecords): +- +-class loginRecords(semanageRecords): - def __init__(self, store = ""): - semanageRecords.__init__(self, store) - self.oldsename = None @@ -254317,46 +254181,38 @@ index b3018f3..06c36c5 100644 - 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) -+ 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): -+ 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) -+ -+ (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 exists: -+ semanage_seuser_key_free(k) -+ return self.__modify(name, sename, serange) -+ - if name[0] == '%': - try: - grp.getgrnam(name[1:]) -@@ -524,205 +536,205 @@ class loginRecords(semanageRecords): - if rc < 0: - raise ValueError(_("Could not add login mapping for %s") % name) - +- if name[0] == '%': +- try: +- grp.getgrnam(name[1:]) +- except: +- raise ValueError(_("Linux Group %s does not exist") % name[1:]) +- else: +- try: +- pwd.getpwnam(name) +- except: +- raise ValueError(_("Linux User %s does not exist") % name) +- +- (rc, u) = semanage_seuser_create(self.sh) +- if rc < 0: +- raise ValueError(_("Could not create login mapping for %s") % name) +- +- rc = semanage_seuser_set_name(self.sh, u, name) +- if rc < 0: +- raise ValueError(_("Could not set name for %s") % name) +- +- if serange != "": +- rc = semanage_seuser_set_mlsrange(self.sh, u, serange) +- if rc < 0: +- raise ValueError(_("Could not set MLS range for %s") % name) +- +- rc = semanage_seuser_set_sename(self.sh, u, sename) +- if rc < 0: +- raise ValueError(_("Could not set SELinux user for %s") % name) +- +- rc = semanage_seuser_modify_local(self.sh, k, u) +- if rc < 0: +- raise ValueError(_("Could not add login mapping for %s") % name) +- - 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); @@ -254373,24 +254229,8 @@ index b3018f3..06c36c5 100644 - def __modify(self, name, sename = "", serange = ""): - rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) - if sename == "" and serange == "": -+ 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() -+ except ValueError as error: -+ self.mylog.commit(0) -+ raise error -+ -+ def __modify(self, name, sename = "", serange = ""): -+ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) -+ if sename == "" and serange == "": - raise ValueError(_("Requires seuser or serange")) - +- raise ValueError(_("Requires seuser or serange")) +- - userrec = seluserRecords() - range, (rc, oldserole) = userrec.get(self.oldsename) - @@ -254438,56 +254278,9 @@ index b3018f3..06c36c5 100644 - - def modify(self, name, sename = "", serange = ""): - try: -+ userrec = seluserRecords() -+ RANGE, (rc, oldserole) = userrec.get(self.oldsename) -+ -+ if sename != "": -+ RANGE, (rc, serole) = userrec.get(sename) -+ else: -+ serole=oldserole -+ -+ if serange != "": -+ self.serange=serange -+ else: -+ self.serange=RANGE -+ -+ (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) -+ -+ (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)) -+ -+ 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) -+ -+ 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() +- self.begin() +- self.__modify(name, sename, serange) +- self.commit() - except ValueError, error: - self.mylog.commit(0) - raise error @@ -254565,111 +254358,27 @@ index b3018f3..06c36c5 100644 - - def get_all(self, locallist = 0): - ddict = {} -+ except ValueError as error: -+ self.mylog.commit(0) -+ raise error -+ -+ def __delete(self, name): -+ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) -+ userrec = seluserRecords() -+ RANGE, (rc, oldserole) = userrec.get(self.oldsename) -+ -+ (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) -+ -+ (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) -+ -+ rec, self.sename, self.serange = selinux.getseuserbyname("__default__") -+ RANGE, (rc, serole) = userrec.get(self.sename) -+ -+ 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() -+ -+ except ValueError as error: -+ self.mylog.commit(0) -+ raise error -+ -+ def deleteall(self): -+ (rc, ulist) = semanage_seuser_list_local(self.sh) -+ if rc < 0: -+ raise ValueError(_("Could not list login mappings")) -+ -+ try: -+ self.begin() -+ for u in ulist: -+ self.__delete(semanage_seuser_get_name(u)) -+ self.commit() -+ except ValueError as error: -+ self.mylog.commit(0) -+ raise error -+ -+ def get_all_logins(self): -+ ddict = {} -+ self.logins_path = selinux.selinux_policy_root() + "/logins" -+ for path,dirs,files in os.walk(self.logins_path): -+ if path == self.logins_path: -+ for name in files: -+ try: -+ fd = open(path + "/" + name) -+ rec = fd.read().rstrip().split(":") -+ fd.close() -+ ddict[name] = (rec[1], rec[2], rec[0]) -+ except IndexError: -+ pass -+ return ddict -+ -+ def get_all(self, locallist = False): -+ ddict = {} - if locallist: - (rc, self.ulist) = semanage_seuser_list_local(self.sh) - else: - (rc, self.ulist) = semanage_seuser_list(self.sh) +- if locallist: +- (rc, self.ulist) = semanage_seuser_list_local(self.sh) +- else: +- (rc, self.ulist) = semanage_seuser_list(self.sh) - if rc < 0: - raise ValueError(_("Could not list login mappings")) -+ if rc < 0: -+ raise ValueError(_("Could not list login mappings")) - +- - for u in self.ulist: - name = semanage_seuser_get_name(u) - ddict[name] = (semanage_seuser_get_sename(u), semanage_seuser_get_mlsrange(u), "*") - return ddict -+ for u in self.ulist: -+ name = semanage_seuser_get_name(u) -+ ddict[name] = (semanage_seuser_get_sename(u), semanage_seuser_get_mlsrange(u), "*") -+ return ddict - - def customized(self): - l = [] - ddict = self.get_all(True) +- +- def customized(self): +- l = [] +- ddict = self.get_all(True) - keys = ddict.keys() -+ keys = list(ddict.keys()) - keys.sort() - for k in keys: - l.append("-a -s %s -r '%s' %s" % (ddict[k][0], ddict[k][1], k)) - return l - +- keys.sort() +- for k in keys: +- l.append("-a -s %s -r '%s' %s" % (ddict[k][0], ddict[k][1], k)) +- return l +- - def list(self,heading = 1, locallist = 0): - ddict = self.get_all(locallist) - ldict = self.get_all_logins() @@ -254697,49 +254406,23 @@ index b3018f3..06c36c5 100644 - print "\n%-25s %-25s\n" % (_("Login Name"), _("SELinux User")) - for k in keys: - print "%-25s %-25s" % (k, ddict[k][0]) -+ def list(self,heading = True, locallist = False): -+ ddict = self.get_all(locallist) -+ ldict = self.get_all_logins() -+ lkeys = list(ldict.keys()) -+ keys = list(ddict.keys()) -+ if len(keys) == 0 and len(lkeys) == 0: -+ return -+ keys.sort() -+ lkeys.sort() -+ -+ if is_mls_enabled == 1: -+ if heading: -+ print("\n%-20s %-20s %-20s %s\n" % (_("Login Name"), _("SELinux User"), _("MLS/MCS Range"), _("Service"))) -+ for k in keys: -+ u = ddict[k] -+ print("%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])) -+ if len(lkeys): -+ print("\nLocal customization in %s" % self.logins_path) -+ -+ for k in lkeys: -+ u = ldict[k] -+ print("%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])) -+ else: -+ if heading: -+ print("\n%-25s %-25s\n" % (_("Login Name"), _("SELinux User"))) -+ for k in keys: -+ print("%-25s %-25s" % (k, ddict[k][0])) - - class seluserRecords(semanageRecords): +- +-class seluserRecords(semanageRecords): - def __init__(self, store = ""): - semanageRecords.__init__(self, store) -+ def __init__(self, store = ""): -+ semanageRecords.__init__(self, store) - +- - def get(self, name): -+ 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) -@@ -734,25 +746,25 @@ class seluserRecords(semanageRecords): - raise ValueError(_("Could not query user for %s") % name) - serange = semanage_user_get_mlsrange(u) - serole = semanage_user_get_roles(self.sh,u) +- (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 @@ -254756,61 +254439,53 @@ index b3018f3..06c36c5 100644 - else: - selevel = untranslate(selevel) - -+ 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 == "": -+ serange = "s0" -+ else: -+ serange = untranslate(serange) -+ -+ if selevel == "": -+ selevel = "s0" -+ else: -+ selevel = untranslate(selevel) -+ - if len(roles) < 1: - raise ValueError(_("You must add at least one role for %s") % name) +- if len(roles) < 1: +- raise ValueError(_("You must add at least one role for %s") % name) - -+ - (rc, k) = semanage_user_key_create(self.sh, name) - if rc < 0: - raise ValueError(_("Could not create a key for %s") % name) -@@ -761,7 +773,8 @@ class seluserRecords(semanageRecords): - if rc < 0: - raise ValueError(_("Could not check if SELinux user %s is defined") % name) - if exists: +- (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) +- 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: -@@ -774,7 +787,7 @@ class seluserRecords(semanageRecords): - for r in roles: - rc = semanage_user_add_role(self.sh, u, r) - if rc < 0: +- +- (rc, u) = semanage_user_create(self.sh) +- if rc < 0: +- raise ValueError(_("Could not create SELinux user for %s") % name) +- +- rc = semanage_user_set_name(self.sh, u, name) +- if rc < 0: +- raise ValueError(_("Could not set name for %s") % name) +- +- for r in roles: +- rc = semanage_user_add_role(self.sh, u, r) +- if rc < 0: - raise ValueError(_("Could not add role %s for %s") % (r, name)) -+ raise ValueError(_("Could not add role %(ROLE)s for %(NAME)s") % {"ROLE":r, "NAME":name}) - - if is_mls_enabled == 1: - rc = semanage_user_set_mlsrange(self.sh, u, serange) -@@ -786,7 +799,7 @@ class seluserRecords(semanageRecords): - raise ValueError(_("Could not set MLS level for %s") % name) - rc = semanage_user_set_prefix(self.sh, u, prefix) - if rc < 0: +- +- if is_mls_enabled == 1: +- rc = semanage_user_set_mlsrange(self.sh, u, serange) +- if rc < 0: +- raise ValueError(_("Could not set MLS range for %s") % name) +- +- rc = semanage_user_set_mlslevel(self.sh, u, selevel) +- if rc < 0: +- raise ValueError(_("Could not set MLS level for %s") % name) +- rc = semanage_user_set_prefix(self.sh, u, prefix) +- if rc < 0: - raise ValueError(_("Could not add prefix %s for %s") % (r, prefix)) -+ raise ValueError(_("Could not add prefix %(ROLE)s for %(PREFIX)s") % {"ROLE":r, "PREFIX": prefix}) - (rc, key) = semanage_user_key_extract(self.sh,u) - if rc < 0: - raise ValueError(_("Could not extract key for %s") % name) -@@ -797,22 +810,21 @@ class seluserRecords(semanageRecords): - - semanage_user_key_free(k) - semanage_user_free(u) +- (rc, key) = semanage_user_key_extract(self.sh,u) +- if rc < 0: +- raise ValueError(_("Could not extract key for %s") % name) +- +- rc = semanage_user_modify_local(self.sh, k, u) +- if rc < 0: +- raise ValueError(_("Could not add SELinux user %s") % name) +- +- 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): @@ -254822,111 +254497,112 @@ index b3018f3..06c36c5 100644 - except ValueError, error: - self.mylog.commit(0) - raise error -+ self.mylog.log("seuser", sename=name, serole=",".join(roles), serange=serange) -+ -+ def add(self, name, roles, selevel, serange, prefix): -+ try: -+ self.begin() -+ self.__add( name, roles, selevel, serange, prefix) -+ self.commit() -+ except ValueError as error: -+ self.mylog.commit(0) -+ raise error - - def __modify(self, name, roles = [], selevel = "", serange = "", prefix = ""): +- +- def __modify(self, name, roles = [], selevel = "", serange = "", prefix = ""): - oldserole = "" - oldserange = "" - newroles = string.join(roles, ' '); -+ oldserole = "" -+ oldserange = "" -+ newroles = string.join(roles, ' '); - if prefix == "" and len(roles) == 0 and serange == "" and selevel == "": - if is_mls_enabled == 1: - raise ValueError(_("Requires prefix, roles, level or range")) -@@ -858,31 +870,31 @@ class seluserRecords(semanageRecords): - if rc < 0: - raise ValueError(_("Could not modify SELinux user %s") % name) - +- if prefix == "" and len(roles) == 0 and serange == "" and selevel == "": +- if is_mls_enabled == 1: +- raise ValueError(_("Requires prefix, roles, level or range")) +- else: +- raise ValueError(_("Requires prefix or roles")) +- +- (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) +- if not exists: +- raise ValueError(_("SELinux user %s is not defined") % 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) +- if rc >= 0: +- oldserole = string.join(rlist, ' '); +- +- if serange != "": +- semanage_user_set_mlsrange(self.sh, u, untranslate(serange)) +- if selevel != "": +- semanage_user_set_mlslevel(self.sh, u, untranslate(selevel)) +- +- if prefix != "": +- semanage_user_set_prefix(self.sh, u, prefix) +- +- if len(roles) != 0: +- for r in rlist: +- if r not in roles: +- semanage_user_del_role(u, r) +- for r in roles: +- if r not in rlist: +- semanage_user_add_role(self.sh, u, r) +- +- rc = semanage_user_modify_local(self.sh, k, u) +- if rc < 0: +- raise ValueError(_("Could not modify SELinux user %s") % name) +- - semanage_user_key_free(k) - semanage_user_free(u) - - role=",".join(newroles.split()) - oldserole=",".join(oldserole.split()) - self.mylog.log("seuser", sename=name, oldsename=name, serole=role, serange=serange, oldserole=oldserole, oldserange=oldserange) -+ semanage_user_key_free(k) -+ semanage_user_free(u) -+ -+ 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 = ""): - try: -+ def modify(self, name, roles = [], selevel = "", serange = "", prefix = ""): -+ try: - self.begin() - self.__modify(name, roles, selevel, serange, prefix) - self.commit() +- self.begin() +- self.__modify(name, roles, selevel, serange, prefix) +- self.commit() - except ValueError, error: - self.mylog.commit(0) - raise error -+ except ValueError as error: -+ self.mylog.commit(0) -+ raise error - +- - def __delete(self, name): -+ def __delete(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, 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: +- (rc, exists) = semanage_user_exists(self.sh, k) +- if rc < 0: - raise ValueError(_("Could not check if SELinux user %s is defined") % name) -+ raise ValueError(_("Could not check if SELinux user %s is defined") % name) - if not exists: - raise ValueError(_("SELinux user %s is not defined") % name) - -@@ -891,244 +903,246 @@ class seluserRecords(semanageRecords): - raise ValueError(_("Could not check if SELinux user %s is defined") % name) - if not exists: - raise ValueError(_("SELinux user %s is defined in policy, cannot be deleted") % name) +- if not exists: +- raise ValueError(_("SELinux user %s is not defined") % name) +- +- (rc, exists) = semanage_user_exists_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if SELinux user %s is defined") % name) +- 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: -+ -+ (rc, u) = semanage_user_query(self.sh, k) -+ if rc < 0: - raise ValueError(_("Could not query user for %s") % name) +- 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) -+ 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) - +- +- 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) -+ semanage_user_key_free(k) -+ semanage_user_free(u) - +- - self.mylog.log_remove("seuser", oldsename=name, oldserange=oldserange, oldserole=oldserole) -+ self.mylog.log_remove("seuser", oldsename=name, oldserange=oldserange, oldserole=oldserole) - +- - def delete(self, name): - try: -+ def delete(self, name): -+ try: - self.begin() - self.__delete(name) - self.commit() - +- self.begin() +- self.__delete(name) +- self.commit() +- - except ValueError, error: - self.mylog.commit(0) - raise error @@ -254947,64 +254623,33 @@ index b3018f3..06c36c5 100644 - - def get_all(self, locallist = 0): - ddict = {} -+ except ValueError as error: -+ self.mylog.commit(0) -+ raise error -+ -+ def deleteall(self): -+ (rc, ulist) = semanage_user_list_local(self.sh) -+ if rc < 0: -+ raise ValueError(_("Could not list login mappings")) -+ -+ try: -+ self.begin() -+ for u in ulist: -+ self.__delete(semanage_user_get_name(u)) -+ self.commit() -+ except ValueError as error: -+ self.mylog.commit(0) -+ raise error -+ -+ def get_all(self, locallist = False): -+ ddict = {} - if locallist: - (rc, self.ulist) = semanage_user_list_local(self.sh) - else: - (rc, self.ulist) = semanage_user_list(self.sh) +- if locallist: +- (rc, self.ulist) = semanage_user_list_local(self.sh) +- else: +- (rc, self.ulist) = semanage_user_list(self.sh) - if rc < 0: - raise ValueError(_("Could not list SELinux users")) -+ if rc < 0: -+ raise ValueError(_("Could not list SELinux users")) - +- - for u in self.ulist: - name = semanage_user_get_name(u) - (rc, rlist) = semanage_user_get_roles(self.sh, u) - if rc < 0: - raise ValueError(_("Could not list roles for user %s") % name) -+ for u in self.ulist: -+ name = semanage_user_get_name(u) -+ (rc, rlist) = semanage_user_get_roles(self.sh, u) -+ if rc < 0: -+ raise ValueError(_("Could not list roles for user %s") % name) - +- - roles = string.join(rlist, ' '); - ddict[semanage_user_get_name(u)] = (semanage_user_get_prefix(u), semanage_user_get_mlslevel(u), semanage_user_get_mlsrange(u), roles) -+ roles = string.join(rlist, ' '); -+ ddict[semanage_user_get_name(u)] = (semanage_user_get_prefix(u), semanage_user_get_mlslevel(u), semanage_user_get_mlsrange(u), roles) - +- - return ddict -+ return ddict - - def customized(self): - l = [] - ddict = self.get_all(True) +- +- def customized(self): +- l = [] +- ddict = self.get_all(True) - keys = ddict.keys() -+ keys = list(ddict.keys()) - keys.sort() - for k in keys: - l.append("-a -L %s -r %s -R '%s' %s" % (ddict[k][1], ddict[k][2], ddict[k][3], k)) - return l - +- keys.sort() +- for k in keys: +- l.append("-a -L %s -r %s -R '%s' %s" % (ddict[k][1], ddict[k][2], ddict[k][3], k)) +- return l +- - def list(self, heading = 1, locallist = 0): - ddict = self.get_all(locallist) - keys = ddict.keys() @@ -255023,26 +254668,8 @@ index b3018f3..06c36c5 100644 - print "%-15s %s\n" % (_("SELinux User"), _("SELinux Roles")) - for k in keys: - print "%-15s %s" % (k, ddict[k][3]) -+ def list(self, heading = True, locallist = False): -+ ddict = self.get_all(locallist) -+ keys = list(ddict.keys()) -+ if len(keys) == 0: -+ return -+ keys.sort() -+ -+ if is_mls_enabled == 1: -+ if heading: -+ print("\n%-15s %-10s %-10s %-30s" % ("", _("Labeling"), _("MLS/"), _("MLS/"))) -+ print("%-15s %-10s %-10s %-30s %s\n" % (_("SELinux User"), _("Prefix"), _("MCS Level"), _("MCS Range"), _("SELinux Roles"))) -+ for k in keys: -+ print("%-15s %-10s %-10s %-30s %s" % (k, ddict[k][0], translate(ddict[k][1]), translate(ddict[k][2]), ddict[k][3])) -+ else: -+ if heading: -+ print("%-15s %s\n" % (_("SELinux User"), _("SELinux Roles"))) -+ for k in keys: -+ print("%-15s %s" % (k, ddict[k][3])) - - class portRecords(semanageRecords): +- +-class portRecords(semanageRecords): - try: - valid_types = sepolicy.info(sepolicy.ATTRIBUTE,"port_type")[0]["types"] - except RuntimeError: @@ -255138,107 +254765,10 @@ index b3018f3..06c36c5 100644 - semanage_port_free(p) - - def add(self, port, proto, serange, type): -+ try: -+ valid_types = sepolicy.info(sepolicy.ATTRIBUTE,"port_type")[0]["types"] -+ except RuntimeError: -+ valid_types = [] -+ -+ def __init__(self, store = ""): -+ semanageRecords.__init__(self, store) -+ -+ def __genkey(self, port, proto): -+ if proto == "tcp": -+ proto_d = SEMANAGE_PROTO_TCP -+ else: -+ if proto == "udp": -+ proto_d = SEMANAGE_PROTO_UDP -+ else: -+ raise ValueError(_("Protocol udp or tcp is required")) -+ if port == "": -+ raise ValueError(_("Port is required")) -+ -+ ports = port.split("-") -+ if len(ports) == 1: -+ high = low = int(ports[0]) -+ else: -+ low = int(ports[0]) -+ high = int(ports[1]) -+ -+ if high > 65535: -+ raise ValueError(_("Invalid Port")) -+ -+ (rc, k) = semanage_port_key_create(self.sh, low, high, proto_d) -+ if rc < 0: -+ raise ValueError(_("Could not create a key for %(PROTOTYPE)s/%(PORT)s") % {"PROTOTYPE": proto, "PORT":port}) -+ return ( k, proto_d, low, high ) -+ -+ def __add(self, port, proto, serange, type): -+ if is_mls_enabled == 1: -+ if serange == "": -+ serange = "s0" -+ else: -+ serange = untranslate(serange) -+ -+ if type == "": -+ raise ValueError(_("Type is required")) -+ -+ if type not in self.valid_types: -+ raise ValueError(_("Type %s is invalid, must be a port type") % type) -+ -+ ( k, proto_d, low, high ) = self.__genkey(port, proto) -+ if semanageRecords.transaction: -+ (rc, exists) = semanage_port_exists_local(self.sh, k) -+ else: -+ (rc, exists) = semanage_port_exists(self.sh, k) -+ if rc < 0: -+ raise ValueError(_("Could not check if port %(PROTOCOL)s/%(PORT)s is defined") % {"PROTOCOL": proto, "PORT": port}) -+ if exists: -+ raise ValueError(_("Port %(PROTOCOL)s/%(PORT)s already defined") % {"PROTOCOL": proto, "PORT": port}) -+ -+ (rc, p) = semanage_port_create(self.sh) -+ if rc < 0: -+ raise ValueError(_("Could not create port for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) -+ -+ semanage_port_set_proto(p, proto_d) -+ semanage_port_set_range(p, low, high) -+ (rc, con) = semanage_context_create(self.sh) -+ if rc < 0: -+ raise ValueError(_("Could not create context for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) -+ -+ rc = semanage_context_set_user(self.sh, con, "system_u") -+ if rc < 0: -+ raise ValueError(_("Could not set user in port context for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) -+ -+ rc = semanage_context_set_role(self.sh, con, "object_r") -+ if rc < 0: -+ raise ValueError(_("Could not set role in port context for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) -+ -+ rc = semanage_context_set_type(self.sh, con, type) -+ if rc < 0: -+ raise ValueError(_("Could not set type in port context for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) -+ -+ if serange != "": -+ rc = semanage_context_set_mls(self.sh, con, serange) -+ if rc < 0: -+ raise ValueError(_("Could not set mls fields in port context for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) -+ -+ rc = semanage_port_set_con(self.sh, p, con) -+ if rc < 0: -+ raise ValueError(_("Could not set port context for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) -+ -+ rc = semanage_port_modify_local(self.sh, k, p) -+ if rc < 0: -+ raise ValueError(_("Could not add port %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) -+ -+ semanage_context_free(con) -+ semanage_port_key_free(k) -+ semanage_port_free(p) -+ -+ def add(self, port, proto, serange, type): - self.begin() - self.__add(port, proto, serange, type) - self.commit() - +- self.begin() +- self.__add(port, proto, serange, type) +- self.commit() +- - def __modify(self, port, proto, serange, setype): - if serange == "" and setype == "": - if is_mls_enabled == 1: @@ -255276,71 +254806,34 @@ index b3018f3..06c36c5 100644 - semanage_port_free(p) - - def modify(self, port, proto, serange, setype): -+ def __modify(self, port, proto, serange, setype): -+ if serange == "" and setype == "": -+ if is_mls_enabled == 1: -+ raise ValueError(_("Requires setype or serange")) -+ else: -+ raise ValueError(_("Requires setype")) -+ -+ if setype and setype not in self.valid_types: -+ raise ValueError(_("Type %s is invalid, must be a port type") % setype) -+ -+ ( k, proto_d, low, high ) = self.__genkey(port, proto) -+ -+ (rc, exists) = semanage_port_exists(self.sh, k) -+ if rc < 0: -+ raise ValueError(_("Could not check if port @%(PROTOCOL)s/%(PORT)s is defined") % {"PROTOCOL": proto, "PORT": port}) -+ if not exists: -+ raise ValueError(_("Port @%(PROTOCOL)s/%(PORT)s is not defined") % {"PROTOCOL": proto, "PORT": port}) -+ -+ (rc, p) = semanage_port_query(self.sh, k) -+ if rc < 0: -+ raise ValueError(_("Could not query port %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) -+ -+ con = semanage_port_get_con(p) -+ -+ if serange != "": -+ semanage_context_set_mls(self.sh, con, untranslate(serange)) -+ if setype != "": -+ semanage_context_set_type(self.sh, con, setype) -+ -+ rc = semanage_port_modify_local(self.sh, k, p) -+ if rc < 0: -+ raise ValueError(_("Could not modify port %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) -+ -+ semanage_port_key_free(k) -+ semanage_port_free(p) -+ -+ def modify(self, port, proto, serange, setype): - self.begin() - self.__modify(port, proto, serange, setype) - self.commit() - +- self.begin() +- self.__modify(port, proto, serange, setype) +- self.commit() +- - def deleteall(self): - (rc, plist) = semanage_port_list_local(self.sh) - if rc < 0: - raise ValueError(_("Could not list the ports")) -+ def deleteall(self): -+ (rc, plist) = semanage_port_list_local(self.sh) -+ if rc < 0: -+ raise ValueError(_("Could not list the ports")) - - self.begin() - +- +- self.begin() +- - for port in plist: -+ for port in plist: - proto = semanage_port_get_proto(port) - proto_str = semanage_port_get_proto_str(proto) - low = semanage_port_get_low(port) -@@ -1142,87 +1156,87 @@ class portRecords(semanageRecords): - if rc < 0: - raise ValueError(_("Could not delete the port %s") % port_str) - semanage_port_key_free(k) +- proto = semanage_port_get_proto(port) +- proto_str = semanage_port_get_proto_str(proto) +- low = semanage_port_get_low(port) +- high = semanage_port_get_high(port) +- port_str = "%s-%s" % (low, high) +- ( k, proto_d, low, high ) = self.__genkey(port_str , proto_str) +- if rc < 0: +- raise ValueError(_("Could not create a key for %s") % port_str) +- +- rc = semanage_port_del_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not delete the port %s") % port_str) +- semanage_port_key_free(k) - -+ - self.commit() - +- self.commit() +- - def __delete(self, port, proto): - ( k, proto_d, low, high ) = self.__genkey(port, proto) - (rc, exists) = semanage_port_exists(self.sh, k) @@ -255362,39 +254855,16 @@ index b3018f3..06c36c5 100644 - semanage_port_key_free(k) - - def delete(self, port, proto): -+ def __delete(self, port, proto): -+ ( k, proto_d, low, high ) = self.__genkey(port, proto) -+ (rc, exists) = semanage_port_exists(self.sh, k) -+ if rc < 0: -+ raise ValueError(_("Could not check if port %(PROTOCOL)s/%(PORT)s is defined") % {"PROTOCOL": proto, "PORT": port}) -+ if not exists: -+ raise ValueError(_("Port %(PROTOCOL)s/%(PORT)s is not defined") % {"PROTOCOL": proto, "PORT": port}) -+ -+ (rc, exists) = semanage_port_exists_local(self.sh, k) -+ if rc < 0: -+ raise ValueError(_("Could not check if port %(PROTOCOL)s/%(PORT)s is defined") % {"PROTOCOL": proto, "PORT": port}) -+ if not exists: -+ raise ValueError(_("Port %(PROTOCOL)s/%(PORT)s is defined in policy, cannot be deleted") % {"PROTOCOL": proto, "PORT": port}) -+ -+ rc = semanage_port_del_local(self.sh, k) -+ if rc < 0: -+ raise ValueError(_("Could not delete port %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) -+ -+ semanage_port_key_free(k) -+ -+ def delete(self, port, proto): - self.begin() - self.__delete(port, proto) - self.commit() - +- self.begin() +- self.__delete(port, proto) +- self.commit() +- - def get_all(self, locallist = 0): - ddict = {} -+ def get_all(self, locallist = False): -+ ddict = {} - if locallist: - (rc, self.plist) = semanage_port_list_local(self.sh) - else: - (rc, self.plist) = semanage_port_list(self.sh) +- if locallist: +- (rc, self.plist) = semanage_port_list_local(self.sh) +- else: +- (rc, self.plist) = semanage_port_list(self.sh) - if rc < 0: - raise ValueError(_("Could not list ports")) - @@ -255413,28 +254883,10 @@ index b3018f3..06c36c5 100644 - - def get_all_by_type(self, locallist = 0): - ddict = {} -+ if rc < 0: -+ raise ValueError(_("Could not list ports")) -+ -+ for port in self.plist: -+ con = semanage_port_get_con(port) -+ ctype = semanage_context_get_type(con) -+ if ctype == "reserved_port_t": -+ continue -+ level = semanage_context_get_mls(con) -+ proto = semanage_port_get_proto(port) -+ proto_str = semanage_port_get_proto_str(proto) -+ low = semanage_port_get_low(port) -+ high = semanage_port_get_high(port) -+ ddict[(low, high, proto_str)] = (ctype, level) -+ return ddict -+ -+ def get_all_by_type(self, locallist = False): -+ ddict = {} - if locallist: - (rc, self.plist) = semanage_port_list_local(self.sh) - else: - (rc, self.plist) = semanage_port_list(self.sh) +- if locallist: +- (rc, self.plist) = semanage_port_list_local(self.sh) +- else: +- (rc, self.plist) = semanage_port_list(self.sh) - if rc < 0: - raise ValueError(_("Could not list ports")) - @@ -255454,41 +254906,19 @@ index b3018f3..06c36c5 100644 - else: - ddict[(ctype,proto_str)].append("%d-%d" % (low, high)) - return ddict -+ if rc < 0: -+ raise ValueError(_("Could not list ports")) -+ -+ for port in self.plist: -+ con = semanage_port_get_con(port) -+ ctype = semanage_context_get_type(con) -+ if ctype == "reserved_port_t": -+ continue -+ proto = semanage_port_get_proto(port) -+ proto_str = semanage_port_get_proto_str(proto) -+ low = semanage_port_get_low(port) -+ high = semanage_port_get_high(port) -+ if (ctype, proto_str) not in list(ddict.keys()): -+ ddict[(ctype,proto_str)] = [] -+ if low == high: -+ ddict[(ctype,proto_str)].append("%d" % low) -+ else: -+ ddict[(ctype,proto_str)].append("%d-%d" % (low, high)) -+ return ddict - - def customized(self): - l = [] +- +- def customized(self): +- l = [] - ddict = self.get_all(True) - keys = ddict.keys() - keys.sort() -+ ddict = self.get_all(True) -+ keys = list(ddict.keys()) -+ keys.sort() - for k in keys: - if k[0] == k[1]: - l.append("-a -t %s -p %s %s" % (ddict[k][0], k[2], k[0])) -@@ -1230,27 +1244,27 @@ class portRecords(semanageRecords): - l.append("-a -t %s -p %s %s-%s" % (ddict[k][0], k[2], k[0], k[1])) - return l - +- for k in keys: +- if k[0] == k[1]: +- l.append("-a -t %s -p %s %s" % (ddict[k][0], k[2], k[0])) +- else: +- l.append("-a -t %s -p %s %s-%s" % (ddict[k][0], k[2], k[0], k[1])) +- return l +- - def list(self, heading = 1, locallist = 0): - ddict = self.get_all_by_type(locallist) - keys = ddict.keys() @@ -255504,134 +254934,245 @@ index b3018f3..06c36c5 100644 - for p in ddict[i][1:]: - rec += ", %s" % p - print rec -+ def list(self, heading = True, locallist = False): -+ ddict = self.get_all_by_type(locallist) -+ keys = list(ddict.keys()) -+ if len(keys) == 0: -+ return -+ keys.sort() -+ -+ if heading: -+ print("%-30s %-8s %s\n" % (_("SELinux Port Type"), _("Proto"), _("Port Number"))) -+ for i in keys: -+ rec = "%-30s %-8s " % i -+ rec += "%s" % ddict[i][0] -+ for p in ddict[i][1:]: -+ rec += ", %s" % p -+ print(rec) - - class nodeRecords(semanageRecords): - try: +- +-class nodeRecords(semanageRecords): +- try: - valid_types = sepolicy.info(sepolicy.ATTRIBUTE,"node_type")[0]["types"] -+ valid_types = sepolicy.info(sepolicy.ATTRIBUTE,"node_type")[0]["types"] - except RuntimeError: +- except RuntimeError: - valid_types = [] -+ valid_types = [] - - def __init__(self, store = ""): - semanageRecords.__init__(self,store) -@@ -1293,8 +1307,8 @@ class nodeRecords(semanageRecords): - if ctype == "": - raise ValueError(_("SELinux node type is required")) - +- +- def __init__(self, store = ""): +- semanageRecords.__init__(self,store) +- self.protocol = ["ipv4", "ipv6"] +- +- def validate(self, addr, mask, protocol): +- newaddr=addr +- newmask=mask +- newprotocol="" +- +- if addr == "": +- raise ValueError(_("Node Address is required")) +- +- # verify valid comination +- if len(mask) == 0 or mask[0] == "/": +- i = IP(addr + mask) +- newaddr = i.strNormal(0) +- newmask = str(i.netmask()) +- if newmask == "0.0.0.0" and i.version() == 6: +- newmask = "::" +- +- protocol = "ipv%d" % i.version() +- +- try: +- newprotocol = self.protocol.index(protocol) +- except: +- raise ValueError(_("Unknown or missing protocol")) +- +- return newaddr, newmask, newprotocol +- +- def __add(self, addr, mask, proto, serange, ctype): +- addr, mask, proto = self.validate(addr, mask, proto) +- +- if is_mls_enabled == 1: +- if serange == "": +- serange = "s0" +- else: +- serange = untranslate(serange) +- +- if ctype == "": +- raise ValueError(_("SELinux node type is required")) +- - if ctype not in self.valid_types: - raise ValueError(_("Type %s is invalid, must be a node type") % ctype) -+ if ctype not in self.valid_types: -+ raise ValueError(_("Type %s is invalid, must be a node type") % ctype) - - (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) - if rc < 0: -@@ -1304,7 +1318,8 @@ class nodeRecords(semanageRecords): - - (rc, exists) = semanage_node_exists(self.sh, k) - if exists: +- +- (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) +- if rc < 0: +- raise ValueError(_("Could not create key for %s") % addr) +- if rc < 0: +- raise ValueError(_("Could not check if addr %s is defined") % addr) +- +- (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: -@@ -1360,8 +1375,8 @@ class nodeRecords(semanageRecords): - if serange == "" and setype == "": - raise ValueError(_("Requires setype or serange")) - +- +- (rc, node) = semanage_node_create(self.sh) +- if rc < 0: +- raise ValueError(_("Could not create addr for %s") % addr) +- semanage_node_set_proto(node, proto) +- +- rc = semanage_node_set_addr(self.sh, node, proto, addr) +- (rc, con) = semanage_context_create(self.sh) +- if rc < 0: +- raise ValueError(_("Could not create context for %s") % addr) +- +- rc = semanage_node_set_mask(self.sh, node, proto, mask) +- if rc < 0: +- raise ValueError(_("Could not set mask for %s") % addr) +- +- rc = semanage_context_set_user(self.sh, con, "system_u") +- if rc < 0: +- raise ValueError(_("Could not set user in addr context for %s") % addr) +- +- rc = semanage_context_set_role(self.sh, con, "object_r") +- if rc < 0: +- raise ValueError(_("Could not set role in addr context for %s") % addr) +- +- rc = semanage_context_set_type(self.sh, con, ctype) +- if rc < 0: +- raise ValueError(_("Could not set type in addr context for %s") % addr) +- +- if serange != "": +- rc = semanage_context_set_mls(self.sh, con, serange) +- if rc < 0: +- raise ValueError(_("Could not set mls fields in addr context for %s") % addr) +- +- rc = semanage_node_set_con(self.sh, node, con) +- if rc < 0: +- raise ValueError(_("Could not set addr context for %s") % addr) +- +- rc = semanage_node_modify_local(self.sh, k, node) +- if rc < 0: +- raise ValueError(_("Could not add addr %s") % addr) +- +- semanage_context_free(con) +- semanage_node_key_free(k) +- semanage_node_free(node) +- +- def add(self, addr, mask, proto, serange, ctype): +- self.begin() +- self.__add(addr, mask, proto, serange, ctype) +- self.commit() +- +- def __modify(self, addr, mask, proto, serange, setype): +- addr, mask, proto = self.validate(addr, mask, proto) +- +- if serange == "" and setype == "": +- raise ValueError(_("Requires setype or serange")) +- - if setype and setype not in self.valid_types: - raise ValueError(_("Type %s is invalid, must be a node type") % setype) -+ if setype and setype not in self.valid_types: -+ raise ValueError(_("Type %s is invalid, must be a node type") % setype) - - (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) - if rc < 0: -@@ -1425,7 +1440,7 @@ class nodeRecords(semanageRecords): - self.begin() - self.__delete(addr, mask, proto) - self.commit() +- +- (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) +- if rc < 0: +- raise ValueError(_("Could not create key for %s") % addr) +- +- (rc, exists) = semanage_node_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if addr %s is defined") % addr) +- if not exists: +- raise ValueError(_("Addr %s is not defined") % addr) +- +- (rc, node) = semanage_node_query(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not query addr %s") % addr) +- +- con = semanage_node_get_con(node) +- if serange != "": +- semanage_context_set_mls(self.sh, con, untranslate(serange)) +- if setype != "": +- semanage_context_set_type(self.sh, con, setype) +- +- rc = semanage_node_modify_local(self.sh, k, node) +- if rc < 0: +- raise ValueError(_("Could not modify addr %s") % addr) +- +- semanage_node_key_free(k) +- semanage_node_free(node) +- +- def modify(self, addr, mask, proto, serange, setype): +- self.begin() +- self.__modify(addr, mask, proto, serange, setype) +- self.commit() +- +- def __delete(self, addr, mask, proto): +- +- addr, mask, proto = self.validate(addr, mask, proto) +- +- (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) +- if rc < 0: +- raise ValueError(_("Could not create key for %s") % addr) +- +- (rc, exists) = semanage_node_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if addr %s is defined") % addr) +- if not exists: +- raise ValueError(_("Addr %s is not defined") % addr) +- +- (rc, exists) = semanage_node_exists_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if addr %s is defined") % addr) +- if not exists: +- raise ValueError(_("Addr %s is defined in policy, cannot be deleted") % addr) +- +- rc = semanage_node_del_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not delete addr %s") % addr) +- +- semanage_node_key_free(k) +- +- def delete(self, addr, mask, proto): +- self.begin() +- self.__delete(addr, mask, proto) +- self.commit() - -+ - def deleteall(self): - (rc, nlist) = semanage_node_list_local(self.sh) - if rc < 0: -@@ -1436,12 +1451,12 @@ class nodeRecords(semanageRecords): - self.__delete(semanage_node_get_addr(self.sh, node)[1], semanage_node_get_mask(self.sh, node)[1], self.protocol[semanage_node_get_proto(node)]) - self.commit() - +- def deleteall(self): +- (rc, nlist) = semanage_node_list_local(self.sh) +- if rc < 0: +- raise ValueError(_("Could not deleteall node mappings")) +- +- self.begin() +- for node in nlist: +- self.__delete(semanage_node_get_addr(self.sh, node)[1], semanage_node_get_mask(self.sh, node)[1], self.protocol[semanage_node_get_proto(node)]) +- self.commit() +- - def get_all(self, locallist = 0): -+ def get_all(self, locallist = False): - ddict = {} +- ddict = {} - if locallist : - (rc, self.ilist) = semanage_node_list_local(self.sh) - else: - (rc, self.ilist) = semanage_node_list(self.sh) -+ if locallist : -+ (rc, self.ilist) = semanage_node_list_local(self.sh) -+ else: -+ (rc, self.ilist) = semanage_node_list(self.sh) - if rc < 0: - raise ValueError(_("Could not list addrs")) - -@@ -1457,228 +1472,229 @@ class nodeRecords(semanageRecords): - def customized(self): - l = [] - ddict = self.get_all(True) +- if rc < 0: +- raise ValueError(_("Could not list addrs")) +- +- for node in self.ilist: +- con = semanage_node_get_con(node) +- addr = semanage_node_get_addr(self.sh, node) +- mask = semanage_node_get_mask(self.sh, node) +- proto = self.protocol[semanage_node_get_proto(node)] +- ddict[(addr[1], mask[1], proto)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con)) +- +- return ddict +- +- def customized(self): +- l = [] +- ddict = self.get_all(True) - keys = ddict.keys() -+ keys = list(ddict.keys()) - keys.sort() - for k in keys: - l.append("-a -M %s -p %s -t %s %s" % (k[1], k[2],ddict[k][2], k[0])) - return l - +- keys.sort() +- for k in keys: +- l.append("-a -M %s -p %s -t %s %s" % (k[1], k[2],ddict[k][2], k[0])) +- return l +- - def list(self, heading = 1, locallist = 0): -+ def list(self, heading = True, locallist = False): - ddict = self.get_all(locallist) +- ddict = self.get_all(locallist) - keys = ddict.keys() - if len(keys) == 0: - return -+ keys = list(ddict.keys()) -+ if len(keys) == 0: -+ return - keys.sort() - - if heading: +- keys.sort() +- +- if heading: - print "%-18s %-18s %-5s %-5s\n" % ("IP Address", "Netmask", "Protocol", "Context") -+ print("%-18s %-18s %-5s %-5s\n" % ("IP Address", "Netmask", "Protocol", "Context")) - if is_mls_enabled: +- if is_mls_enabled: - for k in keys: - val = '' - for fields in k: - val = val + '\t' + str(fields) - print "%-18s %-18s %-5s %s:%s:%s:%s " % (k[0],k[1],k[2],ddict[k][0], ddict[k][1],ddict[k][2], translate(ddict[k][3], False)) -+ for k in keys: -+ val = '' -+ for fields in k: -+ val = val + '\t' + str(fields) -+ print("%-18s %-18s %-5s %s:%s:%s:%s " % (k[0],k[1],k[2],ddict[k][0], ddict[k][1],ddict[k][2], translate(ddict[k][3], False))) - else: - for k in keys: +- else: +- for k in keys: - print "%-18s %-18s %-5s %s:%s:%s " % (k[0],k[1],k[2],ddict[k][0], ddict[k][1],ddict[k][2]) -+ print("%-18s %-18s %-5s %s:%s:%s " % (k[0],k[1],k[2],ddict[k][0], ddict[k][1],ddict[k][2])) - - - class interfaceRecords(semanageRecords): +- +- +-class interfaceRecords(semanageRecords): - def __init__(self, store = ""): - semanageRecords.__init__(self, store) - @@ -255698,15 +255239,2196 @@ index b3018f3..06c36c5 100644 - semanage_iface_free(iface) - - def add(self, interface, serange, ctype): +- self.begin() +- self.__add(interface, serange, ctype) +- self.commit() +- +- def __modify(self, interface, serange, setype): +- if serange == "" and setype == "": +- raise ValueError(_("Requires setype or serange")) +- +- (rc, k) = semanage_iface_key_create(self.sh, interface) +- if rc < 0: +- raise ValueError(_("Could not create key for %s") % interface) +- +- (rc, exists) = semanage_iface_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if interface %s is defined") % interface) +- if not exists: +- raise ValueError(_("Interface %s is not defined") % interface) +- +- (rc, iface) = semanage_iface_query(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not query interface %s") % interface) +- +- con = semanage_iface_get_ifcon(iface) +- +- if serange != "": +- semanage_context_set_mls(self.sh, con, untranslate(serange)) +- if setype != "": +- semanage_context_set_type(self.sh, con, setype) +- +- rc = semanage_iface_modify_local(self.sh, k, iface) +- if rc < 0: +- raise ValueError(_("Could not modify interface %s") % interface) +- +- semanage_iface_key_free(k) +- semanage_iface_free(iface) +- +- def modify(self, interface, serange, setype): +- self.begin() +- self.__modify(interface, serange, setype) +- self.commit() +- +- def __delete(self, interface): +- (rc, k) = semanage_iface_key_create(self.sh, interface) +- if rc < 0: +- raise ValueError(_("Could not create key for %s") % interface) +- +- (rc, exists) = semanage_iface_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if interface %s is defined") % interface) +- if not exists: +- raise ValueError(_("Interface %s is not defined") % interface) +- +- (rc, exists) = semanage_iface_exists_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if interface %s is defined") % interface) +- if not exists: +- raise ValueError(_("Interface %s is defined in policy, cannot be deleted") % interface) +- +- rc = semanage_iface_del_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not delete interface %s") % interface) +- +- semanage_iface_key_free(k) +- +- def delete(self, interface): +- self.begin() +- self.__delete(interface) +- self.commit() +- +- def deleteall(self): +- (rc, ulist) = semanage_iface_list_local(self.sh) +- if rc < 0: +- raise ValueError(_("Could not delete all interface mappings")) +- +- self.begin() +- for i in ulist: +- self.__delete(semanage_iface_get_name(i)) +- self.commit() +- +- def get_all(self, locallist = 0): +- ddict = {} +- if locallist: +- (rc, self.ilist) = semanage_iface_list_local(self.sh) +- else: +- (rc, self.ilist) = semanage_iface_list(self.sh) +- if rc < 0: +- raise ValueError(_("Could not list interfaces")) +- +- for interface in self.ilist: +- con = semanage_iface_get_ifcon(interface) +- ddict[semanage_iface_get_name(interface)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con)) +- +- return ddict +- +- def customized(self): +- l = [] +- ddict = self.get_all(True) +- keys = ddict.keys() +- keys.sort() +- for k in keys: +- l.append("-a -t %s %s" % (ddict[k][2], k)) +- return l +- +- def list(self, heading = 1, locallist = 0): +- ddict = self.get_all(locallist) +- keys = ddict.keys() +- if len(keys) == 0: +- return +- keys.sort() +- +- if heading: +- print "%-30s %s\n" % (_("SELinux Interface"), _("Context")) +- if is_mls_enabled: +- for k in keys: +- print "%-30s %s:%s:%s:%s " % (k,ddict[k][0], ddict[k][1],ddict[k][2], translate(ddict[k][3], False)) +- else: +- for k in keys: +- print "%-30s %s:%s:%s " % (k,ddict[k][0], ddict[k][1],ddict[k][2]) +- +-class fcontextRecords(semanageRecords): +- try: +- valid_types = sepolicy.info(sepolicy.ATTRIBUTE,"file_type")[0]["types"] +- valid_types += sepolicy.info(sepolicy.ATTRIBUTE,"device_node")[0]["types"] +- valid_types.append("<>") +- except RuntimeError: +- valid_types = [] +- +- def __init__(self, store = ""): +- semanageRecords.__init__(self, store) +- self.equiv = {} +- self.equiv_dist = {} +- self.equal_ind = False +- try: +- fd = open(selinux.selinux_file_context_subs_path(), "r") +- for i in fd.readlines(): +- i = i.strip() +- if len(i) == 0: +- continue +- if i.startswith("#"): +- continue +- target, substitute = i.split() +- self.equiv[target] = substitute +- fd.close() +- except IOError: +- pass +- try: +- fd = open(selinux.selinux_file_context_subs_dist_path(), "r") +- for i in fd.readlines(): +- i = i.strip() +- if len(i) == 0: +- continue +- if i.startswith("#"): +- continue +- target, substitute = i.split() +- self.equiv_dist[target] = substitute +- fd.close() +- except IOError: +- pass +- +- def commit(self): +- if self.equal_ind: +- subs_file = selinux.selinux_file_context_subs_path() +- tmpfile = "%s.tmp" % subs_file +- fd = open(tmpfile, "w") +- for target in self.equiv.keys(): +- fd.write("%s %s\n" % (target, self.equiv[target])) +- fd.close() +- try: +- os.chmod(tmpfile, os.stat(subs_file)[stat.ST_MODE]) +- except: +- pass +- os.rename(tmpfile,subs_file) +- self.equal_ind = False +- semanageRecords.commit(self) +- +- def add_equal(self, target, substitute): +- self.begin() +- if target != "/" and target[-1] == "/": +- raise ValueError(_("Target %s is not valid. Target is not allowed to end with '/'") % target ) +- +- if substitute != "/" and substitute[-1] == "/": +- raise ValueError(_("Substiture %s is not valid. Substitute is not allowed to end with '/'") % substitute ) +- +- if target in self.equiv.keys(): +- raise ValueError(_("Equivalence class for %s already exists") % target) +- self.validate(target) +- +- for fdict in (self.equiv, self.equiv_dist): +- for i in fdict: +- if i.startswith(target + "/"): +- raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'") % (target, i, fdict[i])) +- +- self.equiv[target] = substitute +- self.equal_ind = True +- self.commit() +- +- def modify_equal(self, target, substitute): +- self.begin() +- if target not in self.equiv.keys(): +- raise ValueError(_("Equivalence class for %s does not exists") % target) +- self.equiv[target] = substitute +- self.equal_ind = True +- self.commit() +- +- def createcon(self, target, seuser = "system_u"): +- (rc, con) = semanage_context_create(self.sh) +- if rc < 0: +- raise ValueError(_("Could not create context for %s") % target) +- if seuser == "": +- seuser = "system_u" +- +- rc = semanage_context_set_user(self.sh, con, seuser) +- if rc < 0: +- raise ValueError(_("Could not set user in file context for %s") % target) +- +- rc = semanage_context_set_role(self.sh, con, "object_r") +- if rc < 0: +- raise ValueError(_("Could not set role in file context for %s") % target) +- +- if is_mls_enabled == 1: +- rc = semanage_context_set_mls(self.sh, con, "s0") +- if rc < 0: +- raise ValueError(_("Could not set mls fields in file context for %s") % target) +- +- return con +- +- def validate(self, target): +- if target == "" or target.find("\n") >= 0: +- raise ValueError(_("Invalid file specification")) +- if target.find(" ") != -1: +- raise ValueError(_("File specification can not include spaces")) +- for fdict in (self.equiv, self.equiv_dist): +- for i in fdict: +- if target.startswith(i+"/"): +- t = re.sub(i, fdict[i], target) +- raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'; Try adding '%s' instead") % (target, i, fdict[i], t)) +- +- +- def __add(self, target, type, ftype = "", serange = "s0", seuser = "system_u"): +- self.validate(target) +- +- if seuser == "": +- seuser = "system_u" +- +- if serange == "": +- serange = "s0" +- +- if is_mls_enabled == 1: +- serange = untranslate(serange) +- +- if type == "": +- raise ValueError(_("SELinux Type is required")) +- +- if type not in self.valid_types: +- raise ValueError(_("Type %s is invalid, must be a file or device type") % type) +- +- (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) +- if rc < 0: +- raise ValueError(_("Could not create key for %s") % target) +- +- (rc, exists) = semanage_fcontext_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if file context for %s is defined") % target) +- +- if not exists: +- (rc, exists) = semanage_fcontext_exists_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if file context for %s is defined") % target) +- +- if exists: +- raise ValueError(_("File context for %s already defined") % target) +- +- (rc, fcontext) = semanage_fcontext_create(self.sh) +- if rc < 0: +- raise ValueError(_("Could not create file context for %s") % target) +- +- rc = semanage_fcontext_set_expr(self.sh, fcontext, target) +- if type != "<>": +- con = self.createcon(target, seuser) +- +- rc = semanage_context_set_type(self.sh, con, type) +- if rc < 0: +- raise ValueError(_("Could not set type in file context for %s") % target) +- +- if serange != "": +- rc = semanage_context_set_mls(self.sh, con, serange) +- if rc < 0: +- raise ValueError(_("Could not set mls fields in file context for %s") % target) +- rc = semanage_fcontext_set_con(self.sh, fcontext, con) +- if rc < 0: +- raise ValueError(_("Could not set file context for %s") % target) +- +- semanage_fcontext_set_type(fcontext, file_types[ftype]) +- +- rc = semanage_fcontext_modify_local(self.sh, k, fcontext) +- if rc < 0: +- raise ValueError(_("Could not add file context for %s") % target) +- +- if type != "<>": +- semanage_context_free(con) +- semanage_fcontext_key_free(k) +- semanage_fcontext_free(fcontext) +- +- def add(self, target, type, ftype = "", serange = "", seuser = "system_u"): +- self.begin() +- self.__add(target, type, ftype, serange, seuser) +- self.commit() +- +- def __modify(self, target, setype, ftype, serange, seuser): +- if serange == "" and setype == "" and seuser == "": +- raise ValueError(_("Requires setype, serange or seuser")) +- if setype and setype not in self.valid_types: +- raise ValueError(_("Type %s is invalid, must be a port type") % setype) +- +- self.validate(target) +- +- (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) +- if rc < 0: +- raise ValueError(_("Could not create a key for %s") % target) +- +- (rc, exists) = semanage_fcontext_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if file context for %s is defined") % target) +- if not exists: +- (rc, exists) = semanage_fcontext_exists_local(self.sh, k) +- if not exists: +- raise ValueError(_("File context for %s is not defined") % target) +- +- (rc, fcontext) = semanage_fcontext_query_local(self.sh, k) +- if rc < 0: +- (rc, fcontext) = semanage_fcontext_query(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not query file context for %s") % target) +- +- if setype != "<>": +- con = semanage_fcontext_get_con(fcontext) +- +- if con == None: +- con = self.createcon(target) +- +- if serange != "": +- semanage_context_set_mls(self.sh, con, untranslate(serange)) +- if seuser != "": +- semanage_context_set_user(self.sh, con, seuser) +- +- if setype != "": +- semanage_context_set_type(self.sh, con, setype) +- +- rc = semanage_fcontext_set_con(self.sh, fcontext, con) +- if rc < 0: +- raise ValueError(_("Could not set file context for %s") % target) +- else: +- rc = semanage_fcontext_set_con(self.sh, fcontext, None) +- if rc < 0: +- raise ValueError(_("Could not set file context for %s") % target) +- +- rc = semanage_fcontext_modify_local(self.sh, k, fcontext) +- if rc < 0: +- raise ValueError(_("Could not modify file context for %s") % target) +- +- semanage_fcontext_key_free(k) +- semanage_fcontext_free(fcontext) +- +- def modify(self, target, setype, ftype, serange, seuser): +- self.begin() +- self.__modify(target, setype, ftype, serange, seuser) +- self.commit() +- +- def deleteall(self): +- (rc, flist) = semanage_fcontext_list_local(self.sh) +- if rc < 0: +- raise ValueError(_("Could not list the file contexts")) +- +- self.begin() +- +- for fcontext in flist: +- target = semanage_fcontext_get_expr(fcontext) +- ftype = semanage_fcontext_get_type(fcontext) +- ftype_str = semanage_fcontext_get_type_str(ftype) +- (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype_str]) +- if rc < 0: +- raise ValueError(_("Could not create a key for %s") % target) +- +- rc = semanage_fcontext_del_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not delete the file context %s") % target) +- semanage_fcontext_key_free(k) +- +- self.equiv = {} +- self.equal_ind = True +- self.commit() +- +- def __delete(self, target, ftype): +- if target in self.equiv.keys(): +- self.equiv.pop(target) +- self.equal_ind = True +- return +- +- (rc,k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) +- if rc < 0: +- raise ValueError(_("Could not create a key for %s") % target) +- +- (rc, exists) = semanage_fcontext_exists_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if file context for %s is defined") % target) +- if not exists: +- (rc, exists) = semanage_fcontext_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if file context for %s is defined") % target) +- if exists: +- raise ValueError(_("File context for %s is defined in policy, cannot be deleted") % target) +- else: +- raise ValueError(_("File context for %s is not defined") % target) +- +- rc = semanage_fcontext_del_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not delete file context for %s") % target) +- +- semanage_fcontext_key_free(k) +- +- def delete(self, target, ftype): +- self.begin() +- self.__delete( target, ftype) +- self.commit() +- +- def get_all(self, locallist = 0): +- if locallist: +- (rc, self.flist) = semanage_fcontext_list_local(self.sh) +- else: +- (rc, self.flist) = semanage_fcontext_list(self.sh) +- if rc < 0: +- raise ValueError(_("Could not list file contexts")) +- +- (rc, fclocal) = semanage_fcontext_list_local(self.sh) +- if rc < 0: +- raise ValueError(_("Could not list local file contexts")) +- +- self.flist += fclocal +- +- ddict = {} +- for fcontext in self.flist: +- expr = semanage_fcontext_get_expr(fcontext) +- ftype = semanage_fcontext_get_type(fcontext) +- ftype_str = semanage_fcontext_get_type_str(ftype) +- con = semanage_fcontext_get_con(fcontext) +- if con: +- ddict[(expr, ftype_str)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con)) +- else: +- ddict[(expr, ftype_str)] = con +- +- return ddict +- +- def customized(self): +- l = [] +- fcon_dict = self.get_all(True) +- keys = fcon_dict.keys() +- keys.sort() +- for k in keys: +- if fcon_dict[k]: +- l.append("-a -f %s -t %s '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], k[0])) +- +- if len(self.equiv): +- for target in self.equiv.keys(): +- l.append("-a -e %s %s" % (self.equiv[target], target)) +- return l +- +- def list(self, heading = 1, locallist = 0 ): +- fcon_dict = self.get_all(locallist) +- keys = fcon_dict.keys() +- if len(keys) != 0: +- keys.sort() +- if heading: +- print "%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context")) +- for k in keys: +- if fcon_dict[k]: +- if is_mls_enabled: +- print "%-50s %-18s %s:%s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2], translate(fcon_dict[k][3],False)) +- else: +- print "%-50s %-18s %s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1],fcon_dict[k][2]) +- else: +- print "%-50s %-18s <>" % (k[0], k[1]) +- +- if len(self.equiv_dist): +- if not locallist: +- if heading: +- print _("\nSELinux Distribution fcontext Equivalence \n") +- for target in self.equiv_dist.keys(): +- print "%s = %s" % (target, self.equiv_dist[target]) +- if len(self.equiv): +- if heading: +- print _("\nSELinux Local fcontext Equivalence \n") +- +- for target in self.equiv.keys(): +- print "%s = %s" % (target, self.equiv[target]) +- +-class booleanRecords(semanageRecords): +- def __init__(self, store = ""): +- semanageRecords.__init__(self, store) +- self.dict = {} +- self.dict["TRUE"] = 1 +- self.dict["FALSE"] = 0 +- self.dict["ON"] = 1 +- self.dict["OFF"] = 0 +- self.dict["1"] = 1 +- self.dict["0"] = 0 +- +- try: +- rc, self.current_booleans = selinux.security_get_boolean_names() +- rc, ptype = selinux.selinux_getpolicytype() +- except: +- self.current_booleans = [] +- ptype = None +- +- if self.store == None or self.store == ptype: +- self.modify_local = True +- else: +- self.modify_local = False +- +- def __mod(self, name, value): +- name = selinux.selinux_boolean_sub(name) +- +- (rc, k) = semanage_bool_key_create(self.sh, name) +- if rc < 0: +- raise ValueError(_("Could not create a key for %s") % name) +- (rc, exists) = semanage_bool_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if boolean %s is defined") % name) +- if not exists: +- raise ValueError(_("Boolean %s is not defined") % name) +- +- (rc, b) = semanage_bool_query(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not query file context %s") % name) +- +- if value.upper() in self.dict: +- semanage_bool_set_value(b, self.dict[value.upper()]) +- else: +- raise ValueError(_("You must specify one of the following values: %s") % ", ".join(self.dict.keys()) ) +- +- if self.modify_local and name in self.current_booleans: +- rc = semanage_bool_set_active(self.sh, k, b) +- if rc < 0: +- raise ValueError(_("Could not set active value of boolean %s") % name) +- rc = semanage_bool_modify_local(self.sh, k, b) +- if rc < 0: +- raise ValueError(_("Could not modify boolean %s") % name) +- semanage_bool_key_free(k) +- semanage_bool_free(b) +- +- def modify(self, name, value = None, use_file = False): +- self.begin() +- if use_file: +- fd = open(name) +- for b in fd.read().split("\n"): +- b = b.strip() +- if len(b) == 0: +- continue +- +- try: +- boolname, val = b.split("=") +- except ValueError: +- raise ValueError(_("Bad format %s: Record %s" % ( name, b) )) +- self.__mod(boolname.strip(), val.strip()) +- fd.close() +- else: +- self.__mod(name, value) +- +- self.commit() +- +- def __delete(self, name): +- name = selinux.selinux_boolean_sub(name) +- +- (rc, k) = semanage_bool_key_create(self.sh, name) +- if rc < 0: +- raise ValueError(_("Could not create a key for %s") % name) +- (rc, exists) = semanage_bool_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if boolean %s is defined") % name) +- if not exists: +- raise ValueError(_("Boolean %s is not defined") % name) +- +- (rc, exists) = semanage_bool_exists_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if boolean %s is defined") % name) +- if not exists: +- raise ValueError(_("Boolean %s is defined in policy, cannot be deleted") % name) +- +- rc = semanage_bool_del_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not delete boolean %s") % name) +- +- semanage_bool_key_free(k) +- +- def delete(self, name): +- self.begin() +- self.__delete(name) +- self.commit() +- +- def deleteall(self): +- (rc, self.blist) = semanage_bool_list_local(self.sh) +- if rc < 0: +- raise ValueError(_("Could not list booleans")) +- +- self.begin() +- +- for boolean in self.blist: +- name = semanage_bool_get_name(boolean) +- self.__delete(name) +- +- self.commit() +- +- def get_all(self, locallist = 0): +- ddict = {} +- if locallist: +- (rc, self.blist) = semanage_bool_list_local(self.sh) +- else: +- (rc, self.blist) = semanage_bool_list(self.sh) +- if rc < 0: +- raise ValueError(_("Could not list booleans")) +- +- for boolean in self.blist: +- value = [] +- name = semanage_bool_get_name(boolean) +- value.append(semanage_bool_get_value(boolean)) +- if self.modify_local and boolean in self.current_booleans: +- value.append(selinux.security_get_boolean_pending(name)) +- value.append(selinux.security_get_boolean_active(name)) +- else: +- value.append(value[0]) +- value.append(value[0]) +- ddict[name] = value +- +- return ddict +- +- def get_desc(self, name): +- name = selinux.selinux_boolean_sub(name) +- return boolean_desc(name) +- +- def get_category(self, name): +- name = selinux.selinux_boolean_sub(name) +- return boolean_category(name) +- +- def customized(self): +- l = [] +- ddict = self.get_all(True) +- keys = ddict.keys() +- keys.sort() +- for k in keys: +- if ddict[k]: +- l.append("-m -%s %s" % (ddict[k][2], k)) +- return l +- +- def list(self, heading = True, locallist = False, use_file = False): +- on_off = (_("off"), _("on")) +- if use_file: +- ddict = self.get_all(locallist) +- keys = ddict.keys() +- for k in keys: +- if ddict[k]: +- print "%s=%s" % (k, ddict[k][2]) +- return +- ddict = self.get_all(locallist) +- keys = ddict.keys() +- if len(keys) == 0: +- return +- +- if heading: +- print "%-30s %s %s %s\n" % (_("SELinux boolean"),_("State"), _("Default"), _("Description")) +- for k in keys: +- if ddict[k]: +- print "%-30s (%-5s,%5s) %s" % (k, on_off[selinux.security_get_boolean_active(k)], on_off[ddict[k][2]], self.get_desc(k)) +diff --git a/policycoreutils/semanage/seobject/__init__.py b/policycoreutils/semanage/seobject/__init__.py +new file mode 100644 +index 0000000..5835ab1 +--- /dev/null ++++ b/policycoreutils/semanage/seobject/__init__.py +@@ -0,0 +1,2243 @@ ++#! /usr/bin/python -Es ++# Copyright (C) 2005-2013 Red Hat ++# see file 'COPYING' for use and warranty information ++# ++# semanage is a tool for managing SELinux configuration files ++# ++# 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., 59 Temple Place, Suite 330, Boston, MA ++# 02111-1307 USA ++# ++# ++ ++import pwd, grp, string, selinux, os, re, sys, stat ++from semanage import *; ++PROGNAME = "policycoreutils" ++import sepolicy ++from sepolicy import boolean_desc, boolean_category, gen_bool_dict ++gen_bool_dict() ++from IPy import IP ++ ++import gettext ++PROGNAME="policycoreutils" ++gettext.bindtextdomain(PROGNAME, "/usr/share/locale") ++gettext.textdomain(PROGNAME) ++try: ++ gettext.install(PROGNAME, ++ unicode=True, ++ codeset = 'utf-8') ++except TypeError: ++ # Failover to python3 install ++ gettext.install(PROGNAME, ++ codeset = 'utf-8') ++except IOError: ++ import builtins ++ builtins.__dict__['_'] = str ++ ++is_mls_enabled = True ++ ++import syslog ++ ++file_types = {} ++file_types[""] = SEMANAGE_FCONTEXT_ALL; ++file_types["all files"] = SEMANAGE_FCONTEXT_ALL; ++file_types["a"] = SEMANAGE_FCONTEXT_ALL; ++file_types["regular file"] = SEMANAGE_FCONTEXT_REG; ++file_types["--"] = SEMANAGE_FCONTEXT_REG; ++file_types["f"] = SEMANAGE_FCONTEXT_REG; ++file_types["-d"] = SEMANAGE_FCONTEXT_DIR; ++file_types["directory"] = SEMANAGE_FCONTEXT_DIR; ++file_types["d"] = SEMANAGE_FCONTEXT_DIR; ++file_types["-c"] = SEMANAGE_FCONTEXT_CHAR; ++file_types["character device"] = SEMANAGE_FCONTEXT_CHAR; ++file_types["c"] = SEMANAGE_FCONTEXT_CHAR; ++file_types["-b"] = SEMANAGE_FCONTEXT_BLOCK; ++file_types["block device"] = SEMANAGE_FCONTEXT_BLOCK; ++file_types["b"] = SEMANAGE_FCONTEXT_BLOCK; ++file_types["-s"] = SEMANAGE_FCONTEXT_SOCK; ++file_types["socket"] = SEMANAGE_FCONTEXT_SOCK; ++file_types["s"] = SEMANAGE_FCONTEXT_SOCK; ++file_types["-l"] = SEMANAGE_FCONTEXT_LINK; ++file_types["l"] = SEMANAGE_FCONTEXT_LINK; ++file_types["symbolic link"] = SEMANAGE_FCONTEXT_LINK; ++file_types["p"] = SEMANAGE_FCONTEXT_PIPE; ++file_types["-p"] = SEMANAGE_FCONTEXT_PIPE; ++file_types["named pipe"] = SEMANAGE_FCONTEXT_PIPE; ++ ++file_type_str_to_option = { "all files": "a", ++ "regular file":"f", ++ "directory":"d", ++ "character device":"c", ++ "block device":"b", ++ "socket file":"s", ++ "symbolic link":"l", ++ "named pipe":"p" } ++try: ++ import audit ++ class logger: ++ def __init__(self): ++ self.audit_fd = audit.audit_open() ++ 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 __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 oldsename != "": ++ message += " oldsename=" + oldsename ++ if serole != "": ++ message += " role=" + serole ++ if oldserole != "": ++ message += " old_role=" + oldserole ++ if serange != "" and serange != None: ++ message += " MLSRange=" + serange ++ 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 ++ ++def validate_level(raw): ++ sensitivity = "s[0-9]*" ++ category = "c[0-9]*" ++ cat_range = category + "(\." + category +")?" ++ categories = cat_range + "(\," + cat_range + ")*" ++ reg = sensitivity + "(-" + sensitivity + ")?" + "(:" + categories + ")?" ++ return re.search("^" + reg +"$", raw) ++ ++def translate(raw, prepend = 1): ++ filler = "a:b:c:" ++ if prepend == 1: ++ context = "%s%s" % (filler, raw) ++ else: ++ context = raw ++ (rc, trans) = selinux.selinux_raw_to_trans_context(context) ++ if rc != 0: ++ return raw ++ if prepend: ++ trans = trans[len(filler):] ++ if trans == "": ++ return raw ++ else: ++ return trans ++ ++def untranslate(trans, prepend = 1): ++ filler = "a:b:c:" ++ if prepend == 1: ++ context = "%s%s" % (filler, trans) ++ else: ++ context = trans ++ ++ (rc, raw) = selinux.selinux_trans_to_raw_context(context) ++ if rc != 0: ++ return trans ++ if prepend: ++ raw = raw[len(filler):] ++ if raw == "": ++ return trans ++ else: ++ return raw ++ ++class semanageRecords: ++ transaction = False ++ handle = None ++ store = None ++ def __init__(self, store): ++ global handle ++ self.load = True ++ self.sh = self.get_handle(store) ++ ++ rc, localstore = selinux.selinux_getpolicytype() ++ if store == "" or store == localstore: ++ self.mylog = logger() ++ else: ++ self.mylog = nulllogger() ++ ++ def set_reload(self, load): ++ self.load = load ++ ++ def get_handle(self, store): ++ global is_mls_enabled ++ ++ if semanageRecords.handle: ++ return semanageRecords.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 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_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")) ++ ++ semanageRecords.handle = handle ++ return semanageRecords.handle ++ ++ def deleteall(self): ++ raise ValueError(_("Not yet implemented")) ++ ++ def start(self): ++ if semanageRecords.transaction: ++ raise ValueError(_("Semanage transaction already in progress")) ++ self.begin() ++ semanageRecords.transaction = True ++ ++ def begin(self): ++ if semanageRecords.transaction: ++ return ++ rc = semanage_begin_transaction(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not start semanage transaction")) ++ def customized(self): ++ raise ValueError(_("Not yet implemented")) ++ ++ def commit(self): ++ if semanageRecords.transaction: ++ return ++ ++ semanage_set_reload(self.sh, self.load) ++ 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: ++ raise ValueError(_("Semanage transaction not in progress")) ++ semanageRecords.transaction = False ++ self.commit() ++ ++class moduleRecords(semanageRecords): ++ def __init__(self, store): ++ semanageRecords.__init__(self, store) ++ ++ def get_all(self): ++ l = [] ++ (rc, mlist, number) = semanage_module_list(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not list SELinux modules")) ++ ++ for i in range(number): ++ mod = semanage_module_list_nth(mlist, i) ++ l.append((semanage_module_get_name(mod), semanage_module_get_version(mod), semanage_module_get_enabled(mod))) ++ return l ++ ++ def customized(self): ++ ALL = self.get_all() ++ if len(ALL) == 0: ++ return ++ return ["-d %s" % x[0] for x in [t for t in ALL if t[2] == 0]] ++ ++ def list(self, heading = True, locallist = False): ++ ALL = self.get_all() ++ if len(ALL) == 0: ++ return ++ ++ if heading: ++ print("\n%-25s%-10s\n" % (_("Modules Name"), _("Version"))) ++ for t in ALL: ++ if t[2] == 0: ++ disabled = _("Disabled") ++ else: ++ if locallist: ++ continue ++ disabled = "" ++ print("%-25s%-10s%s" % (t[0], t[1], disabled)) ++ ++ def add(self, file): ++ if not os.path.exists(file): ++ raise ValueError(_("Module does not exists %s ") % file) ++ rc = semanage_module_install_file(self.sh, file); ++ if rc >= 0: ++ self.commit() ++ ++ def disable(self, module): ++ need_commit = False ++ for m in module.split(): ++ rc = semanage_module_disable(self.sh, m) ++ if rc < 0 and rc != -3: ++ raise ValueError(_("Could not disable module %s (remove failed)") % m) ++ if rc != -3: ++ need_commit = True ++ if need_commit: ++ self.commit() ++ ++ def enable(self, module): ++ need_commit = False ++ for m in module.split(): ++ rc = semanage_module_enable(self.sh, m) ++ if rc < 0 and rc != -3: ++ raise ValueError(_("Could not enable module %s (remove failed)") % m) ++ if rc != -3: ++ need_commit = True ++ if need_commit: ++ self.commit() ++ ++ def modify(self, file): ++ rc = semanage_module_upgrade_file(self.sh, file); ++ if rc >= 0: ++ self.commit() ++ ++ def delete(self, module): ++ for m in module.split(): ++ rc = semanage_module_remove(self.sh, m) ++ if rc < 0 and rc != -2: ++ raise ValueError(_("Could not remove module %s (remove failed)") % m) ++ ++ self.commit() ++ ++ def deleteall(self): ++ l = [x[0] for x in [t for t in self.get_all() if t[2] == 0]] ++ for m in l: ++ self.enable(m) ++ ++class dontauditClass(semanageRecords): ++ def __init__(self, store): ++ semanageRecords.__init__(self, store) ++ ++ def toggle(self, dontaudit): ++ if dontaudit not in [ "on", "off" ]: ++ raise ValueError(_("dontaudit requires either 'on' or 'off'")) ++ self.begin() ++ semanage_set_disable_dontaudit(self.sh, dontaudit == "off") ++ self.commit() ++ ++class permissiveRecords(semanageRecords): ++ def __init__(self, store): ++ semanageRecords.__init__(self, store) ++ ++ def get_all(self): ++ l = [] ++ (rc, mlist, number) = semanage_module_list(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not list SELinux modules")) ++ ++ for i in range(number): ++ mod = semanage_module_list_nth(mlist, i) ++ name = semanage_module_get_name(mod) ++ if name and name.startswith("permissive_"): ++ l.append(name.split("permissive_")[1]) ++ return l ++ ++ def list(self, heading = True, locallist = False): ++ ALL = [y["name"] for y in [x for x in sepolicy.info(sepolicy.TYPE) if x["permissive"]]] ++ if len(ALL) == 0: ++ return ++ ++ customized = self.get_all() ++ if heading: ++ print("\n%-25s\n" % (_("Customized Permissive Types"))) ++ for t in customized: ++ print(t) ++ ++ if locallist: ++ return ++ ++ if heading: ++ print("\n%-25s\n" % (_("Builtin Permissive Types"))) ++ ++ for t in ALL: ++ if t not in customized: ++ print(t) ++ ++ def add(self, setype): ++ import glob ++ if setype not in sepolicy.get_all_domains(): ++ raise ValueError(_("%s is not a domain type") % setype ) ++ ++ try: ++ import sepolgen.module as module ++ except ImportError: ++ raise ValueError(_("The sepolgen python module is required to setup permissive domains.\nIn some distributions it is included in the policycoreutils-devel patckage.\n# yum install policycoreutils-devel\nOr similar for your distro.")) ++ ++ name = "permissive_%s" % setype ++ dirname = "/var/lib/selinux" ++ os.chdir(dirname) ++ filename = "%s.te" % name ++ modtxt = """ ++module %s 1.0; ++ ++require { ++ type %s; ++} ++ ++permissive %s; ++""" % (name, setype, setype) ++ fd = open(filename, 'w') ++ fd.write(modtxt) ++ fd.close() ++ mc = module.ModuleCompiler() ++ mc.create_module_package(filename, 1) ++ fd = open("permissive_%s.pp" % setype) ++ data = fd.read() ++ fd.close() ++ ++ rc = semanage_module_install(self.sh, data, len(data)); ++ if rc >= 0: ++ self.commit() ++ ++ for root, dirs, files in os.walk("tmp", topdown = False): ++ for name in files: ++ os.remove(os.path.join(root, name)) ++ for name in dirs: ++ os.rmdir(os.path.join(root, name)) ++ os.removedirs("tmp") ++ for i in glob.glob("permissive_%s.*" % setype): ++ os.remove(i) ++ if rc < 0: ++ raise ValueError(_("Could not set permissive domain %s (module installation failed)") % name) ++ ++ def delete(self, name): ++ for n in name.split(): ++ rc = semanage_module_remove(self.sh, "permissive_%s" % n) ++ if rc < 0: ++ raise ValueError(_("Could not remove permissive domain %s (remove failed)") % name) ++ ++ self.commit() ++ ++ def deleteall(self): ++ l = self.get_all() ++ if len(l) > 0: ++ self.delete(" ".join(l)) ++ ++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): ++ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) ++ if sename == "": ++ sename = "user_u" ++ ++ userrec = seluserRecords() ++ (rc, oldserole) = userrec.get(self.oldsename)[1] ++ 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) ++ ++ (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 exists: ++ semanage_seuser_key_free(k) ++ return self.__modify(name, sename, serange) ++ ++ if name[0] == '%': ++ try: ++ grp.getgrnam(name[1:]) ++ except: ++ raise ValueError(_("Linux Group %s does not exist") % name[1:]) ++ else: ++ try: ++ pwd.getpwnam(name) ++ except: ++ raise ValueError(_("Linux User %s does not exist") % name) ++ ++ (rc, u) = semanage_seuser_create(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not create login mapping for %s") % name) ++ ++ rc = semanage_seuser_set_name(self.sh, u, name) ++ if rc < 0: ++ raise ValueError(_("Could not set name for %s") % name) ++ ++ if serange: ++ rc = semanage_seuser_set_mlsrange(self.sh, u, serange) ++ if rc < 0: ++ raise ValueError(_("Could not set MLS range for %s") % name) ++ ++ rc = semanage_seuser_set_sename(self.sh, u, sename) ++ if rc < 0: ++ raise ValueError(_("Could not set SELinux user for %s") % name) ++ ++ rc = semanage_seuser_modify_local(self.sh, k, u) ++ if rc < 0: ++ raise ValueError(_("Could not add login mapping for %s") % name) ++ ++ 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() ++ except ValueError as error: ++ self.mylog.commit(0) ++ raise error ++ ++ def __modify(self, name, sename = "", serange=None): ++ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) ++ if sename == "" and not serange: ++ raise ValueError(_("Requires seuser or serange")) ++ ++ userrec = seluserRecords() ++ RANGE, (rc, oldserole) = userrec.get(self.oldsename) ++ ++ if sename != "": ++ RANGE, (rc, serole) = userrec.get(sename) ++ else: ++ serole=oldserole ++ ++ if serange: ++ self.serange=serange ++ else: ++ self.serange=RANGE ++ ++ (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) ++ ++ (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)) ++ ++ 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) ++ ++ 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 = None): ++ try: ++ self.begin() ++ self.__modify(name, sename, serange) ++ self.commit() ++ except ValueError as error: ++ self.mylog.commit(0) ++ raise error ++ ++ def __delete(self, name): ++ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) ++ userrec = seluserRecords() ++ RANGE, (rc, oldserole) = userrec.get(self.oldsename) ++ ++ (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) ++ ++ (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) ++ ++ rec, self.sename, self.serange = selinux.getseuserbyname("__default__") ++ RANGE, (rc, serole) = userrec.get(self.sename) ++ ++ 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() ++ ++ except ValueError as error: ++ self.mylog.commit(0) ++ raise error ++ ++ def deleteall(self): ++ (rc, ulist) = semanage_seuser_list_local(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not list login mappings")) ++ ++ try: ++ self.begin() ++ for u in ulist: ++ self.__delete(semanage_seuser_get_name(u)) ++ self.commit() ++ except ValueError as error: ++ self.mylog.commit(0) ++ raise error ++ ++ def get_all_logins(self): ++ ddict = {} ++ self.logins_path = selinux.selinux_policy_root() + "/logins" ++ for path,dirs,files in os.walk(self.logins_path): ++ if path == self.logins_path: ++ for name in files: ++ try: ++ fd = open(path + "/" + name) ++ rec = fd.read().rstrip().split(":") ++ fd.close() ++ ddict[name] = (rec[1], rec[2], rec[0]) ++ except IndexError: ++ pass ++ return ddict ++ ++ def get_all(self, locallist = False): ++ ddict = {} ++ if locallist: ++ (rc, self.ulist) = semanage_seuser_list_local(self.sh) ++ else: ++ (rc, self.ulist) = semanage_seuser_list(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not list login mappings")) ++ ++ for u in self.ulist: ++ name = semanage_seuser_get_name(u) ++ ddict[name] = (semanage_seuser_get_sename(u), semanage_seuser_get_mlsrange(u), "*") ++ return ddict ++ ++ def customized(self): ++ l = [] ++ ddict = self.get_all(True) ++ keys = list(ddict.keys()) ++ keys.sort() ++ for k in keys: ++ l.append("-a -s %s -r '%s' %s" % (ddict[k][0], ddict[k][1], k)) ++ return l ++ ++ def list(self,heading = True, locallist = False): ++ ddict = self.get_all(locallist) ++ ldict = self.get_all_logins() ++ lkeys = list(ldict.keys()) ++ keys = list(ddict.keys()) ++ if len(keys) == 0 and len(lkeys) == 0: ++ return ++ keys.sort() ++ lkeys.sort() ++ ++ if is_mls_enabled == 1: ++ if heading: ++ print("\n%-20s %-20s %-20s %s\n" % (_("Login Name"), _("SELinux User"), _("MLS/MCS Range"), _("Service"))) ++ for k in keys: ++ u = ddict[k] ++ print("%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])) ++ if len(lkeys): ++ print("\nLocal customization in %s" % self.logins_path) ++ ++ for k in lkeys: ++ u = ldict[k] ++ print("%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])) ++ else: ++ if heading: ++ print("\n%-25s %-25s\n" % (_("Login Name"), _("SELinux User"))) ++ for k in keys: ++ print("%-25s %-25s" % (k, ddict[k][0])) ++ ++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: ++ serange = untranslate(serange) ++ else: ++ serange = "s0" ++ ++ if selevel == "": ++ selevel = "s0" ++ else: ++ selevel = untranslate(selevel) ++ ++ if len(roles) < 1: ++ raise ValueError(_("You must add at least one role for %s") % 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) ++ if exists: ++ semanage_user_key_free(k) ++ return self.__modify(name, roles, selevel, serange, prefix) ++ ++ (rc, u) = semanage_user_create(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not create SELinux user for %s") % name) ++ ++ rc = semanage_user_set_name(self.sh, u, name) ++ if rc < 0: ++ raise ValueError(_("Could not set name for %s") % name) ++ ++ for r in roles: ++ rc = semanage_user_add_role(self.sh, u, r) ++ if rc < 0: ++ raise ValueError(_("Could not add role %(ROLE)s for %(NAME)s") % {"ROLE":r, "NAME":name}) ++ ++ if is_mls_enabled == 1: ++ rc = semanage_user_set_mlsrange(self.sh, u, serange) ++ if rc < 0: ++ raise ValueError(_("Could not set MLS range for %s") % name) ++ ++ rc = semanage_user_set_mlslevel(self.sh, u, selevel) ++ if rc < 0: ++ raise ValueError(_("Could not set MLS level for %s") % name) ++ rc = semanage_user_set_prefix(self.sh, u, prefix) ++ if rc < 0: ++ raise ValueError(_("Could not add prefix %(ROLE)s for %(PREFIX)s") % {"ROLE":r, "PREFIX": prefix}) ++ (rc, key) = semanage_user_key_extract(self.sh,u) ++ if rc < 0: ++ raise ValueError(_("Could not extract key for %s") % name) ++ ++ rc = semanage_user_modify_local(self.sh, k, u) ++ if rc < 0: ++ raise ValueError(_("Could not add SELinux user %s") % name) ++ ++ 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): ++ try: ++ self.begin() ++ self.__add( name, roles, selevel, serange, prefix) ++ self.commit() ++ except ValueError as error: ++ self.mylog.commit(0) ++ raise error ++ ++ def __modify(self, name, roles = [], selevel = "", serange = None, prefix = ""): ++ oldserole = "" ++ oldserange = "" ++ newroles = string.join(roles, ' '); ++ if prefix == "" and len(roles) == 0 and not serange and selevel == "": ++ if is_mls_enabled == 1: ++ raise ValueError(_("Requires prefix, roles, level or range")) ++ else: ++ raise ValueError(_("Requires prefix or roles")) ++ ++ (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) ++ if not exists: ++ raise ValueError(_("SELinux user %s is not defined") % 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) ++ if rc >= 0: ++ oldserole = string.join(rlist, ' '); ++ ++ if serange: ++ semanage_user_set_mlsrange(self.sh, u, untranslate(serange)) ++ if selevel != "": ++ semanage_user_set_mlslevel(self.sh, u, untranslate(selevel)) ++ ++ if prefix != "": ++ semanage_user_set_prefix(self.sh, u, prefix) ++ ++ if len(roles) != 0: ++ for r in rlist: ++ if r not in roles: ++ semanage_user_del_role(u, r) ++ for r in roles: ++ if r not in rlist: ++ semanage_user_add_role(self.sh, u, r) ++ ++ rc = semanage_user_modify_local(self.sh, k, u) ++ if rc < 0: ++ raise ValueError(_("Could not modify SELinux user %s") % name) ++ ++ semanage_user_key_free(k) ++ semanage_user_free(u) ++ ++ 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 = None, prefix = ""): ++ try: ++ self.begin() ++ self.__modify(name, roles, selevel, serange, prefix) ++ self.commit() ++ except ValueError as error: ++ self.mylog.commit(0) ++ raise error ++ ++ def __delete(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) ++ if not exists: ++ raise ValueError(_("SELinux user %s is not defined") % name) ++ ++ (rc, exists) = semanage_user_exists_local(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if SELinux user %s is defined") % name) ++ 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: ++ self.begin() ++ self.__delete(name) ++ self.commit() ++ ++ except ValueError as error: ++ self.mylog.commit(0) ++ raise error ++ ++ def deleteall(self): ++ (rc, ulist) = semanage_user_list_local(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not list login mappings")) ++ ++ try: ++ self.begin() ++ for u in ulist: ++ self.__delete(semanage_user_get_name(u)) ++ self.commit() ++ except ValueError as error: ++ self.mylog.commit(0) ++ raise error ++ ++ def get_all(self, locallist = False): ++ ddict = {} ++ if locallist: ++ (rc, self.ulist) = semanage_user_list_local(self.sh) ++ else: ++ (rc, self.ulist) = semanage_user_list(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not list SELinux users")) ++ ++ for u in self.ulist: ++ name = semanage_user_get_name(u) ++ (rc, rlist) = semanage_user_get_roles(self.sh, u) ++ if rc < 0: ++ raise ValueError(_("Could not list roles for user %s") % name) ++ ++ roles = string.join(rlist, ' '); ++ ddict[semanage_user_get_name(u)] = (semanage_user_get_prefix(u), semanage_user_get_mlslevel(u), semanage_user_get_mlsrange(u), roles) ++ ++ return ddict ++ ++ def customized(self): ++ l = [] ++ ddict = self.get_all(True) ++ keys = list(ddict.keys()) ++ keys.sort() ++ for k in keys: ++ l.append("-a -L %s -r %s -R '%s' %s" % (ddict[k][1], ddict[k][2], ddict[k][3], k)) ++ return l ++ ++ def list(self, heading = True, locallist = False): ++ ddict = self.get_all(locallist) ++ keys = list(ddict.keys()) ++ if len(keys) == 0: ++ return ++ keys.sort() ++ ++ if is_mls_enabled == 1: ++ if heading: ++ print("\n%-15s %-10s %-10s %-30s" % ("", _("Labeling"), _("MLS/"), _("MLS/"))) ++ print("%-15s %-10s %-10s %-30s %s\n" % (_("SELinux User"), _("Prefix"), _("MCS Level"), _("MCS Range"), _("SELinux Roles"))) ++ for k in keys: ++ print("%-15s %-10s %-10s %-30s %s" % (k, ddict[k][0], translate(ddict[k][1]), translate(ddict[k][2]), ddict[k][3])) ++ else: ++ if heading: ++ print("%-15s %s\n" % (_("SELinux User"), _("SELinux Roles"))) ++ for k in keys: ++ print("%-15s %s" % (k, ddict[k][3])) ++ ++class portRecords(semanageRecords): ++ try: ++ valid_types = sepolicy.info(sepolicy.ATTRIBUTE,"port_type")[0]["types"] ++ except RuntimeError: ++ valid_types = [] ++ ++ def __init__(self, store = ""): ++ semanageRecords.__init__(self, store) ++ ++ def __genkey(self, port, proto): ++ if proto == "tcp": ++ proto_d = SEMANAGE_PROTO_TCP ++ else: ++ if proto == "udp": ++ proto_d = SEMANAGE_PROTO_UDP ++ else: ++ raise ValueError(_("Protocol udp or tcp is required")) ++ if port == "": ++ raise ValueError(_("Port is required")) ++ ++ ports = port.split("-") ++ if len(ports) == 1: ++ high = low = int(ports[0]) ++ else: ++ low = int(ports[0]) ++ high = int(ports[1]) ++ ++ if high > 65535: ++ raise ValueError(_("Invalid Port")) ++ ++ (rc, k) = semanage_port_key_create(self.sh, low, high, proto_d) ++ if rc < 0: ++ raise ValueError(_("Could not create a key for %(PROTOTYPE)s/%(PORT)s") % {"PROTOTYPE": proto, "PORT":port}) ++ return ( k, proto_d, low, high ) ++ ++ def __add(self, port, proto, serange, type): ++ if is_mls_enabled == 1: ++ if serange: ++ serange = untranslate(serange) ++ else: ++ serange = "s0" ++ ++ if type == "": ++ raise ValueError(_("Type is required")) ++ ++ if type not in self.valid_types: ++ raise ValueError(_("Type %s is invalid, must be a port type") % type) ++ ++ ( k, proto_d, low, high ) = self.__genkey(port, proto) ++ if semanageRecords.transaction: ++ (rc, exists) = semanage_port_exists_local(self.sh, k) ++ else: ++ (rc, exists) = semanage_port_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if port %(PROTOCOL)s/%(PORT)s is defined") % {"PROTOCOL": proto, "PORT": port}) ++ if exists: ++ raise ValueError(_("Port %(PROTOCOL)s/%(PORT)s already defined") % {"PROTOCOL": proto, "PORT": port}) ++ ++ (rc, p) = semanage_port_create(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not create port for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) ++ ++ semanage_port_set_proto(p, proto_d) ++ semanage_port_set_range(p, low, high) ++ (rc, con) = semanage_context_create(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not create context for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) ++ ++ rc = semanage_context_set_user(self.sh, con, "system_u") ++ if rc < 0: ++ raise ValueError(_("Could not set user in port context for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) ++ ++ rc = semanage_context_set_role(self.sh, con, "object_r") ++ if rc < 0: ++ raise ValueError(_("Could not set role in port context for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) ++ ++ rc = semanage_context_set_type(self.sh, con, type) ++ if rc < 0: ++ raise ValueError(_("Could not set type in port context for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) ++ ++ if serange: ++ rc = semanage_context_set_mls(self.sh, con, serange) ++ if rc < 0: ++ raise ValueError(_("Could not set mls fields in port context for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) ++ ++ rc = semanage_port_set_con(self.sh, p, con) ++ if rc < 0: ++ raise ValueError(_("Could not set port context for %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) ++ ++ rc = semanage_port_modify_local(self.sh, k, p) ++ if rc < 0: ++ raise ValueError(_("Could not add port %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) ++ ++ semanage_context_free(con) ++ semanage_port_key_free(k) ++ semanage_port_free(p) ++ ++ def add(self, port, proto, serange, type): ++ self.begin() ++ self.__add(port, proto, serange, type) ++ self.commit() ++ ++ def __modify(self, port, proto, serange, setype): ++ if not serange and setype == "": ++ if is_mls_enabled == 1: ++ raise ValueError(_("Requires setype or serange")) ++ else: ++ raise ValueError(_("Requires setype")) ++ ++ if setype and setype not in self.valid_types: ++ raise ValueError(_("Type %s is invalid, must be a port type") % setype) ++ ++ ( k, proto_d, low, high ) = self.__genkey(port, proto) ++ ++ (rc, exists) = semanage_port_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if port @%(PROTOCOL)s/%(PORT)s is defined") % {"PROTOCOL": proto, "PORT": port}) ++ if not exists: ++ raise ValueError(_("Port @%(PROTOCOL)s/%(PORT)s is not defined") % {"PROTOCOL": proto, "PORT": port}) ++ ++ (rc, p) = semanage_port_query(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not query port %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) ++ ++ con = semanage_port_get_con(p) ++ ++ if serange: ++ semanage_context_set_mls(self.sh, con, untranslate(serange)) ++ if setype != "": ++ semanage_context_set_type(self.sh, con, setype) ++ ++ rc = semanage_port_modify_local(self.sh, k, p) ++ if rc < 0: ++ raise ValueError(_("Could not modify port %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) ++ ++ semanage_port_key_free(k) ++ semanage_port_free(p) ++ ++ def modify(self, port, proto, serange, setype): ++ self.begin() ++ self.__modify(port, proto, serange, setype) ++ self.commit() ++ ++ def deleteall(self): ++ (rc, plist) = semanage_port_list_local(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not list the ports")) ++ ++ self.begin() ++ ++ for port in plist: ++ proto = semanage_port_get_proto(port) ++ proto_str = semanage_port_get_proto_str(proto) ++ low = semanage_port_get_low(port) ++ high = semanage_port_get_high(port) ++ port_str = "%s-%s" % (low, high) ++ ( k, proto_d, low, high ) = self.__genkey(port_str , proto_str) ++ if rc < 0: ++ raise ValueError(_("Could not create a key for %s") % port_str) ++ ++ rc = semanage_port_del_local(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not delete the port %s") % port_str) ++ semanage_port_key_free(k) ++ ++ self.commit() ++ ++ def __delete(self, port, proto): ++ ( k, proto_d, low, high ) = self.__genkey(port, proto) ++ (rc, exists) = semanage_port_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if port %(PROTOCOL)s/%(PORT)s is defined") % {"PROTOCOL": proto, "PORT": port}) ++ if not exists: ++ raise ValueError(_("Port %(PROTOCOL)s/%(PORT)s is not defined") % {"PROTOCOL": proto, "PORT": port}) ++ ++ (rc, exists) = semanage_port_exists_local(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if port %(PROTOCOL)s/%(PORT)s is defined") % {"PROTOCOL": proto, "PORT": port}) ++ if not exists: ++ raise ValueError(_("Port %(PROTOCOL)s/%(PORT)s is defined in policy, cannot be deleted") % {"PROTOCOL": proto, "PORT": port}) ++ ++ rc = semanage_port_del_local(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not delete port %(PROTOCOL)s/%(PORT)s") % {"PROTOCOL": proto, "PORT": port}) ++ ++ semanage_port_key_free(k) ++ ++ def delete(self, port, proto): ++ self.begin() ++ self.__delete(port, proto) ++ self.commit() ++ ++ def get_all(self, locallist = False): ++ ddict = {} ++ if locallist: ++ (rc, self.plist) = semanage_port_list_local(self.sh) ++ else: ++ (rc, self.plist) = semanage_port_list(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not list ports")) ++ ++ for port in self.plist: ++ con = semanage_port_get_con(port) ++ ctype = semanage_context_get_type(con) ++ if ctype == "reserved_port_t": ++ continue ++ level = semanage_context_get_mls(con) ++ proto = semanage_port_get_proto(port) ++ proto_str = semanage_port_get_proto_str(proto) ++ low = semanage_port_get_low(port) ++ high = semanage_port_get_high(port) ++ ddict[(low, high, proto_str)] = (ctype, level) ++ return ddict ++ ++ def get_all_by_type(self, locallist = False): ++ ddict = {} ++ if locallist: ++ (rc, self.plist) = semanage_port_list_local(self.sh) ++ else: ++ (rc, self.plist) = semanage_port_list(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not list ports")) ++ ++ for port in self.plist: ++ con = semanage_port_get_con(port) ++ ctype = semanage_context_get_type(con) ++ if ctype == "reserved_port_t": ++ continue ++ proto = semanage_port_get_proto(port) ++ proto_str = semanage_port_get_proto_str(proto) ++ low = semanage_port_get_low(port) ++ high = semanage_port_get_high(port) ++ if (ctype, proto_str) not in list(ddict.keys()): ++ ddict[(ctype,proto_str)] = [] ++ if low == high: ++ ddict[(ctype,proto_str)].append("%d" % low) ++ else: ++ ddict[(ctype,proto_str)].append("%d-%d" % (low, high)) ++ return ddict ++ ++ def customized(self): ++ l = [] ++ ddict = self.get_all(True) ++ keys = list(ddict.keys()) ++ keys.sort() ++ for k in keys: ++ if k[0] == k[1]: ++ l.append("-a -t %s -p %s %s" % (ddict[k][0], k[2], k[0])) ++ else: ++ l.append("-a -t %s -p %s %s-%s" % (ddict[k][0], k[2], k[0], k[1])) ++ return l ++ ++ def list(self, heading = True, locallist = False): ++ ddict = self.get_all_by_type(locallist) ++ keys = list(ddict.keys()) ++ if len(keys) == 0: ++ return ++ keys.sort() ++ ++ if heading: ++ print("%-30s %-8s %s\n" % (_("SELinux Port Type"), _("Proto"), _("Port Number"))) ++ for i in keys: ++ rec = "%-30s %-8s " % i ++ rec += "%s" % ddict[i][0] ++ for p in ddict[i][1:]: ++ rec += ", %s" % p ++ print(rec) ++ ++class nodeRecords(semanageRecords): ++ try: ++ valid_types = sepolicy.info(sepolicy.ATTRIBUTE,"node_type")[0]["types"] ++ except RuntimeError: ++ valid_types = [] ++ ++ def __init__(self, store = ""): ++ semanageRecords.__init__(self,store) ++ self.protocol = ["ipv4", "ipv6"] ++ ++ def validate(self, addr, mask, protocol): ++ newaddr=addr ++ newmask=mask ++ newprotocol="" ++ ++ if addr == "": ++ raise ValueError(_("Node Address is required")) ++ ++ # verify valid comination ++ if len(mask) == 0 or mask[0] == "/": ++ i = IP(addr + mask) ++ newaddr = i.strNormal(0) ++ newmask = str(i.netmask()) ++ if newmask == "0.0.0.0" and i.version() == 6: ++ newmask = "::" ++ ++ protocol = "ipv%d" % i.version() ++ ++ try: ++ newprotocol = self.protocol.index(protocol) ++ except: ++ raise ValueError(_("Unknown or missing protocol")) ++ ++ return newaddr, newmask, newprotocol ++ ++ def __add(self, addr, mask, proto, serange, ctype): ++ addr, mask, proto = self.validate(addr, mask, proto) ++ ++ if is_mls_enabled == 1: ++ if serange: ++ serange = untranslate(serange) ++ else: ++ serange = "s0" ++ ++ if ctype == "": ++ raise ValueError(_("SELinux node type is required")) ++ ++ if ctype not in self.valid_types: ++ raise ValueError(_("Type %s is invalid, must be a node type") % ctype) ++ ++ (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) ++ if rc < 0: ++ raise ValueError(_("Could not create key for %s") % addr) ++ if rc < 0: ++ raise ValueError(_("Could not check if addr %s is defined") % addr) ++ ++ (rc, exists) = semanage_node_exists(self.sh, k) ++ if exists: ++ 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: ++ raise ValueError(_("Could not create addr for %s") % addr) ++ semanage_node_set_proto(node, proto) ++ ++ rc = semanage_node_set_addr(self.sh, node, proto, addr) ++ (rc, con) = semanage_context_create(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not create context for %s") % addr) ++ ++ rc = semanage_node_set_mask(self.sh, node, proto, mask) ++ if rc < 0: ++ raise ValueError(_("Could not set mask for %s") % addr) ++ ++ rc = semanage_context_set_user(self.sh, con, "system_u") ++ if rc < 0: ++ raise ValueError(_("Could not set user in addr context for %s") % addr) ++ ++ rc = semanage_context_set_role(self.sh, con, "object_r") ++ if rc < 0: ++ raise ValueError(_("Could not set role in addr context for %s") % addr) ++ ++ rc = semanage_context_set_type(self.sh, con, ctype) ++ if rc < 0: ++ raise ValueError(_("Could not set type in addr context for %s") % addr) ++ ++ if serange: ++ rc = semanage_context_set_mls(self.sh, con, serange) ++ if rc < 0: ++ raise ValueError(_("Could not set mls fields in addr context for %s") % addr) ++ ++ rc = semanage_node_set_con(self.sh, node, con) ++ if rc < 0: ++ raise ValueError(_("Could not set addr context for %s") % addr) ++ ++ rc = semanage_node_modify_local(self.sh, k, node) ++ if rc < 0: ++ raise ValueError(_("Could not add addr %s") % addr) ++ ++ semanage_context_free(con) ++ semanage_node_key_free(k) ++ semanage_node_free(node) ++ ++ def add(self, addr, mask, proto, serange, ctype): ++ self.begin() ++ self.__add(addr, mask, proto, serange, ctype) ++ self.commit() ++ ++ def __modify(self, addr, mask, proto, serange, setype): ++ addr, mask, proto = self.validate(addr, mask, proto) ++ ++ if not serange and setype == "": ++ raise ValueError(_("Requires setype or serange")) ++ ++ if setype and setype not in self.valid_types: ++ raise ValueError(_("Type %s is invalid, must be a node type") % setype) ++ ++ (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) ++ if rc < 0: ++ raise ValueError(_("Could not create key for %s") % addr) ++ ++ (rc, exists) = semanage_node_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if addr %s is defined") % addr) ++ if not exists: ++ raise ValueError(_("Addr %s is not defined") % addr) ++ ++ (rc, node) = semanage_node_query(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not query addr %s") % addr) ++ ++ con = semanage_node_get_con(node) ++ if serange: ++ semanage_context_set_mls(self.sh, con, untranslate(serange)) ++ if setype != "": ++ semanage_context_set_type(self.sh, con, setype) ++ ++ rc = semanage_node_modify_local(self.sh, k, node) ++ if rc < 0: ++ raise ValueError(_("Could not modify addr %s") % addr) ++ ++ semanage_node_key_free(k) ++ semanage_node_free(node) ++ ++ def modify(self, addr, mask, proto, serange, setype): ++ self.begin() ++ self.__modify(addr, mask, proto, serange, setype) ++ self.commit() ++ ++ def __delete(self, addr, mask, proto): ++ ++ addr, mask, proto = self.validate(addr, mask, proto) ++ ++ (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) ++ if rc < 0: ++ raise ValueError(_("Could not create key for %s") % addr) ++ ++ (rc, exists) = semanage_node_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if addr %s is defined") % addr) ++ if not exists: ++ raise ValueError(_("Addr %s is not defined") % addr) ++ ++ (rc, exists) = semanage_node_exists_local(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if addr %s is defined") % addr) ++ if not exists: ++ raise ValueError(_("Addr %s is defined in policy, cannot be deleted") % addr) ++ ++ rc = semanage_node_del_local(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not delete addr %s") % addr) ++ ++ semanage_node_key_free(k) ++ ++ def delete(self, addr, mask, proto): ++ self.begin() ++ self.__delete(addr, mask, proto) ++ self.commit() ++ ++ def deleteall(self): ++ (rc, nlist) = semanage_node_list_local(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not deleteall node mappings")) ++ ++ self.begin() ++ for node in nlist: ++ self.__delete(semanage_node_get_addr(self.sh, node)[1], semanage_node_get_mask(self.sh, node)[1], self.protocol[semanage_node_get_proto(node)]) ++ self.commit() ++ ++ def get_all(self, locallist = False): ++ ddict = {} ++ if locallist : ++ (rc, self.ilist) = semanage_node_list_local(self.sh) ++ else: ++ (rc, self.ilist) = semanage_node_list(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not list addrs")) ++ ++ for node in self.ilist: ++ con = semanage_node_get_con(node) ++ addr = semanage_node_get_addr(self.sh, node) ++ mask = semanage_node_get_mask(self.sh, node) ++ proto = self.protocol[semanage_node_get_proto(node)] ++ ddict[(addr[1], mask[1], proto)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con)) ++ ++ return ddict ++ ++ def customized(self): ++ l = [] ++ ddict = self.get_all(True) ++ keys = list(ddict.keys()) ++ keys.sort() ++ for k in keys: ++ l.append("-a -M %s -p %s -t %s %s" % (k[1], k[2],ddict[k][2], k[0])) ++ return l ++ ++ def list(self, heading = True, locallist = False): ++ ddict = self.get_all(locallist) ++ keys = list(ddict.keys()) ++ if len(keys) == 0: ++ return ++ keys.sort() ++ ++ if heading: ++ print("%-18s %-18s %-5s %-5s\n" % ("IP Address", "Netmask", "Protocol", "Context")) ++ if is_mls_enabled: ++ for k in keys: ++ val = '' ++ for fields in k: ++ val = val + '\t' + str(fields) ++ print("%-18s %-18s %-5s %s:%s:%s:%s " % (k[0],k[1],k[2],ddict[k][0], ddict[k][1],ddict[k][2], translate(ddict[k][3], False))) ++ else: ++ for k in keys: ++ print("%-18s %-18s %-5s %s:%s:%s " % (k[0],k[1],k[2],ddict[k][0], ddict[k][1],ddict[k][2])) ++ ++ ++class interfaceRecords(semanageRecords): + def __init__(self, store = ""): + semanageRecords.__init__(self, store) + + def __add(self, interface, serange, ctype): + if is_mls_enabled == 1: -+ if serange == "": -+ serange = "s0" ++ if serange: ++ serange = untranslate(serange) + else: -+ serange = untranslate(serange) ++ serange = "s0" + + if ctype == "": + raise ValueError(_("SELinux Type is required")) @@ -255743,7 +257465,7 @@ index b3018f3..06c36c5 100644 + if rc < 0: + raise ValueError(_("Could not set type in interface context for %s") % interface) + -+ if serange != "": ++ if serange: + rc = semanage_context_set_mls(self.sh, con, serange) + if rc < 0: + raise ValueError(_("Could not set mls fields in interface context for %s") % interface) @@ -255765,45 +257487,12 @@ index b3018f3..06c36c5 100644 + semanage_iface_free(iface) + + def add(self, interface, serange, ctype): - self.begin() - self.__add(interface, serange, ctype) - self.commit() - -- def __modify(self, interface, serange, setype): -- if serange == "" and setype == "": -- raise ValueError(_("Requires setype or serange")) -- -- (rc, k) = semanage_iface_key_create(self.sh, interface) -- if rc < 0: -- raise ValueError(_("Could not create key for %s") % interface) -- -- (rc, exists) = semanage_iface_exists(self.sh, k) -- if rc < 0: -- raise ValueError(_("Could not check if interface %s is defined") % interface) -- if not exists: -- raise ValueError(_("Interface %s is not defined") % interface) -- -- (rc, iface) = semanage_iface_query(self.sh, k) -- if rc < 0: -- raise ValueError(_("Could not query interface %s") % interface) -- -- con = semanage_iface_get_ifcon(iface) -- -- if serange != "": -- semanage_context_set_mls(self.sh, con, untranslate(serange)) -- if setype != "": -- semanage_context_set_type(self.sh, con, setype) -- -- rc = semanage_iface_modify_local(self.sh, k, iface) -- if rc < 0: -- raise ValueError(_("Could not modify interface %s") % interface) -- -- semanage_iface_key_free(k) -- semanage_iface_free(iface) -- -- def modify(self, interface, serange, setype): ++ self.begin() ++ self.__add(interface, serange, ctype) ++ self.commit() ++ + def __modify(self, interface, serange, setype): -+ if serange == "" and setype == "": ++ if not serange and setype == "": + raise ValueError(_("Requires setype or serange")) + + (rc, k) = semanage_iface_key_create(self.sh, interface) @@ -255822,7 +257511,7 @@ index b3018f3..06c36c5 100644 + + con = semanage_iface_get_ifcon(iface) + -+ if serange != "": ++ if serange: + semanage_context_set_mls(self.sh, con, untranslate(serange)) + if setype != "": + semanage_context_set_type(self.sh, con, setype) @@ -255835,123 +257524,72 @@ index b3018f3..06c36c5 100644 + semanage_iface_free(iface) + + def modify(self, interface, serange, setype): - self.begin() - self.__modify(interface, serange, setype) - self.commit() - -- def __delete(self, interface): -- (rc, k) = semanage_iface_key_create(self.sh, interface) -- if rc < 0: -- raise ValueError(_("Could not create key for %s") % interface) ++ self.begin() ++ self.__modify(interface, serange, setype) ++ self.commit() ++ + def __delete(self, interface): + (rc, k) = semanage_iface_key_create(self.sh, interface) + if rc < 0: + raise ValueError(_("Could not create key for %s") % interface) - -- (rc, exists) = semanage_iface_exists(self.sh, k) -- if rc < 0: -- raise ValueError(_("Could not check if interface %s is defined") % interface) -- if not exists: -- raise ValueError(_("Interface %s is not defined") % interface) ++ + (rc, exists) = semanage_iface_exists(self.sh, k) + if rc < 0: + raise ValueError(_("Could not check if interface %s is defined") % interface) + if not exists: + raise ValueError(_("Interface %s is not defined") % interface) - -- (rc, exists) = semanage_iface_exists_local(self.sh, k) -- if rc < 0: -- raise ValueError(_("Could not check if interface %s is defined") % interface) -- if not exists: -- raise ValueError(_("Interface %s is defined in policy, cannot be deleted") % interface) ++ + (rc, exists) = semanage_iface_exists_local(self.sh, k) + if rc < 0: + raise ValueError(_("Could not check if interface %s is defined") % interface) + if not exists: + raise ValueError(_("Interface %s is defined in policy, cannot be deleted") % interface) - -- rc = semanage_iface_del_local(self.sh, k) -- if rc < 0: -- raise ValueError(_("Could not delete interface %s") % interface) ++ + rc = semanage_iface_del_local(self.sh, k) + if rc < 0: + raise ValueError(_("Could not delete interface %s") % interface) - -- semanage_iface_key_free(k) -+ semanage_iface_key_free(k) - -- def delete(self, interface): -+ def delete(self, interface): - self.begin() - self.__delete(interface) - self.commit() -- + - def deleteall(self): -- (rc, ulist) = semanage_iface_list_local(self.sh) -- if rc < 0: -- raise ValueError(_("Could not delete all interface mappings")) ++ semanage_iface_key_free(k) ++ ++ def delete(self, interface): ++ self.begin() ++ self.__delete(interface) ++ self.commit() ++ ++ def deleteall(self): + (rc, ulist) = semanage_iface_list_local(self.sh) + if rc < 0: + raise ValueError(_("Could not delete all interface mappings")) - - self.begin() -- for i in ulist: -- self.__delete(semanage_iface_get_name(i)) ++ ++ self.begin() + for i in ulist: + self.__delete(semanage_iface_get_name(i)) - self.commit() - -- def get_all(self, locallist = 0): -- ddict = {} ++ self.commit() ++ + def get_all(self, locallist = False): + ddict = {} - if locallist: - (rc, self.ilist) = semanage_iface_list_local(self.sh) - else: - (rc, self.ilist) = semanage_iface_list(self.sh) -- if rc < 0: -- raise ValueError(_("Could not list interfaces")) ++ if locallist: ++ (rc, self.ilist) = semanage_iface_list_local(self.sh) ++ else: ++ (rc, self.ilist) = semanage_iface_list(self.sh) + if rc < 0: + raise ValueError(_("Could not list interfaces")) + + for interface in self.ilist: + con = semanage_iface_get_ifcon(interface) + ddict[semanage_iface_get_name(interface)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con)) - -- for interface in self.ilist: -- con = semanage_iface_get_ifcon(interface) -- ddict[semanage_iface_get_name(interface)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con)) ++ + return ddict - -- return ddict -- - def customized(self): - l = [] - ddict = self.get_all(True) -- keys = ddict.keys() ++ ++ def customized(self): ++ l = [] ++ ddict = self.get_all(True) + keys = list(ddict.keys()) - keys.sort() - for k in keys: - l.append("-a -t %s %s" % (ddict[k][2], k)) - return l - -- def list(self, heading = 1, locallist = 0): -- ddict = self.get_all(locallist) -- keys = ddict.keys() -- if len(keys) == 0: -- return -- keys.sort() -- -- if heading: -- print "%-30s %s\n" % (_("SELinux Interface"), _("Context")) -- if is_mls_enabled: -- for k in keys: -- print "%-30s %s:%s:%s:%s " % (k,ddict[k][0], ddict[k][1],ddict[k][2], translate(ddict[k][3], False)) -- else: -- for k in keys: -- print "%-30s %s:%s:%s " % (k,ddict[k][0], ddict[k][1],ddict[k][2]) -- ++ keys.sort() ++ for k in keys: ++ l.append("-a -t %s %s" % (ddict[k][2], k)) ++ return l ++ + def list(self, heading = True, locallist = False): + ddict = self.get_all(locallist) + keys = list(ddict.keys()) @@ -255968,142 +257606,143 @@ index b3018f3..06c36c5 100644 + for k in keys: + print("%-30s %s:%s:%s " % (k,ddict[k][0], ddict[k][1],ddict[k][2])) + - class fcontextRecords(semanageRecords): -- try: -- valid_types = sepolicy.info(sepolicy.ATTRIBUTE,"file_type")[0]["types"] -- valid_types += sepolicy.info(sepolicy.ATTRIBUTE,"device_node")[0]["types"] ++class fcontextRecords(semanageRecords): + try: + valid_types = sepolicy.info(sepolicy.ATTRIBUTE,"file_type")[0]["types"] + valid_types += sepolicy.info(sepolicy.ATTRIBUTE,"device_node")[0]["types"] - valid_types.append("<>") -- except RuntimeError: -- valid_types = [] ++ valid_types.append("<>") + except RuntimeError: + valid_types = [] - -- def __init__(self, store = ""): -- semanageRecords.__init__(self, store) ++ + def __init__(self, store = ""): + semanageRecords.__init__(self, store) - self.equiv = {} - self.equiv_dist = {} - self.equal_ind = False -@@ -1714,7 +1730,7 @@ class fcontextRecords(semanageRecords): - subs_file = selinux.selinux_file_context_subs_path() - tmpfile = "%s.tmp" % subs_file - fd = open(tmpfile, "w") -- for target in self.equiv.keys(): ++ self.equiv = {} ++ self.equiv_dist = {} ++ self.equal_ind = False ++ try: ++ fd = open(selinux.selinux_file_context_subs_path(), "r") ++ for i in fd.readlines(): ++ i = i.strip() ++ if len(i) == 0: ++ continue ++ if i.startswith("#"): ++ continue ++ target, substitute = i.split() ++ self.equiv[target] = substitute ++ fd.close() ++ except IOError: ++ pass ++ try: ++ fd = open(selinux.selinux_file_context_subs_dist_path(), "r") ++ for i in fd.readlines(): ++ i = i.strip() ++ if len(i) == 0: ++ continue ++ if i.startswith("#"): ++ continue ++ target, substitute = i.split() ++ self.equiv_dist[target] = substitute ++ fd.close() ++ except IOError: ++ pass ++ ++ def commit(self): ++ if self.equal_ind: ++ subs_file = selinux.selinux_file_context_subs_path() ++ tmpfile = "%s.tmp" % subs_file ++ fd = open(tmpfile, "w") + for target in list(self.equiv.keys()): - fd.write("%s %s\n" % (target, self.equiv[target])) - fd.close() - try: -@@ -1723,7 +1739,7 @@ class fcontextRecords(semanageRecords): - pass - os.rename(tmpfile,subs_file) - self.equal_ind = False -- semanageRecords.commit(self) ++ fd.write("%s %s\n" % (target, self.equiv[target])) ++ fd.close() ++ try: ++ os.chmod(tmpfile, os.stat(subs_file)[stat.ST_MODE]) ++ except: ++ pass ++ os.rename(tmpfile,subs_file) ++ self.equal_ind = False + semanageRecords.commit(self) - - def add_equal(self, target, substitute): - self.begin() -@@ -1733,14 +1749,14 @@ class fcontextRecords(semanageRecords): - if substitute != "/" and substitute[-1] == "/": - raise ValueError(_("Substiture %s is not valid. Substitute is not allowed to end with '/'") % substitute ) - -- if target in self.equiv.keys(): ++ ++ def add_equal(self, target, substitute): ++ self.begin() ++ if target != "/" and target[-1] == "/": ++ raise ValueError(_("Target %s is not valid. Target is not allowed to end with '/'") % target ) ++ ++ if substitute != "/" and substitute[-1] == "/": ++ raise ValueError(_("Substiture %s is not valid. Substitute is not allowed to end with '/'") % substitute ) ++ + if target in list(self.equiv.keys()): - raise ValueError(_("Equivalence class for %s already exists") % target) - self.validate(target) - -- for fdict in (self.equiv, self.equiv_dist): -- for i in fdict: -- if i.startswith(target + "/"): -- raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'") % (target, i, fdict[i])) ++ raise ValueError(_("Equivalence class for %s already exists") % target) ++ self.validate(target) ++ + for fdict in (self.equiv, self.equiv_dist): + for i in fdict: + if i.startswith(target + "/"): + raise ValueError(_("File spec %(TARGET)s conflicts with equivalency rule '%(SOURCE)s %(DEST)s'") % {"TARGET": target, "SOURCE": i, "DEST": fdict[i]}) - - self.equiv[target] = substitute - self.equal_ind = True -@@ -1748,7 +1764,7 @@ class fcontextRecords(semanageRecords): - - def modify_equal(self, target, substitute): - self.begin() -- if target not in self.equiv.keys(): ++ ++ self.equiv[target] = substitute ++ self.equal_ind = True ++ self.commit() ++ ++ def modify_equal(self, target, substitute): ++ self.begin() + if target not in list(self.equiv.keys()): - raise ValueError(_("Equivalence class for %s does not exists") % target) - self.equiv[target] = substitute - self.equal_ind = True -@@ -1758,18 +1774,18 @@ class fcontextRecords(semanageRecords): - (rc, con) = semanage_context_create(self.sh) - if rc < 0: - raise ValueError(_("Could not create context for %s") % target) -- if seuser == "": -- seuser = "system_u" ++ raise ValueError(_("Equivalence class for %s does not exists") % target) ++ self.equiv[target] = substitute ++ self.equal_ind = True ++ self.commit() ++ ++ def createcon(self, target, seuser = "system_u"): ++ (rc, con) = semanage_context_create(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not create context for %s") % target) + if seuser == "": + seuser = "system_u" - - rc = semanage_context_set_user(self.sh, con, seuser) - if rc < 0: - raise ValueError(_("Could not set user in file context for %s") % target) -- + - rc = semanage_context_set_role(self.sh, con, "object_r") - if rc < 0: - raise ValueError(_("Could not set role in file context for %s") % target) - -- if is_mls_enabled == 1: ++ rc = semanage_context_set_user(self.sh, con, seuser) ++ if rc < 0: ++ raise ValueError(_("Could not set user in file context for %s") % target) ++ ++ rc = semanage_context_set_role(self.sh, con, "object_r") ++ if rc < 0: ++ raise ValueError(_("Could not set role in file context for %s") % target) ++ + if is_mls_enabled == 1: - rc = semanage_context_set_mls(self.sh, con, "s0") - if rc < 0: - raise ValueError(_("Could not set mls fields in file context for %s") % target) -@@ -1781,14 +1797,14 @@ class fcontextRecords(semanageRecords): - raise ValueError(_("Invalid file specification")) - if target.find(" ") != -1: - raise ValueError(_("File specification can not include spaces")) -- for fdict in (self.equiv, self.equiv_dist): -- for i in fdict: -- if target.startswith(i+"/"): -- t = re.sub(i, fdict[i], target) -- raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'; Try adding '%s' instead") % (target, i, fdict[i], t)) ++ rc = semanage_context_set_mls(self.sh, con, "s0") ++ if rc < 0: ++ raise ValueError(_("Could not set mls fields in file context for %s") % target) ++ ++ return con ++ ++ def validate(self, target): ++ if target == "" or target.find("\n") >= 0: ++ raise ValueError(_("Invalid file specification")) ++ if target.find(" ") != -1: ++ raise ValueError(_("File specification can not include spaces")) + for fdict in (self.equiv, self.equiv_dist): + for i in fdict: + if target.startswith(i+"/"): + t = re.sub(i, fdict[i], target) + raise ValueError(_("File spec %(TARGET)s conflicts with equivalency rule '%(SOURCE)s %(DEST)s'; Try adding '%(DEST1)s' instead") % {"TARGET":target, "SOURCE": i, "DEST":fdict[i], "DEST1": t}) - - -- def __add(self, target, type, ftype = "", serange = "s0", seuser = "system_u"): -+ def __add(self, target, type, ftype = "", serange = "s0", seuser = "system_u"): - self.validate(target) - - if seuser == "": -@@ -1797,36 +1813,37 @@ class fcontextRecords(semanageRecords): - if serange == "": - serange = "s0" - -- if is_mls_enabled == 1: ++ ++ ++ def __add(self, target, type, ftype = "", serange = None, seuser = "system_u"): ++ self.validate(target) ++ ++ if seuser == "": ++ seuser = "system_u" ++ ++ if not serange: ++ serange = "s0" ++ + if is_mls_enabled == 1: - serange = untranslate(serange) -- -- if type == "": -- raise ValueError(_("SELinux Type is required")) - -- if type not in self.valid_types: -- raise ValueError(_("Type %s is invalid, must be a file or device type") % type) ++ serange = untranslate(serange) ++ + if type == "": + raise ValueError(_("SELinux Type is required")) - -- (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) -- if rc < 0: -- raise ValueError(_("Could not create key for %s") % target) ++ + if type not in self.valid_types: + raise ValueError(_("Type %s is invalid, must be a file or device type") % type) - -- (rc, exists) = semanage_fcontext_exists(self.sh, k) -- if rc < 0: -- raise ValueError(_("Could not check if file context for %s is defined") % target) ++ + (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) + if rc < 0: + raise ValueError(_("Could not create key for %s") % target) @@ -256111,197 +257750,142 @@ index b3018f3..06c36c5 100644 + (rc, exists) = semanage_fcontext_exists(self.sh, k) + if rc < 0: + raise ValueError(_("Could not check if file context for %s is defined") % target) - -- if not exists: ++ + if not exists: - (rc, exists) = semanage_fcontext_exists_local(self.sh, k) - if rc < 0: - raise ValueError(_("Could not check if file context for %s is defined") % target) - - if exists: -- raise ValueError(_("File context for %s already defined") % target) ++ (rc, exists) = semanage_fcontext_exists_local(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if file context for %s is defined") % target) ++ ++ if exists: + semanage_fcontext_key_free(k) + return self.__modify(target, type, ftype, serange, seuser) - -- (rc, fcontext) = semanage_fcontext_create(self.sh) -- if rc < 0: -- raise ValueError(_("Could not create file context for %s") % target) -- -- rc = semanage_fcontext_set_expr(self.sh, fcontext, target) ++ + (rc, fcontext) = semanage_fcontext_create(self.sh) + if rc < 0: + raise ValueError(_("Could not create file context for %s") % target) + + rc = semanage_fcontext_set_expr(self.sh, fcontext, target) - if type != "<>": - con = self.createcon(target, seuser) - -@@ -1842,59 +1859,59 @@ class fcontextRecords(semanageRecords): - if rc < 0: - raise ValueError(_("Could not set file context for %s") % target) - -- semanage_fcontext_set_type(fcontext, file_types[ftype]) ++ if type != "<>": ++ con = self.createcon(target, seuser) ++ ++ rc = semanage_context_set_type(self.sh, con, type) ++ if rc < 0: ++ raise ValueError(_("Could not set type in file context for %s") % target) ++ ++ if serange: ++ rc = semanage_context_set_mls(self.sh, con, serange) ++ if rc < 0: ++ raise ValueError(_("Could not set mls fields in file context for %s") % target) ++ rc = semanage_fcontext_set_con(self.sh, fcontext, con) ++ if rc < 0: ++ raise ValueError(_("Could not set file context for %s") % target) ++ + semanage_fcontext_set_type(fcontext, file_types[ftype]) - -- rc = semanage_fcontext_modify_local(self.sh, k, fcontext) -- if rc < 0: -- raise ValueError(_("Could not add file context for %s") % target) ++ + rc = semanage_fcontext_modify_local(self.sh, k, fcontext) + if rc < 0: + raise ValueError(_("Could not add file context for %s") % target) - - if type != "<>": - semanage_context_free(con) -- semanage_fcontext_key_free(k) -- semanage_fcontext_free(fcontext) ++ ++ if type != "<>": ++ semanage_context_free(con) + semanage_fcontext_key_free(k) + semanage_fcontext_free(fcontext) - -- def add(self, target, type, ftype = "", serange = "", seuser = "system_u"): -+ def add(self, target, type, ftype = "", serange = "", seuser = "system_u"): - self.begin() - self.__add(target, type, ftype, serange, seuser) - self.commit() - -- def __modify(self, target, setype, ftype, serange, seuser): -- if serange == "" and setype == "" and seuser == "": -- raise ValueError(_("Requires setype, serange or seuser")) -- if setype and setype not in self.valid_types: -- raise ValueError(_("Type %s is invalid, must be a port type") % setype) ++ ++ def add(self, target, type, ftype = "", serange=None, seuser = "system_u"): ++ self.begin() ++ self.__add(target, type, ftype, serange, seuser) ++ self.commit() ++ + def __modify(self, target, setype, ftype, serange, seuser): -+ if serange == "" and setype == "" and seuser == "": ++ if serange and setype == "" and seuser == "": + raise ValueError(_("Requires setype, serange or seuser")) + if setype and setype not in self.valid_types: + raise ValueError(_("Type %s is invalid, must be a port type") % setype) - - self.validate(target) - -- (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) -- if rc < 0: -- raise ValueError(_("Could not create a key for %s") % target) ++ ++ self.validate(target) ++ + (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) + if rc < 0: + raise ValueError(_("Could not create a key for %s") % target) - -- (rc, exists) = semanage_fcontext_exists(self.sh, k) -- if rc < 0: -- raise ValueError(_("Could not check if file context for %s is defined") % target) -- if not exists: ++ + (rc, exists) = semanage_fcontext_exists(self.sh, k) + if rc < 0: + raise ValueError(_("Could not check if file context for %s is defined") % target) + if not exists: - (rc, exists) = semanage_fcontext_exists_local(self.sh, k) - if not exists: - raise ValueError(_("File context for %s is not defined") % target) -- -- (rc, fcontext) = semanage_fcontext_query_local(self.sh, k) -- if rc < 0: ++ (rc, exists) = semanage_fcontext_exists_local(self.sh, k) ++ if not exists: ++ raise ValueError(_("File context for %s is not defined") % target) + + (rc, fcontext) = semanage_fcontext_query_local(self.sh, k) + if rc < 0: - (rc, fcontext) = semanage_fcontext_query(self.sh, k) - if rc < 0: - raise ValueError(_("Could not query file context for %s") % target) - - if setype != "<>": - con = semanage_fcontext_get_con(fcontext) -- ++ (rc, fcontext) = semanage_fcontext_query(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not query file context for %s") % target) + - if con == None: - con = self.createcon(target) -- ++ if setype != "<>": ++ con = semanage_fcontext_get_con(fcontext) + - if serange != "": - semanage_context_set_mls(self.sh, con, untranslate(serange)) - if seuser != "": - semanage_context_set_user(self.sh, con, seuser) -- ++ if con == None: ++ con = self.createcon(target) ++ ++ if serange: ++ semanage_context_set_mls(self.sh, con, untranslate(serange)) ++ if seuser != "": ++ semanage_context_set_user(self.sh, con, seuser) ++ ++ if setype != "": ++ semanage_context_set_type(self.sh, con, setype) ++ ++ rc = semanage_fcontext_set_con(self.sh, fcontext, con) ++ if rc < 0: ++ raise ValueError(_("Could not set file context for %s") % target) ++ else: ++ rc = semanage_fcontext_set_con(self.sh, fcontext, None) ++ if rc < 0: ++ raise ValueError(_("Could not set file context for %s") % target) + - if setype != "": - semanage_context_set_type(self.sh, con, setype) - -@@ -1905,27 +1922,27 @@ class fcontextRecords(semanageRecords): - rc = semanage_fcontext_set_con(self.sh, fcontext, None) - if rc < 0: - raise ValueError(_("Could not set file context for %s") % target) -- -- rc = semanage_fcontext_modify_local(self.sh, k, fcontext) -- if rc < 0: -- raise ValueError(_("Could not modify file context for %s") % target) - -- semanage_fcontext_key_free(k) -- semanage_fcontext_free(fcontext) + rc = semanage_fcontext_modify_local(self.sh, k, fcontext) + if rc < 0: + raise ValueError(_("Could not modify file context for %s") % target) + + semanage_fcontext_key_free(k) + semanage_fcontext_free(fcontext) - -- def modify(self, target, setype, ftype, serange, seuser): ++ + def modify(self, target, setype, ftype, serange, seuser): - self.begin() - self.__modify(target, setype, ftype, serange, seuser) - self.commit() - -- def deleteall(self): -- (rc, flist) = semanage_fcontext_list_local(self.sh) -- if rc < 0: -- raise ValueError(_("Could not list the file contexts")) ++ self.begin() ++ self.__modify(target, setype, ftype, serange, seuser) ++ self.commit() ++ + def deleteall(self): + (rc, flist) = semanage_fcontext_list_local(self.sh) + if rc < 0: + raise ValueError(_("Could not list the file contexts")) - - self.begin() - -- for fcontext in flist: -+ for fcontext in flist: - target = semanage_fcontext_get_expr(fcontext) - ftype = semanage_fcontext_get_type(fcontext) - ftype_str = semanage_fcontext_get_type_str(ftype) -@@ -1937,45 +1954,45 @@ class fcontextRecords(semanageRecords): - if rc < 0: - raise ValueError(_("Could not delete the file context %s") % target) - semanage_fcontext_key_free(k) -- + - self.equiv = {} - self.equal_ind = True - self.commit() - -- def __delete(self, target, ftype): -- if target in self.equiv.keys(): ++ self.begin() ++ ++ for fcontext in flist: ++ target = semanage_fcontext_get_expr(fcontext) ++ ftype = semanage_fcontext_get_type(fcontext) ++ ftype_str = semanage_fcontext_get_type_str(ftype) ++ (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype_str]) ++ if rc < 0: ++ raise ValueError(_("Could not create a key for %s") % target) ++ ++ rc = semanage_fcontext_del_local(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not delete the file context %s") % target) ++ semanage_fcontext_key_free(k) ++ ++ self.equiv = {} ++ self.equal_ind = True ++ self.commit() ++ + def __delete(self, target, ftype): + if target in list(self.equiv.keys()): - self.equiv.pop(target) - self.equal_ind = True - return - -- (rc,k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) -- if rc < 0: -- raise ValueError(_("Could not create a key for %s") % target) -- -- (rc, exists) = semanage_fcontext_exists_local(self.sh, k) -- if rc < 0: -- raise ValueError(_("Could not check if file context for %s is defined") % target) -- if not exists: -- (rc, exists) = semanage_fcontext_exists(self.sh, k) -- if rc < 0: -- raise ValueError(_("Could not check if file context for %s is defined") % target) -- if exists: -- raise ValueError(_("File context for %s is defined in policy, cannot be deleted") % target) -- else: -- raise ValueError(_("File context for %s is not defined") % target) -- -- rc = semanage_fcontext_del_local(self.sh, k) -- if rc < 0: -- raise ValueError(_("Could not delete file context for %s") % target) -- -- semanage_fcontext_key_free(k) -- -- def delete(self, target, ftype): ++ self.equiv.pop(target) ++ self.equal_ind = True ++ return ++ + (rc,k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) + if rc < 0: + raise ValueError(_("Could not create a key for %s") % target) @@ -256325,82 +257909,51 @@ index b3018f3..06c36c5 100644 + semanage_fcontext_key_free(k) + + def delete(self, target, ftype): - self.begin() - self.__delete( target, ftype) - self.commit() - -- def get_all(self, locallist = 0): ++ self.begin() ++ self.__delete( target, ftype) ++ self.commit() ++ + def get_all(self, locallist = False): - if locallist: - (rc, self.flist) = semanage_fcontext_list_local(self.sh) - else: -@@ -1990,64 +2007,64 @@ class fcontextRecords(semanageRecords): - self.flist += fclocal - - ddict = {} -- for fcontext in self.flist: -- expr = semanage_fcontext_get_expr(fcontext) -- ftype = semanage_fcontext_get_type(fcontext) -- ftype_str = semanage_fcontext_get_type_str(ftype) -- con = semanage_fcontext_get_con(fcontext) -- if con: ++ if locallist: ++ (rc, self.flist) = semanage_fcontext_list_local(self.sh) ++ else: ++ (rc, self.flist) = semanage_fcontext_list(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not list file contexts")) ++ ++ (rc, fclocal) = semanage_fcontext_list_local(self.sh) ++ if rc < 0: ++ raise ValueError(_("Could not list local file contexts")) ++ ++ self.flist += fclocal ++ ++ ddict = {} + for fcontext in self.flist: + expr = semanage_fcontext_get_expr(fcontext) + ftype = semanage_fcontext_get_type(fcontext) + ftype_str = semanage_fcontext_get_type_str(ftype) + con = semanage_fcontext_get_con(fcontext) + if con: - ddict[(expr, ftype_str)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con)) -- else: -- ddict[(expr, ftype_str)] = con ++ ddict[(expr, ftype_str)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con)) + else: + ddict[(expr, ftype_str)] = con + + return ddict - -- return ddict -- - def customized(self): - l = [] - fcon_dict = self.get_all(True) -- keys = fcon_dict.keys() ++ ++ def customized(self): ++ l = [] ++ fcon_dict = self.get_all(True) + keys = list(fcon_dict.keys()) - keys.sort() - for k in keys: - if fcon_dict[k]: - l.append("-a -f %s -t %s '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], k[0])) - -- if len(self.equiv): -- for target in self.equiv.keys(): -- l.append("-a -e %s %s" % (self.equiv[target], target)) ++ keys.sort() ++ for k in keys: ++ if fcon_dict[k]: ++ l.append("-a -f %s -t %s '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], k[0])) ++ + if len(self.equiv): + for target in list(self.equiv.keys()): + l.append("-a -e %s %s" % (self.equiv[target], target)) - return l - -- def list(self, heading = 1, locallist = 0 ): -- fcon_dict = self.get_all(locallist) -- keys = fcon_dict.keys() -- if len(keys) != 0: -- keys.sort() -- if heading: -- print "%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context")) -- for k in keys: -- if fcon_dict[k]: -- if is_mls_enabled: -- print "%-50s %-18s %s:%s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2], translate(fcon_dict[k][3],False)) -- else: -- print "%-50s %-18s %s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1],fcon_dict[k][2]) -- else: -- print "%-50s %-18s <>" % (k[0], k[1]) -- -- if len(self.equiv_dist): -- if not locallist: -- if heading: -- print _("\nSELinux Distribution fcontext Equivalence \n") -- for target in self.equiv_dist.keys(): -- print "%s = %s" % (target, self.equiv_dist[target]) -- if len(self.equiv): ++ return l ++ + def list(self, heading = True, locallist = False ): + fcon_dict = self.get_all(locallist) + keys = list(fcon_dict.keys()) @@ -256424,39 +257977,23 @@ index b3018f3..06c36c5 100644 + for target in list(self.equiv_dist.keys()): + print("%s = %s" % (target, self.equiv_dist[target])) + if len(self.equiv): - if heading: -- print _("\nSELinux Local fcontext Equivalence \n") ++ if heading: + print(_("\nSELinux Local fcontext Equivalence \n")) + + for target in list(self.equiv.keys()): + print("%s = %s" % (target, self.equiv[target])) - -- for target in self.equiv.keys(): -- print "%s = %s" % (target, self.equiv[target]) -- - class booleanRecords(semanageRecords): -- def __init__(self, store = ""): -- semanageRecords.__init__(self, store) ++ ++class booleanRecords(semanageRecords): + def __init__(self, store = ""): + semanageRecords.__init__(self, store) - self.dict = {} - self.dict["TRUE"] = 1 - self.dict["FALSE"] = 0 -@@ -2056,19 +2073,19 @@ class booleanRecords(semanageRecords): - self.dict["1"] = 1 - self.dict["0"] = 0 - -- try: -- rc, self.current_booleans = selinux.security_get_boolean_names() -- rc, ptype = selinux.selinux_getpolicytype() -- except: -- self.current_booleans = [] -- ptype = None -- -- if self.store == None or self.store == ptype: -- self.modify_local = True -- else: -- self.modify_local = False ++ self.dict = {} ++ self.dict["TRUE"] = 1 ++ self.dict["FALSE"] = 0 ++ self.dict["ON"] = 1 ++ self.dict["OFF"] = 0 ++ self.dict["1"] = 1 ++ self.dict["0"] = 0 ++ + try: + rc, self.current_booleans = selinux.security_get_boolean_names() + rc, ptype = selinux.selinux_getpolicytype() @@ -256468,92 +258005,64 @@ index b3018f3..06c36c5 100644 + self.modify_local = True + else: + self.modify_local = False - -- def __mod(self, name, value): ++ + def __mod(self, name, value): - name = selinux.selinux_boolean_sub(name) - - (rc, k) = semanage_bool_key_create(self.sh, name) -@@ -2078,8 +2095,8 @@ class booleanRecords(semanageRecords): - if rc < 0: - raise ValueError(_("Could not check if boolean %s is defined") % name) - if not exists: -- raise ValueError(_("Boolean %s is not defined") % name) -- ++ name = selinux.selinux_boolean_sub(name) ++ ++ (rc, k) = semanage_bool_key_create(self.sh, name) ++ if rc < 0: ++ raise ValueError(_("Could not create a key for %s") % name) ++ (rc, exists) = semanage_bool_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if boolean %s is defined") % name) ++ if not exists: + raise ValueError(_("Boolean %s is not defined") % name) + - (rc, b) = semanage_bool_query(self.sh, k) - if rc < 0: - raise ValueError(_("Could not query file context %s") % name) -@@ -2087,19 +2104,19 @@ class booleanRecords(semanageRecords): - if value.upper() in self.dict: - semanage_bool_set_value(b, self.dict[value.upper()]) - else: -- raise ValueError(_("You must specify one of the following values: %s") % ", ".join(self.dict.keys()) ) -- -- if self.modify_local and name in self.current_booleans: -- rc = semanage_bool_set_active(self.sh, k, b) -- if rc < 0: -- raise ValueError(_("Could not set active value of boolean %s") % name) ++ (rc, b) = semanage_bool_query(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not query file context %s") % name) ++ ++ if value.upper() in self.dict: ++ semanage_bool_set_value(b, self.dict[value.upper()]) ++ else: + raise ValueError(_("You must specify one of the following values: %s") % ", ".join(list(self.dict.keys())) ) + + if self.modify_local and name in self.current_booleans: + rc = semanage_bool_set_active(self.sh, k, b) + if rc < 0: + raise ValueError(_("Could not set active value of boolean %s") % name) - rc = semanage_bool_modify_local(self.sh, k, b) - if rc < 0: - raise ValueError(_("Could not modify boolean %s") % name) -- semanage_bool_key_free(k) -- semanage_bool_free(b) ++ rc = semanage_bool_modify_local(self.sh, k, b) ++ if rc < 0: ++ raise ValueError(_("Could not modify boolean %s") % name) + semanage_bool_key_free(k) + semanage_bool_free(b) - -- def modify(self, name, value = None, use_file = False): ++ + def modify(self, name, value = None, use_file = False): - self.begin() - if use_file: - fd = open(name) -@@ -2111,113 +2128,113 @@ class booleanRecords(semanageRecords): - try: - boolname, val = b.split("=") - except ValueError: -- raise ValueError(_("Bad format %s: Record %s" % ( name, b) )) ++ self.begin() ++ if use_file: ++ fd = open(name) ++ for b in fd.read().split("\n"): ++ b = b.strip() ++ if len(b) == 0: ++ continue ++ ++ try: ++ boolname, val = b.split("=") ++ except ValueError: + raise ValueError(_("Bad format %(BOOLNAME)s: Record %(VALUE)s" % { "BOOLNAME": name, "VALUE": b } )) - self.__mod(boolname.strip(), val.strip()) - fd.close() - else: - self.__mod(name, value) - - self.commit() -- -- def __delete(self, name): ++ self.__mod(boolname.strip(), val.strip()) ++ fd.close() ++ else: ++ self.__mod(name, value) ++ ++ self.commit() + + def __delete(self, name): - name = selinux.selinux_boolean_sub(name) - - (rc, k) = semanage_bool_key_create(self.sh, name) - if rc < 0: - raise ValueError(_("Could not create a key for %s") % name) -- (rc, exists) = semanage_bool_exists(self.sh, k) -- if rc < 0: -- raise ValueError(_("Could not check if boolean %s is defined") % name) -- if not exists: -- raise ValueError(_("Boolean %s is not defined") % name) -- -- (rc, exists) = semanage_bool_exists_local(self.sh, k) -- if rc < 0: -- raise ValueError(_("Could not check if boolean %s is defined") % name) -- if not exists: -- raise ValueError(_("Boolean %s is defined in policy, cannot be deleted") % name) -- -- rc = semanage_bool_del_local(self.sh, k) -- if rc < 0: -- raise ValueError(_("Could not delete boolean %s") % name) -- -- semanage_bool_key_free(k) -- -- def delete(self, name): ++ name = selinux.selinux_boolean_sub(name) ++ ++ (rc, k) = semanage_bool_key_create(self.sh, name) ++ if rc < 0: ++ raise ValueError(_("Could not create a key for %s") % name) + (rc, exists) = semanage_bool_exists(self.sh, k) + if rc < 0: + raise ValueError(_("Could not check if boolean %s is defined") % name) @@ -256573,112 +258082,73 @@ index b3018f3..06c36c5 100644 + semanage_bool_key_free(k) + + def delete(self, name): - self.begin() - self.__delete(name) - self.commit() - -- def deleteall(self): -- (rc, self.blist) = semanage_bool_list_local(self.sh) -- if rc < 0: -- raise ValueError(_("Could not list booleans")) ++ self.begin() ++ self.__delete(name) ++ self.commit() ++ + def deleteall(self): + (rc, self.blist) = semanage_bool_list_local(self.sh) + if rc < 0: + raise ValueError(_("Could not list booleans")) - - self.begin() - -- for boolean in self.blist: ++ ++ self.begin() ++ + for boolean in self.blist: - name = semanage_bool_get_name(boolean) - self.__delete(name) - - self.commit() -- -- def get_all(self, locallist = 0): -- ddict = {} ++ name = semanage_bool_get_name(boolean) ++ self.__delete(name) ++ ++ self.commit() + + def get_all(self, locallist = False): + ddict = {} - if locallist: - (rc, self.blist) = semanage_bool_list_local(self.sh) - else: - (rc, self.blist) = semanage_bool_list(self.sh) -- if rc < 0: -- raise ValueError(_("Could not list booleans")) ++ if locallist: ++ (rc, self.blist) = semanage_bool_list_local(self.sh) ++ else: ++ (rc, self.blist) = semanage_bool_list(self.sh) + if rc < 0: + raise ValueError(_("Could not list booleans")) - -- for boolean in self.blist: ++ + for boolean in self.blist: - value = [] - name = semanage_bool_get_name(boolean) - value.append(semanage_bool_get_value(boolean)) -- if self.modify_local and boolean in self.current_booleans: -- value.append(selinux.security_get_boolean_pending(name)) -- value.append(selinux.security_get_boolean_active(name)) -- else: -- value.append(value[0]) -- value.append(value[0]) ++ value = [] ++ name = semanage_bool_get_name(boolean) ++ value.append(semanage_bool_get_value(boolean)) + if self.modify_local and boolean in self.current_booleans: + value.append(selinux.security_get_boolean_pending(name)) + value.append(selinux.security_get_boolean_active(name)) + else: + value.append(value[0]) + value.append(value[0]) - ddict[name] = value - -- return ddict -- ++ ddict[name] = value ++ + return ddict + - def get_desc(self, name): -- name = selinux.selinux_boolean_sub(name) -- return boolean_desc(name) ++ def get_desc(self, name): + name = selinux.selinux_boolean_sub(name) + return boolean_desc(name) - - def get_category(self, name): -- name = selinux.selinux_boolean_sub(name) -- return boolean_category(name) ++ ++ def get_category(self, name): + name = selinux.selinux_boolean_sub(name) + return boolean_category(name) - - def customized(self): - l = [] - ddict = self.get_all(True) -- keys = ddict.keys() ++ ++ def customized(self): ++ l = [] ++ ddict = self.get_all(True) + keys = list(ddict.keys()) - keys.sort() - for k in keys: - if ddict[k]: - l.append("-m -%s %s" % (ddict[k][2], k)) - return l - -- def list(self, heading = True, locallist = False, use_file = False): -- on_off = (_("off"), _("on")) -- if use_file: ++ keys.sort() ++ for k in keys: ++ if ddict[k]: ++ l.append("-m -%s %s" % (ddict[k][2], k)) ++ return l ++ + def list(self, heading = True, locallist = False, use_file = False): + on_off = (_("off"), _("on")) + if use_file: - ddict = self.get_all(locallist) -- keys = ddict.keys() ++ ddict = self.get_all(locallist) + keys = list(ddict.keys()) - for k in keys: - if ddict[k]: -- print "%s=%s" % (k, ddict[k][2]) ++ for k in keys: ++ if ddict[k]: + print("%s=%s" % (k, ddict[k][2])) - return -- ddict = self.get_all(locallist) -- keys = ddict.keys() -- if len(keys) == 0: -- return -- -- if heading: -- print "%-30s %s %s %s\n" % (_("SELinux boolean"),_("State"), _("Default"), _("Description")) -- for k in keys: -- if ddict[k]: -- print "%-30s (%-5s,%5s) %s" % (k, on_off[selinux.security_get_boolean_active(k)], on_off[ddict[k][2]], self.get_desc(k)) ++ return + ddict = self.get_all(locallist) + keys = list(ddict.keys()) + if len(keys) == 0: @@ -256689,8 +258159,90 @@ index b3018f3..06c36c5 100644 + for k in keys: + if ddict[k]: + print("%-30s (%-5s,%5s) %s" % (k, on_off[selinux.security_get_boolean_active(k)], on_off[ddict[k][2]], self.get_desc(k))) +diff --git a/policycoreutils/semanage/setup.py b/policycoreutils/semanage/setup.py +new file mode 100644 +index 0000000..7735c59 +--- /dev/null ++++ b/policycoreutils/semanage/setup.py +@@ -0,0 +1,35 @@ ++# Authors: ++# Dan Walsh ++# ++# Copyright (C) 2013 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 ++ ++setup(name = 'seobject', ++ version = '0.1', ++ description = 'python bindings used by semanage and system-config-selinux', ++ long_description = 'python bindings used by semanage and system-config-selinux', ++ author = 'Dan Walsh', ++ author_email = 'dwalsh@redhat.com', ++ maintainer = 'Dan Walsh', ++ maintainer_email = 'dwalsh@redhat.com', ++ license = 'GPLv2+', ++ platforms = 'posix', ++ url = '', ++ download_url = '', ++ packages=["seobject"], ++) +diff --git a/policycoreutils/semanage/test-semanage.py b/policycoreutils/semanage/test-semanage.py +index d39013e..e847ca7 100644 +--- a/policycoreutils/semanage/test-semanage.py ++++ b/policycoreutils/semanage/test-semanage.py +@@ -9,18 +9,18 @@ object_list = [ 'login', 'user', 'port', 'module', 'interface', 'node', 'fcontex + class SemanageTests(unittest.TestCase): + def assertDenied(self, err): + self.assertTrue('Permission denied' in err, +- '"Permission denied" not found in %r' % err) ++ '"Permission denied" not found in %r' % err) + def assertNotFound(self, err): + self.assertTrue('not found' in err, +- '"not found" not found in %r' % err) ++ '"not found" not found in %r' % err) + + def assertFailure(self, status): + self.assertTrue(status != 0, +- '"semanage succeeded when it should have failed') ++ '"semanage succeeded when it should have failed') + + def assertSuccess(self, status, err): + self.assertTrue(status == 0, +- '"semanage should have succeeded for this test %r' % err) ++ '"semanage should have succeeded for this test %r' % err) + + def test_extract(self): + for object in object_list: +diff --git a/policycoreutils/semodule/semodule.8 b/policycoreutils/semodule/semodule.8 +index 35277e9..2a91697 100644 +--- a/policycoreutils/semodule/semodule.8 ++++ b/policycoreutils/semodule/semodule.8 +@@ -59,6 +59,9 @@ do not reload policy after commit + .B \-h,\-\-help + prints help message and quit + .TP ++.B \-P,\-\-preserve_tunables ++Preserve tunables in policy ++.TP + .B \-v,\-\-verbose + be verbose + diff --git a/policycoreutils/sepolicy/Makefile b/policycoreutils/sepolicy/Makefile -index 2b8716c..49fe070 100644 +index 2b8716c..d08f34c 100644 --- a/policycoreutils/sepolicy/Makefile +++ b/policycoreutils/sepolicy/Makefile @@ -27,7 +27,7 @@ sepolgen: @@ -256702,6 +258254,19 @@ index 2b8716c..49fe070 100644 install: $(PYTHON) setup.py install `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` +@@ -47,6 +47,11 @@ install: + -mkdir -p $(DESTDIR)/usr/share/system-config-selinux + install -m 755 selinux_server.py $(DESTDIR)/usr/share/system-config-selinux + install -m 644 *.desktop $(DATADIR)/system-config-selinux ++ -mkdir -p $(DESTDIR) $(DATADIR)/pixmaps ++ install -m 644 sepolicy_256.png $(DATADIR)/pixmaps/sepolicy.png ++ for i in 16 22 32 48 256; do \ ++ mkdir -p $(DESTDIR) $(DATADIR)/icons/hicolor/$${i}x$${i}/apps; \ ++ install -m 644 sepolicy_$${i}.png $(DATADIR)/icons/hicolor/$${i}x$${i}/apps/sepolicy.png; \ ++ done + + relabel: +- diff --git a/policycoreutils/sepolicy/common.h b/policycoreutils/sepolicy/common.h index dc3ce6a..3b93845 100644 --- a/policycoreutils/sepolicy/common.h @@ -257307,6 +258872,100 @@ index cd1026a..ac44dfe 100644 + PyModule_AddIntConstant(m, "SENS", SENS); + PyModule_AddIntConstant(m, "CATS", CATS); } +diff --git a/policycoreutils/sepolicy/org.selinux.policy b/policycoreutils/sepolicy/org.selinux.policy +index c0a730c..44ae625 100644 +--- a/policycoreutils/sepolicy/org.selinux.policy ++++ b/policycoreutils/sepolicy/org.selinux.policy +@@ -11,8 +11,8 @@ + SELinux write access + System policy prevents restorecon access to SELinux + +- auth_admin_keep +- auth_admin_keep ++ no ++ no + auth_admin_keep + + +@@ -20,8 +20,8 @@ + SELinux write access + System policy prevents setenforce access to SELinux + +- auth_admin_keep +- auth_admin_keep ++ no ++ no + auth_admin_keep + + +@@ -29,8 +29,8 @@ + SELinux write access + System policy prevents semanage access to SELinux + +- auth_admin_keep +- auth_admin_keep ++ no ++ no + auth_admin_keep + + +@@ -38,8 +38,8 @@ + SELinux Read access + System policy prevents read access to SELinux + +- yes +- yes ++ no ++ no + yes + + +@@ -47,8 +47,8 @@ + SELinux list modules access + System policy prevents read access to SELinux modules + +- yes +- yes ++ no ++ no + yes + + +@@ -56,25 +56,27 @@ + SELinux write access + System policy prevents relabel_on_boot access to SELinux + +- yes ++ no ++ no ++ auth_admin_keep + + + + SELinux write access + System policy prevents change_default_policy access to SELinux + +- auth_admin_keep +- auth_admin_keep +- auth_admin_keep ++ no ++ no ++ auth_admin_keep + + + + SELinux write access + System policy prevents change_policy_type access to SELinux + +- auth_admin_keep +- auth_admin_keep +- auth_admin_keep ++ no ++ no ++ auth_admin_keep + + + diff --git a/policycoreutils/sepolicy/policy.c b/policycoreutils/sepolicy/policy.c index 2a9e1c7..365e622 100644 --- a/policycoreutils/sepolicy/policy.c @@ -257463,18 +259122,9 @@ index 2a9e1c7..365e622 100644 +#endif } diff --git a/policycoreutils/sepolicy/search.c b/policycoreutils/sepolicy/search.c -index d9a5aec..b24ef52 100644 +index d9a5aec..513eba8 100644 --- a/policycoreutils/sepolicy/search.c +++ b/policycoreutils/sepolicy/search.c -@@ -8,7 +8,7 @@ - * @author Dan Walsh - * Copyright (C) 2012-2013 Red Hat, inc - * -- * Sections copied from sesearch.c in setools package -+ * Sections copied from seinfo.c in setools package - * @author Frank Mayer mayerf@tresys.com - * @author Jeremy A. Mowery jmowery@tresys.com - * @author Paul Rosenfeld prosenfeld@tresys.com @@ -189,7 +189,7 @@ static PyObject* get_ra_results(const apol_policy_t * policy, const apol_vector_ if (qpol_role_get_name(q, role, &tmp)) { goto err; @@ -257502,7 +259152,7 @@ index d9a5aec..b24ef52 100644 if (!obj) goto err; if (py_append_obj(boollist, obj)) goto err; -@@ -341,13 +341,13 @@ static PyObject* get_bool(const qpol_policy_t *q, const qpol_cond_t * cond, int +@@ -341,7 +341,7 @@ static PyObject* get_bool(const qpol_policy_t *q, const qpol_cond_t * cond, int if (qpol_bool_get_name(q, cond_bool, &bool_name)) { goto err; } @@ -257511,13 +259161,6 @@ index d9a5aec..b24ef52 100644 if (py_tuple_insert_obj(tuple, 0, obj)) goto err; obj = PyBool_FromLong(enabled); - if (py_tuple_insert_obj(tuple, 1, obj)) - goto err; -- if (py_append_obj(boollist, tuple)) -+ if (py_append_obj(boollist, tuple)) - goto err; - tuple=NULL; - } @@ -994,14 +994,14 @@ PyObject* search(bool allow, static int Dict_ContainsInt(PyObject *dict, const char *key){ PyObject *item = PyDict_GetItemString(dict, key); @@ -257558,7 +259201,7 @@ index 458a4d2..b6088af 100644 + except dbus.DBusException as e: + print(e) diff --git a/policycoreutils/sepolicy/selinux_server.py b/policycoreutils/sepolicy/selinux_server.py -index 98dbff4..e5d3103 100644 +index 98dbff4..3cfdc94 100644 --- a/policycoreutils/sepolicy/selinux_server.py +++ b/policycoreutils/sepolicy/selinux_server.py @@ -18,7 +18,7 @@ class selinux_server(slip.dbus.service.Object): @@ -257583,7 +259226,7 @@ index 98dbff4..e5d3103 100644 # another server to make the two systems have duplicate policy. # @slip.dbus.polkit.require_auth("org.selinux.customized") -@@ -42,7 +42,7 @@ class selinux_server(slip.dbus.service.Object): +@@ -42,12 +42,12 @@ class selinux_server(slip.dbus.service.Object): if p.returncode and p.returncode != 0: raise OSError("Failed to read SELinux configuration: %s", output) return buf @@ -257592,7 +259235,13 @@ index 98dbff4..e5d3103 100644 # # The semodule_list method will return the output of semodule -l, using the customized polkit, # since this is a readonly behaviour -@@ -56,7 +56,7 @@ class selinux_server(slip.dbus.service.Object): + # +- @slip.dbus.polkit.require_auth("org.selinux.customized") ++ @slip.dbus.polkit.require_auth("org.selinux.semodule_list") + @dbus.service.method("org.selinux", in_signature='', out_signature='s') + def semodule_list(self): + p = Popen(["/usr/sbin/semodule", "-l"],stdout=PIPE, stderr=PIPE) +@@ -56,10 +56,11 @@ class selinux_server(slip.dbus.service.Object): if p.returncode and p.returncode != 0: raise OSError("Failed to list SELinux modules: %s", output) return buf @@ -257601,7 +259250,27 @@ index 98dbff4..e5d3103 100644 # # The restorecon method modifies any file path to the default system label # -@@ -83,7 +83,7 @@ class selinux_server(slip.dbus.service.Object): ++ @slip.dbus.polkit.require_auth("org.selinux.restorecon") + @dbus.service.method("org.selinux", in_signature='s') + def restorecon(self, path): + selinux.restorecon(str(path), recursive=1) +@@ -67,6 +68,7 @@ class selinux_server(slip.dbus.service.Object): + # + # The setenforce method turns off the current enforcement of SELinux + # ++ @slip.dbus.polkit.require_auth("org.selinux.setenforce") + @dbus.service.method("org.selinux", in_signature='i') + def setenforce(self, value): + selinux.security_setenforce(value) +@@ -74,6 +76,7 @@ class selinux_server(slip.dbus.service.Object): + # + # The setenforce method turns off the current enforcement of SELinux + # ++ @slip.dbus.polkit.require_auth("org.selinux.relabel_on_boot") + @dbus.service.method("org.selinux", in_signature='i') + def relabel_on_boot(self, value): + if value == 1: +@@ -83,7 +86,7 @@ class selinux_server(slip.dbus.service.Object): os.unlink("/.autorelabel") def write_selinux_config(self, enforcing=None, policy=None): @@ -257610,16 +259279,17 @@ index 98dbff4..e5d3103 100644 backup_path = path + ".bck" fd = open(path) lines = fd.readlines() -@@ -101,7 +101,7 @@ class selinux_server(slip.dbus.service.Object): +@@ -101,26 +104,28 @@ class selinux_server(slip.dbus.service.Object): os.rename(backup_path, path) # - # The change_default_enforcement modifies the current enforcement mode + # The change_default_enforcement modifies the current enforcement mode # ++ @slip.dbus.polkit.require_auth("org.selinux.change_default_mode") @dbus.service.method("org.selinux", in_signature='s') def change_default_mode(self, value): -@@ -109,7 +109,7 @@ class selinux_server(slip.dbus.service.Object): + values = [ "enforcing", "permissive", "disabled" ] if value not in values: raise ValueError("Enforcement mode must be %s" % ", ".join(values)) self.write_selinux_config(enforcing=value) @@ -257628,7 +259298,11 @@ index 98dbff4..e5d3103 100644 # # The change_default_policy method modifies the policy type -@@ -120,7 +120,7 @@ class selinux_server(slip.dbus.service.Object): + # ++ @slip.dbus.polkit.require_auth("org.selinux.change_default_policy") + @dbus.service.method("org.selinux", in_signature='s') + def change_default_policy(self, value): + path = selinux.selinux_path() + value if os.path.isdir(path): return self.write_selinux_config(policy=value) raise ValueError("%s does not exist" % path) @@ -257637,6 +259311,75 @@ index 98dbff4..e5d3103 100644 if __name__ == "__main__": mainloop = gobject.MainLoop() dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) +diff --git a/policycoreutils/sepolicy/sepolicy-bash-completion.sh b/policycoreutils/sepolicy/sepolicy-bash-completion.sh +index 779fd75..29ccbdf 100644 +--- a/policycoreutils/sepolicy/sepolicy-bash-completion.sh ++++ b/policycoreutils/sepolicy/sepolicy-bash-completion.sh +@@ -16,9 +16,9 @@ + # along with systemd; If not, see . + + __contains_word () { +- local word=$1; shift +- for w in $*; do [[ $w = $word ]] && return 0; done +- return 1 ++ local word=$1; shift ++ for w in $*; do [[ $w = $word ]] && return 0; done ++ return 1 + } + + __get_all_paths () { +@@ -28,37 +28,40 @@ __get_all_ftypes () { + echo '-- -d -c -b -s -l -p' + } + __get_all_networks () { +- seinfo -u 2> /dev/null | tail -n +3 ++ /usr/bin/seinfo -u 2> /dev/null | tail -n +3 + } + __get_all_booleans () { +- getsebool -a 2> /dev/null ++ /usr/bin/getsebool -a 2> /dev/null + } + __get_all_types () { +- seinfo -t 2> /dev/null | tail -n +3 ++ /usr/bin/seinfo -t 2> /dev/null | tail -n +3 ++} ++__get_all_roles () { ++ /usr/bin/seinfo -r 2> /dev/null | tail -n +3 + } + __get_all_admin_interaces () { +- awk '/InterfaceVector.*_admin /{ print $2 }' /var/lib/sepolgen/interface_info | awk -F '_admin' '{ print $1 }' ++ /usr/bin/awk '/InterfaceVector.*_admin /{ print $2 }' /var/lib/sepolgen/interface_info | /usr/bin/awk -F '_admin' '{ print $1 }' + } + __get_all_user_role_interaces () { +- awk '/InterfaceVector.*_role /{ print $2 }' /var/lib/sepolgen/interface_info | awk -F '_role' '{ print $1 }' ++ /usr/bin/awk '/InterfaceVector.*_role /{ print $2 }' /var/lib/sepolgen/interface_info | /usr/bin/awk -F '_role' '{ print $1 }' + } + __get_all_user_domains () { +- seinfo -auserdomain -x 2> /dev/null | tail -n +2 ++ /usr/bin/seinfo -auserdomain -x 2> /dev/null | tail -n +2 + } + __get_all_users () { +- seinfo -u 2> /dev/null | tail -n +2 ++ /usr/bin/seinfo -u 2> /dev/null | tail -n +2 + } + __get_all_classes () { +- seinfo -c 2> /dev/null | tail -n +2 ++ /usr/bin/seinfo -c 2> /dev/null | tail -n +2 + } + __get_all_port_types () { +- seinfo -aport_type -x 2> /dev/null | tail -n +2 ++ /usr/bin/seinfo -aport_type -x 2> /dev/null | tail -n +2 + } + __get_all_domain_types () { +- seinfo -adomain -x 2> /dev/null | tail -n +2 ++ /usr/bin/seinfo -adomain -x 2> /dev/null | tail -n +2 + } + __get_all_domains () { +- seinfo -adomain -x 2>/dev/null | sed 's/_t$//g' ++ /usr/bin/seinfo -adomain -x 2>/dev/null | sed 's/_t$//g' + } + _sepolicy () { + local command=${COMP_WORDS[1]} diff --git a/policycoreutils/sepolicy/sepolicy.py b/policycoreutils/sepolicy/sepolicy.py index 74fb347..adb6ca5 100755 --- a/policycoreutils/sepolicy/sepolicy.py @@ -257916,7 +259659,7 @@ index 74fb347..adb6ca5 100755 + print("Out") sys.exit(0) diff --git a/policycoreutils/sepolicy/sepolicy/__init__.py b/policycoreutils/sepolicy/sepolicy/__init__.py -index fd95c16..1f9cab9 100644 +index fd95c16..e7607fd 100644 --- a/policycoreutils/sepolicy/sepolicy/__init__.py +++ b/policycoreutils/sepolicy/sepolicy/__init__.py @@ -3,7 +3,7 @@ @@ -257986,7 +259729,17 @@ index fd95c16..1f9cab9 100644 def get_types_from_attribute(attribute): return info(ATTRIBUTE,attribute)[0]["types"] -@@ -166,7 +171,7 @@ def find_file(reg): +@@ -141,6 +146,9 @@ def get_writable_files(setype): + for i in permlist: + if i['target'] in attributes: + continue ++ if "enabled" in i: ++ if not i["enabled"]: ++ continue + if i['target'].endswith("_t"): + if i['target'] not in file_types: + continue +@@ -166,7 +174,7 @@ def find_file(reg): try: pat = re.compile(r"%s$" % reg) except: @@ -257995,7 +259748,7 @@ index fd95c16..1f9cab9 100644 return [] p = reg if p.endswith("(/.*)?"): -@@ -178,19 +183,19 @@ def find_file(reg): +@@ -178,19 +186,19 @@ def find_file(reg): if path[-1] != "/": # is pass in it breaks without try block path += "/" except IndexError: @@ -258018,7 +259771,7 @@ index fd95c16..1f9cab9 100644 if exe.endswith("_exec_t") and exe not in exclude_list: for path in executable_files[exe]: for f in find_file(path): -@@ -218,7 +223,7 @@ def read_file_equiv(edict, fc_path, modify): +@@ -218,7 +226,7 @@ def read_file_equiv(edict, fc_path, modify): f = e.split() edict[f[0]] = { "equiv" : f[1], "modify" : modify } return edict @@ -258027,7 +259780,7 @@ index fd95c16..1f9cab9 100644 file_equiv_modified=None def get_file_equiv_modified(fc_path = selinux.selinux_file_context_path()): global file_equiv_modified -@@ -236,7 +241,7 @@ def get_file_equiv(fc_path = selinux.selinux_file_context_path()): +@@ -236,7 +244,7 @@ def get_file_equiv(fc_path = selinux.selinux_file_context_path()): file_equiv = get_file_equiv_modified(fc_path) file_equiv = read_file_equiv(file_equiv, fc_path + ".subs_dist", modify = False) return file_equiv @@ -258036,7 +259789,7 @@ index fd95c16..1f9cab9 100644 local_files=None def get_local_file_paths(fc_path = selinux.selinux_file_context_path()): global local_files -@@ -306,7 +311,7 @@ def get_fcdict(fc_path = selinux.selinux_file_context_path()): +@@ -306,7 +314,7 @@ def get_fcdict(fc_path = selinux.selinux_file_context_path()): def get_transitions_into(setype): try: @@ -258045,7 +259798,7 @@ index fd95c16..1f9cab9 100644 except TypeError: pass return None -@@ -320,7 +325,7 @@ def get_transitions(setype): +@@ -320,7 +328,7 @@ def get_transitions(setype): def get_file_transitions(setype): try: @@ -258054,7 +259807,7 @@ index fd95c16..1f9cab9 100644 except TypeError: pass return None -@@ -344,7 +349,7 @@ def get_all_entrypoints(): +@@ -344,7 +352,7 @@ def get_all_entrypoints(): def get_entrypoint_types(setype): entrypoints = [] try: @@ -258063,7 +259816,7 @@ index fd95c16..1f9cab9 100644 except TypeError: pass return entrypoints -@@ -352,7 +357,7 @@ def get_entrypoint_types(setype): +@@ -352,7 +360,7 @@ def get_entrypoint_types(setype): def get_init_transtype(path): entrypoint = selinux.getfilecon(path)[1].split(":")[2] try: @@ -258072,7 +259825,7 @@ index fd95c16..1f9cab9 100644 if len(entrypoints) == 0: return None return entrypoints[0]["transtype"] -@@ -362,7 +367,7 @@ def get_init_transtype(path): +@@ -362,7 +370,7 @@ def get_init_transtype(path): def get_init_entrypoint(transtype): try: @@ -258081,7 +259834,7 @@ index fd95c16..1f9cab9 100644 if len(entrypoints) == 0: return None return entrypoints[0]["target"] -@@ -372,7 +377,7 @@ def get_init_entrypoint(transtype): +@@ -372,7 +380,7 @@ def get_init_entrypoint(transtype): def get_init_entrypoint_target(entrypoint): try: @@ -258090,7 +259843,7 @@ index fd95c16..1f9cab9 100644 return entrypoints[0] except TypeError: pass -@@ -410,7 +415,7 @@ def get_methods(): +@@ -410,7 +418,7 @@ def get_methods(): # List of per_role_template interfaces ifs = interfaces.InterfaceSet() ifs.from_file(fd) @@ -258099,7 +259852,7 @@ index fd95c16..1f9cab9 100644 fd.close() except: sys.stderr.write("could not open interface info [%s]\n" % fn) -@@ -423,7 +428,7 @@ all_types = None +@@ -423,7 +431,7 @@ all_types = None def get_all_types(): global all_types if all_types == None: @@ -258108,7 +259861,7 @@ index fd95c16..1f9cab9 100644 return all_types user_types = None -@@ -465,7 +470,7 @@ portrecs = None +@@ -465,7 +473,7 @@ portrecs = None portrecsbynum = None def gen_interfaces(): @@ -258117,7 +259870,7 @@ index fd95c16..1f9cab9 100644 ifile = defaults.interface_info() headers = defaults.headers() rebuild = False -@@ -477,7 +482,9 @@ def gen_interfaces(): +@@ -477,7 +485,9 @@ def gen_interfaces(): if os.getuid() != 0: raise ValueError(_("You must regenerate interface info by running /usr/bin/sepolgen-ifgen")) @@ -258128,7 +259881,7 @@ index fd95c16..1f9cab9 100644 def gen_port_dict(): global portrecs -@@ -511,12 +518,26 @@ def get_all_domains(): +@@ -511,12 +521,26 @@ def get_all_domains(): all_domains = info(ATTRIBUTE,"domain")[0]["types"] return all_domains @@ -258156,7 +259909,7 @@ index fd95c16..1f9cab9 100644 roles.remove("object_r") roles.sort() return roles -@@ -549,7 +570,7 @@ def get_login_mappings(): +@@ -549,7 +573,7 @@ def get_login_mappings(): return login_mappings def get_all_users(): @@ -258165,7 +259918,7 @@ index fd95c16..1f9cab9 100644 users.sort() return users -@@ -697,7 +718,7 @@ all_attributes = None +@@ -697,7 +721,7 @@ all_attributes = None def get_all_attributes(): global all_attributes if not all_attributes: @@ -258174,7 +259927,7 @@ index fd95c16..1f9cab9 100644 return all_attributes def policy(policy_file): -@@ -727,7 +748,7 @@ def policy(policy_file): +@@ -727,7 +751,7 @@ def policy(policy_file): try: policy_file = get_installed_policy() policy(policy_file) @@ -258183,7 +259936,7 @@ index fd95c16..1f9cab9 100644 if selinux.is_selinux_enabled() == 1: raise e -@@ -755,7 +776,7 @@ def get_bools(setype): +@@ -755,7 +779,7 @@ def get_bools(setype): bools = [] domainbools = [] domainname, short_name = gen_short_name(setype) @@ -258192,7 +259945,7 @@ index fd95c16..1f9cab9 100644 for b in i: if not isinstance(b,tuple): continue -@@ -818,7 +839,7 @@ def gen_bool_dict(path="/usr/share/selinux/devel/policy.xml"): +@@ -818,7 +842,7 @@ def gen_bool_dict(path="/usr/share/selinux/devel/policy.xml"): desc = i.find("desc").find("p").text.strip("\n") desc = re.sub("\n", " ", desc) booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc) @@ -258201,7 +259954,7 @@ index fd95c16..1f9cab9 100644 pass return booleans_dict -@@ -841,12 +862,13 @@ def get_os_version(): +@@ -841,12 +865,13 @@ def get_os_version(): os_version = "" pkg_name = "selinux-policy" try: @@ -258215,13 +259968,13 @@ index fd95c16..1f9cab9 100644 + output = subprocess.check_output("rpm -q '%s'" % pkg_name, + stderr=subprocess.STDOUT, + shell=True) -+ os_version = output.split(".")[-2] ++ os_version = str(output).split(".")[-2] + except subprocess.CalledProcessError as e: + print(e.output) if os_version[0:2] == "fc": os_version = "Fedora"+os_version[2:] -@@ -868,7 +890,7 @@ def reinit(): +@@ -868,7 +893,7 @@ def reinit(): global file_types global local_files global methods @@ -258256,15 +260009,13 @@ index 9b9a09a..ec3e67e 100755 return tlist diff --git a/policycoreutils/sepolicy/sepolicy/generate.py b/policycoreutils/sepolicy/sepolicy/generate.py -index 15366c3..bd7af36 100644 +index 6b53035..32ea970 100644 --- a/policycoreutils/sepolicy/sepolicy/generate.py +++ b/policycoreutils/sepolicy/sepolicy/generate.py -@@ -26,23 +26,22 @@ import re - import sepolicy +@@ -27,21 +27,21 @@ import sepolicy from sepolicy import get_all_types, get_all_attributes, get_all_roles import time --import yum -- + -from templates import executable -from templates import boolean -from templates import etc_rw @@ -258280,7 +260031,6 @@ index 15366c3..bd7af36 100644 -from templates import script -from templates import spec -from templates import user -+ +from .templates import executable +from .templates import boolean +from .templates import etc_rw @@ -258299,12 +260049,17 @@ index 15366c3..bd7af36 100644 import sepolgen.interfaces as interfaces import sepolgen.defaults as defaults -@@ -57,11 +56,11 @@ gettext.textdomain(PROGNAME) +@@ -55,12 +55,15 @@ gettext.bindtextdomain(PROGNAME, "/usr/share/locale") + gettext.textdomain(PROGNAME) try: gettext.install(PROGNAME, - localedir="/usr/share/locale", +- localedir="/usr/share/locale", - unicode=False, + unicode=True, ++ codeset = 'utf-8') ++except TypeError: ++ # Failover to python3 install ++ gettext.install(PROGNAME, codeset = 'utf-8') except IOError: - import __builtin__ @@ -258314,7 +260069,7 @@ index 15366c3..bd7af36 100644 def get_rpm_nvr_from_header(hdr): 'Given an RPM header return the package NVR as a string' -@@ -83,7 +82,7 @@ def get_rpm_nvr_list(package): +@@ -82,7 +85,7 @@ def get_rpm_nvr_list(package): nvr = get_rpm_nvr_from_header(h) break except: @@ -258323,7 +260078,7 @@ index 15366c3..bd7af36 100644 nvr = None return nvr -@@ -99,7 +98,7 @@ def get_all_ports(): +@@ -98,7 +101,7 @@ def get_all_ports(): return dict def get_all_users(): @@ -258332,7 +260087,7 @@ index 15366c3..bd7af36 100644 users.remove("system_u") users.remove("root") users.sort() -@@ -142,13 +141,13 @@ poltype[RUSER] = _("Confined Root Administrator Role") +@@ -141,13 +144,13 @@ poltype[RUSER] = _("Confined Root Administrator Role") poltype[NEWTYPE] = _("Module information for a new type") def get_poltype_desc(): @@ -258348,7 +260103,7 @@ index 15366c3..bd7af36 100644 APPLICATIONS = [ DAEMON, DBUS, INETD, USER, CGI ] USERS = [ XUSER, TUSER, LUSER, AUSER, RUSER] -@@ -182,7 +181,7 @@ def verify_ports(ports): +@@ -181,7 +184,7 @@ def verify_ports(ports): class policy: @@ -258357,7 +260112,7 @@ index 15366c3..bd7af36 100644 self.rpms = [] self.ports = [] self.all_roles = get_all_roles() -@@ -191,14 +190,14 @@ class policy: +@@ -190,14 +193,14 @@ class policy: if type not in poltype: raise ValueError(_("You must enter a valid policy type")) @@ -258377,7 +260132,7 @@ index 15366c3..bd7af36 100644 self.symbols = {} self.symbols["openlog"] = "set_use_kerberos(True)" -@@ -290,32 +289,32 @@ class policy: +@@ -289,32 +292,32 @@ class policy: self.symbols["audit_control"] = "add_capability('audit_control')" self.symbols["setfcap"] = "add_capability('setfcap')" @@ -258433,7 +260188,7 @@ index 15366c3..bd7af36 100644 ( self.generate_daemon_types, self.generate_daemon_rules), \ ( self.generate_dbusd_types, self.generate_dbusd_rules), \ ( self.generate_inetd_types, self.generate_inetd_rules), \ -@@ -332,47 +331,47 @@ class policy: +@@ -331,47 +334,47 @@ class policy: if not re.match(r"^[a-zA-Z0-9-_]+$", name): raise ValueError(_("Name must be alpha numberic with no spaces. Consider using option \"-n MODULENAME\"")) @@ -258512,7 +260267,7 @@ index 15366c3..bd7af36 100644 self.roles = [] def __isnetset(self, l): -@@ -415,162 +414,162 @@ class policy: +@@ -414,162 +417,162 @@ class policy: return self.use_tcp() or self.use_udp() def find_port(self, port, protocol="tcp"): @@ -258737,7 +260492,7 @@ index 15366c3..bd7af36 100644 newte ="" if self.use_mail: newte = re.sub("TEMPLATETYPE", self.name, executable.te_mail_rules) -@@ -590,7 +589,7 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -589,7 +592,7 @@ allow %s_t %s_t:%s_socket name_%s; """ % (port_name, self.name, port_name, protocol, action) return line @@ -258746,7 +260501,7 @@ index 15366c3..bd7af36 100644 for i in self.in_tcp[PORTS]: rec = self.find_port(int(i), "tcp") if rec == None: -@@ -628,7 +627,7 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -627,7 +630,7 @@ allow %s_t %s_t:%s_socket name_%s; return re.sub("TEMPLATETYPE", self.name, network.te_types) return "" @@ -258755,7 +260510,7 @@ index 15366c3..bd7af36 100644 for d in self.DEFAULT_DIRS: if file.find(d) == 0: self.DEFAULT_DIRS[d][1].append(file) -@@ -636,34 +635,34 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -635,34 +638,34 @@ allow %s_t %s_t:%s_socket name_%s; self.DEFAULT_DIRS["rw"][1].append(file) return self.DEFAULT_DIRS["rw"] @@ -258800,7 +260555,7 @@ index 15366c3..bd7af36 100644 newte = "" self.processes.sort() if len(self.processes) > 0: -@@ -671,9 +670,9 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -670,9 +673,9 @@ allow %s_t %s_t:%s_socket name_%s; return newte @@ -258813,7 +260568,7 @@ index 15366c3..bd7af36 100644 newte = "\n" newte += re.sub("TEMPLATETYPE", self.name, network.te_network) -@@ -726,7 +725,7 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -725,7 +728,7 @@ allow %s_t %s_t:%s_socket name_%s; for i in self.found_udp_ports: newte += i @@ -258822,7 +260577,7 @@ index 15366c3..bd7af36 100644 def generate_transition_rules(self): newte = "" -@@ -751,11 +750,11 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -750,11 +753,11 @@ allow %s_t %s_t:%s_socket name_%s; tmp = re.sub("TEMPLATETYPE", name, user.te_admin_domain_rules) if role not in self.all_roles: tmp = re.sub(role, "system_r", tmp) @@ -258837,7 +260592,7 @@ index 15366c3..bd7af36 100644 if self.type == RUSER: newte += re.sub("TEMPLATETYPE", self.name, user.te_admin_rules) -@@ -773,7 +772,7 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -772,7 +775,7 @@ allow %s_t %s_t:%s_socket name_%s; return newte @@ -258846,7 +260601,7 @@ index 15366c3..bd7af36 100644 newif = "" if self.use_dbus: newif = re.sub("TEMPLATETYPE", self.name, executable.if_dbus_rules) -@@ -809,31 +808,31 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -808,31 +811,31 @@ allow %s_t %s_t:%s_socket name_%s; return "" @@ -258895,7 +260650,7 @@ index 15366c3..bd7af36 100644 if len(self.existing_domains) == 0: raise ValueError(_("'%s' policy modules require existing domains") % poltype[self.type]) newte = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_types) -@@ -845,27 +844,27 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -844,27 +847,27 @@ allow %s_t %s_t:%s_socket name_%s; role = d.split("_t")[0] + "_r" if role in self.all_roles: newte += """ @@ -258932,7 +260687,7 @@ index 15366c3..bd7af36 100644 newte += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].te_types) break -@@ -877,46 +876,46 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -876,46 +879,46 @@ allow %s_t %s_t:%s_socket name_%s; return newte @@ -258992,7 +260747,7 @@ index 15366c3..bd7af36 100644 newif = "" for t in self.types: for i in self.DEFAULT_EXT: -@@ -926,46 +925,46 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -925,46 +928,46 @@ allow %s_t %s_t:%s_socket name_%s; break return newif @@ -259064,7 +260819,7 @@ index 15366c3..bd7af36 100644 newif ="" if self.use_terminal or self.type == USER: newif = re.sub("TEMPLATETYPE", self.name, executable.if_user_program_rules) -@@ -974,7 +973,7 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -973,7 +976,7 @@ allow %s_t %s_t:%s_socket name_%s; newif += re.sub("TEMPLATETYPE", self.name, executable.if_role_change_rules) return newif @@ -259073,7 +260828,7 @@ index 15366c3..bd7af36 100644 newif = "" newif += re.sub("TEMPLATETYPE", self.name, executable.if_heading_rules) if self.program: -@@ -983,8 +982,8 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -982,8 +985,8 @@ allow %s_t %s_t:%s_socket name_%s; newif += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_rules) for d in self.DEFAULT_KEYS: @@ -259084,7 +260839,7 @@ index 15366c3..bd7af36 100644 for i in self.DEFAULT_DIRS[d][1]: if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]): newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_stream_rules) -@@ -996,17 +995,17 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -995,17 +998,17 @@ allow %s_t %s_t:%s_socket name_%s; newif += self.generate_new_type_if() newif += self.generate_new_rules() @@ -259107,7 +260862,7 @@ index 15366c3..bd7af36 100644 newte = "" if self.type in ( TUSER, XUSER, AUSER, LUSER ): roles = "" -@@ -1018,12 +1017,12 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1017,12 +1020,12 @@ allow %s_t %s_t:%s_socket name_%s; newte += re.sub("ROLE", role, tmp) return newte @@ -259125,7 +260880,7 @@ index 15366c3..bd7af36 100644 newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_types) if self.type != EUSER: -@@ -1035,14 +1034,14 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1034,14 +1037,14 @@ allow %s_t %s_t:%s_socket name_%s; """ % self.name newte += self.generate_capabilities() newte += self.generate_process() @@ -259146,7 +260901,7 @@ index 15366c3..bd7af36 100644 if self.type == EUSER: newte_tmp = "" for domain in self.existing_domains: -@@ -1060,40 +1059,40 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1059,40 +1062,40 @@ allow %s_t %s_t:%s_socket name_%s; newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_stream_rules) break @@ -259214,7 +260969,7 @@ index 15366c3..bd7af36 100644 fclist.append(re.sub("FILETYPE", self.dirs[i][0], t2)) if self.type in USERS + [ SANDBOX ]: -@@ -1113,9 +1112,9 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1112,9 +1115,9 @@ allow %s_t %s_t:%s_socket name_%s; fclist.sort() newfc="\n".join(fclist) @@ -259226,7 +260981,7 @@ index 15366c3..bd7af36 100644 newsh = "" if self.type not in ( TUSER, XUSER, AUSER, LUSER, RUSER): return newsh -@@ -1141,7 +1140,7 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1140,7 +1143,7 @@ allow %s_t %s_t:%s_socket name_%s; return newsh @@ -259235,7 +260990,7 @@ index 15366c3..bd7af36 100644 temp = re.sub("TEMPLATETYPE", self.file_name, script.compile) temp = re.sub("DOMAINTYPE", self.name, temp) if self.type == EUSER: -@@ -1155,11 +1154,11 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1154,11 +1157,11 @@ allow %s_t %s_t:%s_socket name_%s; if self.initscript != "": newsh += re.sub("FILENAME", self.initscript, script.restorecon) @@ -259251,7 +261006,7 @@ index 15366c3..bd7af36 100644 for i in self.in_tcp[PORTS] + self.out_tcp[PORTS]: if self.find_port(i,"tcp") == None: -@@ -1168,90 +1167,91 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1167,88 +1170,88 @@ allow %s_t %s_t:%s_socket name_%s; for i in self.in_udp[PORTS]: if self.find_port(i,"udp") == None: @@ -259417,23 +261172,8 @@ index 15366c3..bd7af36 100644 + return fcfile def __extract_rpms(self): -+ import yum - yb = yum.YumBase() - yb.setCacheDir() - -@@ -1293,7 +1293,10 @@ allow %s_t %s_t:%s_socket name_%s; - self.add_dir(fname) - - def gen_writeable(self): -- self.__extract_rpms() -+ try: -+ self.__extract_rpms() -+ except ImportError: -+ pass - - if os.path.isfile("/var/run/%s.pid" % self.name): - self.add_file("/var/run/%s.pid" % self.name) -@@ -1313,10 +1316,10 @@ allow %s_t %s_t:%s_socket name_%s; + import yum +@@ -1316,10 +1319,10 @@ allow %s_t %s_t:%s_socket name_%s; if os.path.isfile("/etc/rc.d/init.d/%s" % self.name): self.set_init_script("/etc/rc\.d/init\.d/%s" % self.name) @@ -259446,7 +261186,7 @@ index 15366c3..bd7af36 100644 temp_dirs = [] try: temp_basepath = self.DEFAULT_DIRS[p][1][0] + "/" -@@ -1331,9 +1334,9 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1334,9 +1337,9 @@ allow %s_t %s_t:%s_socket name_%s; if len(temp_dirs) is not 0: for i in temp_dirs: @@ -259458,7 +261198,7 @@ index 15366c3..bd7af36 100644 del(self.files[i]) else: continue -@@ -1355,10 +1358,10 @@ Warning %s does not exist +@@ -1358,10 +1361,10 @@ Warning %s does not exist for s in fd.read().split(): for b in self.symbols: if s.startswith(b): @@ -259472,15 +261212,20 @@ index 15366c3..bd7af36 100644 out += "%s # %s\n" % (self.write_te(out_dir), _("Type Enforcement file")) out += "%s # %s\n" % (self.write_if(out_dir), _("Interface file")) diff --git a/policycoreutils/sepolicy/sepolicy/gui.py b/policycoreutils/sepolicy/sepolicy/gui.py -index 0123e6c..fdabedf 100644 +index 0123e6c..ac3e513 100644 --- a/policycoreutils/sepolicy/sepolicy/gui.py +++ b/policycoreutils/sepolicy/sepolicy/gui.py -@@ -48,11 +48,11 @@ gettext.textdomain(PROGNAME) +@@ -47,12 +47,15 @@ gettext.bindtextdomain(PROGNAME, "/usr/share/locale") + gettext.textdomain(PROGNAME) try: gettext.install(PROGNAME, - localedir="/usr/share/locale", +- localedir="/usr/share/locale", - unicode=False, + unicode=True, ++ codeset = 'utf-8') ++except TypeError: ++ # Failover to python3 install ++ gettext.install(PROGNAME, codeset = 'utf-8') except IOError: - import __builtin__ @@ -259490,18 +261235,60 @@ index 0123e6c..fdabedf 100644 reverse_file_type_str = {} for f in sepolicy.file_type_str: -@@ -106,8 +106,8 @@ class SELinuxGui(): +@@ -60,8 +63,6 @@ for f in sepolicy.file_type_str: + + enabled=[_("No"), _("Yes")] + action=[_("Disable"), _("Enable")] +-def compare(a, b): +- return cmp(a.lower(),b.lower()) + + import distutils.sysconfig + ADVANCED_LABEL = ( _("Advanced >>"), _("Advanced <<") ) +@@ -102,18 +103,13 @@ class SELinuxGui(): + + def __init__( self , app = None, test = False): + self.finish_init = False ++ self.advanced_init = True + self.opage = START_PAGE self.dbus = SELinuxDBus() try: customized = self.dbus.customized() - except dbus.exceptions.DBusException, e: - print e +- self.quit() +- +- sepolicy_domains = sepolicy.get_all_domains() +- sepolicy_domains.sort(compare) +- if app and app not in sepolicy_domains: +- self.error(_("%s is not a valid domain" % app)) + except dbus.exceptions.DBusException as e: + print(e) self.quit() - sepolicy_domains = sepolicy.get_all_domains() -@@ -234,7 +234,7 @@ class SELinuxGui(): + self.init_cur() +@@ -139,7 +135,7 @@ class SELinuxGui(): + self.files_add = False + self.network_add = False + +- self.all_list = [] ++ self.all_domains = [] + self.installed_list = [] + self.previously_modified = {} + +@@ -151,10 +147,10 @@ class SELinuxGui(): + self.invalid_entry = False + # Advanced search window **************************** + self.advanced_search_window = builder.get_object("advanced_search_window") +- self.advanced_search_liststore = builder.get_object("Advanced_search_liststore") +- self.advanced_search_liststore.set_sort_column_id(0, Gtk.SortType.ASCENDING) + self.advanced_search_filter = builder.get_object("advanced_filter") + self.advanced_search_filter.set_visible_func(self.filter_the_data) ++ self.advanced_search_sort = builder.get_object("advanced_filter") ++ + self.advanced_filter_entry = builder.get_object("advanced_filter_entry") + self.advanced_search_treeview = builder.get_object("advanced_search_treeview") + self.advanced_search = False +@@ -234,7 +230,7 @@ class SELinuxGui(): self.advanced_system.set_visible(False) self.system_policy_label.set_visible(False) self.system_policy_type_combobox.set_visible(False) @@ -259510,7 +261297,99 @@ index 0123e6c..fdabedf 100644 self.enforcing_button_default = builder.get_object("Enforcing_button_default") self.permissive_button_default = builder.get_object("Permissive_button_default") self.disabled_button_default = builder.get_object("Disabled_button_default") -@@ -812,7 +812,7 @@ class SELinuxGui(): +@@ -423,12 +419,10 @@ class SELinuxGui(): + + # Combobox and Entry items ************************** + self.combobox_menu = builder.get_object("combobox_org") # This is the combobox box object, aka the arrow next to the entry text bar +- self.combobox_menu_model = builder.get_object("application_liststore") ++ self.application_liststore = builder.get_object("application_liststore") + self.completion_entry = builder.get_object("completion_entry") #self.combobox_menu.get_child() +- self.completion_entry_model = builder.get_object("application_liststore") + self.entrycompletion_obj = builder.get_object("entrycompletion_obj") + #self.entrycompletion_obj = Gtk.EntryCompletion() +- self.entrycompletion_obj.set_model(self.completion_entry_model) + self.entrycompletion_obj.set_minimum_key_length(0) + self.entrycompletion_obj.set_text_column(0) + self.entrycompletion_obj.set_match_func(self.match_func, None) +@@ -483,18 +477,24 @@ class SELinuxGui(): + self.loading = 1 + path = None + if test: +- domains = [ "httpd_t", "abrt_t" ] ++ self.all_domains = [ "httpd_t", "abrt_t" ] ++ if app and app not in self.all_domains: ++ self.all_domains.append(app) + else: +- domains = sepolicy_domains +- loading_gui.show() +- length = len(domains) +- for domain in domains: ++ self.all_domains = sepolicy.get_all_domains() ++ self.all_domains.sort(key=str.lower) ++ ++ if app and app not in self.all_domains: ++ self.error(_("%s is not a valid domain" % app)) ++ self.quit() ++ ++ loading_gui.show() ++ length = len(self.all_domains) ++ for domain in self.all_domains: + # After the user selects a path in the drop down menu call + # get_init_entrypoint_target(entrypoint) to get the transtype + # which will give you the application +- self.combo_box_initialize(domain, None) +- self.advanced_search_initialize(domain) +- self.all_list.append(domain) ++ self.combo_box_add(domain, domain) + self.percentage = float(float(self.loading)/float(length)) + self.progress_bar.set_fraction(self.percentage) + self.progress_bar.set_pulse_step(self.percentage) +@@ -504,14 +504,13 @@ class SELinuxGui(): + if entrypoint: + path = sepolicy.find_entrypoint_path(entrypoint) + if path: +- self.combo_box_initialize(path, None) +- # Adds all files entrypoint paths that exists on disc +- # into the combobox +- self.advanced_search_initialize(path) ++ self.combo_box_add(path, domain) + self.installed_list.append(path) + + self.loading += 1 + loading_gui.hide() ++ self.entrycompletion_obj.set_model(self.application_liststore) ++ self.advanced_search_treeview.set_model(self.advanced_search_sort) + + dic = { + "on_combo_button_clicked" : self.open_combo_menu, +@@ -543,7 +542,7 @@ class SELinuxGui(): + "on_file_equiv_button_clicked" : self.show_file_equiv_page, + "on_app/system_button_clicked" : self.system_interface, + "on_app/users_button_clicked" : self.users_interface, +- "on_main_advanced_label_button_press_event": self.advanced_label_main, ++ "on_show_advanced_search_window": self.on_show_advanced_search_window, + + "on_Show_mislabeled_files_toggled" : self.show_mislabeled_files, + "on_Browse_button_files_clicked" : self.browse_for_files, +@@ -559,8 +558,6 @@ class SELinuxGui(): + "on_advanced_filter_entry_changed" : self.get_advanced_filter_data, + "on_advanced_search_treeview_row_activated" : self.advanced_item_selected, + "on_Select_advanced_search_clicked" : self.advanced_item_button_push, +- "on_All_advanced_button_toggled" : self.advanced_radio_select, +- "on_Installed_advanced_button_toggled" : self.advanced_radio_select, + "on_info_button_button_press_event" : self.on_help_button, + "on_back_button_clicked" : self.on_help_back_clicked, + "on_forward_button_clicked" : self.on_help_forward_clicked, +@@ -701,7 +698,7 @@ class SELinuxGui(): + + def match_func(self, completion, key_string, iter, func_data): + try: +- if self.combobox_menu_model.get_value(iter, 0).find(key_string) != -1: ++ if self.application_liststore.get_value(iter, 0).find(key_string) != -1: + return True + return False + except AttributeError: +@@ -812,7 +809,7 @@ class SELinuxGui(): self.set_application_label = True def resize_wrap(self, *args): @@ -259519,16 +261398,16 @@ index 0123e6c..fdabedf 100644 def initialize_system_default_mode(self): self.enforce_mode = selinux.selinux_getenforcemode()[1] -@@ -825,7 +825,7 @@ class SELinuxGui(): +@@ -825,7 +822,7 @@ class SELinuxGui(): def populate_system_policy(self): selinux_path = selinux.selinux_path() - types = map(lambda x: x[1], filter(lambda x: x[0]==selinux_path, os.walk(selinux_path)))[0] -+ types = map(lambda x: x[1], [x for x in os.walk(selinux_path) if x[0]==selinux_path])[0] ++ types = [x[1] for x in os.walk(selinux_path) if x[0]==selinux_path][0] types.sort() ctr = 0 for item in types: -@@ -850,14 +850,14 @@ class SELinuxGui(): +@@ -850,14 +847,14 @@ class SELinuxGui(): # Returns true if filter_txt exists within the val if(val.find(self.filter_txt) != -1 or val.lower().find(self.filter_txt) != -1) : return True @@ -259545,7 +261424,66 @@ index 0123e6c..fdabedf 100644 for t,ports in netd[k]: pkey = (",".join(ports), protocol) if pkey in self.cur_dict["port"]: -@@ -1114,7 +1114,7 @@ class SELinuxGui(): +@@ -912,11 +909,11 @@ class SELinuxGui(): + self.ready_mouse() + + def network_initialize(self, app): +- netd = sepolicy.network.get_network_connect(app, "tcp", "name_connect") ++ netd = sepolicy.network.get_network_connect(app, "tcp", "name_connect", check_bools=True) + self.net_update(app, netd, "tcp", OUTBOUND_PAGE, self.network_out_liststore) +- netd = sepolicy.network.get_network_connect(app, "tcp", "name_bind") ++ netd = sepolicy.network.get_network_connect(app, "tcp", "name_bind",check_bools=True) + self.net_update(app, netd, "tcp", INBOUND_PAGE, self.network_in_liststore) +- netd = sepolicy.network.get_network_connect(app, "udp", "name_bind") ++ netd = sepolicy.network.get_network_connect(app, "udp", "name_bind",check_bools=True) + self.net_update(app, netd, "udp", INBOUND_PAGE, self.network_in_liststore) + + def network_initial_data_insert(self, model, ports, portType, protocol): +@@ -952,12 +949,12 @@ class SELinuxGui(): + iter = liststore.get_iter(index) + return liststore.get_value(iter, 0) + +- def combo_box_initialize(self, val, desc): ++ def combo_box_add(self, val, val1): + if val == None: + return +- iter = self.combobox_menu_model.append() +- for f in val: +- self.combobox_menu_model.set_value(iter, 0, val) ++ iter = self.application_liststore.append() ++ self.application_liststore.set_value(iter, 0, val) ++ self.application_liststore.set_value(iter, 1, val1) + + def select_type_more(self, *args): + app = self.moreTypes_treeview.get_selection() +@@ -973,7 +970,7 @@ class SELinuxGui(): + model, iter = row.get_selected() + iter = model.convert_iter_to_child_iter(iter) + iter = self.advanced_search_filter.convert_iter_to_child_iter(iter) +- app = self.advanced_search_liststore.get_value(iter, 1) ++ app = self.application_liststore.get_value(iter, 1) + if app == None: + return + self.advanced_filter_entry.set_text('') +@@ -985,7 +982,7 @@ class SELinuxGui(): + def advanced_item_selected(self, treeview, path, *args): + iter = self.advanced_search_filter.get_iter(path) + iter = self.advanced_search_filter.convert_iter_to_child_iter(iter) +- app = self.advanced_search_liststore.get_value(iter, 1) ++ app = self.application_liststore.get_value(iter, 1) + self.advanced_filter_entry.set_text('') + self.advanced_search_window.hide() + self.reveal_advanced(self.main_advanced_label) +@@ -994,7 +991,7 @@ class SELinuxGui(): + + def find_application(self, app): + if app and len(app) > 0: +- for items in self.combobox_menu_model: ++ for items in self.application_liststore: + if app == items[0]: + return True + return False +@@ -1114,7 +1111,7 @@ class SELinuxGui(): def executable_files_initialize(self, application): self.entrypoints = sepolicy.get_entrypoints(application) @@ -259554,7 +261492,7 @@ index 0123e6c..fdabedf 100644 if len(self.entrypoints[exe]) == 0: continue file_class = self.entrypoints[exe][1] -@@ -1151,7 +1151,7 @@ class SELinuxGui(): +@@ -1151,7 +1148,7 @@ class SELinuxGui(): def writable_files_initialize(self, application): # Traversing the dictionary data struct self.writable_files = sepolicy.get_writable_files(application) @@ -259563,7 +261501,7 @@ index 0123e6c..fdabedf 100644 if len(self.writable_files[write]) < 2: self.files_initial_data_insert(self.writable_files_liststore, None, write, _("all files")) continue -@@ -1194,7 +1194,7 @@ class SELinuxGui(): +@@ -1194,7 +1191,7 @@ class SELinuxGui(): def application_files_initialize(self, application): self.file_types = sepolicy.get_file_types(application) @@ -259572,7 +261510,7 @@ index 0123e6c..fdabedf 100644 if len(self.file_types[app]) == 0: continue file_class = self.file_types[app][1] -@@ -1367,8 +1367,8 @@ class SELinuxGui(): +@@ -1367,8 +1364,8 @@ class SELinuxGui(): self.treeview = self.network_in_treeview category = _("listen for inbound connections") @@ -259583,7 +261521,25 @@ index 0123e6c..fdabedf 100644 self.modify_button.set_tooltip_text(_("Modify port definitions to which the '%(APP)s' domain is allowed to %(PERM)s.") % {"APP": self.application, "PERM": category}) if self.transitions_radio_button.get_active(): -@@ -1636,7 +1636,7 @@ class SELinuxGui(): +@@ -1439,7 +1436,7 @@ class SELinuxGui(): + sort_column, _ = model.get_sort_column_id() + val1 = self.unmarkup(model.get_value(row1, sort_column)) + val2 = self.unmarkup(model.get_value(row2, sort_column)) +- return cmp(val1,val2) ++ return (val1 > val2) - (val1 < val2) + + def display_more_detail(self, windows, path): + it = self.boolean_filter.get_iter(path) +@@ -1625,7 +1622,7 @@ class SELinuxGui(): + self.files_type_combolist.clear() + self.files_class_combolist.clear() + compare = self.strip_domain(self.application) +- for d in self.completion_entry_model: ++ for d in self.application_liststore: + if d[0].startswith(compare) and d[0] != self.application and not d[0].startswith("httpd_sys"): + exclude_list.append(self.strip_domain(d[0])) + +@@ -1636,7 +1633,7 @@ class SELinuxGui(): self.files_class_combolist.set_value(iter, 0, sepolicy.file_type_str[files]) if ipage == EXE_PAGE and self.entrypoints != None: @@ -259592,7 +261548,7 @@ index 0123e6c..fdabedf 100644 if exe.startswith(compare): iter = self.files_type_combolist.append() self.files_type_combolist.set_value(iter, 0, exe) -@@ -1646,7 +1646,7 @@ class SELinuxGui(): +@@ -1646,7 +1643,7 @@ class SELinuxGui(): self.files_class_combobox.set_sensitive(False) elif ipage == WRITABLE_PAGE and self.writable_files != None: @@ -259601,7 +261557,7 @@ index 0123e6c..fdabedf 100644 if write.startswith(compare) and not self.exclude_type(write, exclude_list) and write in self.file_types: iter = self.files_type_combolist.append() self.files_type_combolist.set_value(iter, 0, write) -@@ -1663,7 +1663,7 @@ class SELinuxGui(): +@@ -1663,7 +1660,7 @@ class SELinuxGui(): self.more_types_files_liststore.set_value(iter, 0, app) self.files_class_combobox.set_active(0) except AttributeError: @@ -259610,8 +261566,17 @@ index 0123e6c..fdabedf 100644 pass self.files_type_combobox.set_active(0) self.files_mls_entry.set_text("s0") -@@ -1710,7 +1710,7 @@ class SELinuxGui(): - netd += sepolicy.network.get_network_connect(self.application, "udp", "name_bind") +@@ -1704,13 +1701,13 @@ class SELinuxGui(): + + try: + if ipage == OUTBOUND_PAGE: +- netd = sepolicy.network.get_network_connect(self.application, "tcp", "name_connect") ++ netd = sepolicy.network.get_network_connect(self.application, "tcp", "name_connect", check_bools = True) + elif ipage == INBOUND_PAGE: +- netd = sepolicy.network.get_network_connect(self.application, "tcp", "name_bind") +- netd += sepolicy.network.get_network_connect(self.application, "udp", "name_bind") ++ netd = sepolicy.network.get_network_connect(self.application, "tcp", "name_bind", check_bools = True) ++ netd += sepolicy.network.get_network_connect(self.application, "udp", "name_bind", check_bools = True) port_types = [] - for k in netd.keys(): @@ -259619,7 +261584,7 @@ index 0123e6c..fdabedf 100644 for t,ports in netd[k]: if t not in port_types + ["port_t", "unreserved_port_t"]: if t.endswith("_type"): -@@ -1805,7 +1805,7 @@ class SELinuxGui(): +@@ -1805,7 +1802,7 @@ class SELinuxGui(): self.wait_mouse() try: self.dbus.semanage(update_buffer) @@ -259628,7 +261593,7 @@ index 0123e6c..fdabedf 100644 self.error(e) self.ready_mouse() -@@ -1883,7 +1883,7 @@ class SELinuxGui(): +@@ -1883,7 +1880,7 @@ class SELinuxGui(): tree.set_value(iter, 2, fclass) def restore_to_default(self, *args): @@ -259637,7 +261602,7 @@ index 0123e6c..fdabedf 100644 def invalid_entry_retry(self, *args): self.closewindow(self.error_check_window) -@@ -2136,7 +2136,7 @@ class SELinuxGui(): +@@ -2136,7 +2133,7 @@ class SELinuxGui(): def on_save_delete_file_equiv_clicked(self, *args): for delete in self.files_delete_liststore: @@ -259646,7 +261611,7 @@ index 0123e6c..fdabedf 100644 def on_toggle_update(self, cell, path, model): model[path][0] = not model[path][0] -@@ -2444,8 +2444,8 @@ class SELinuxGui(): +@@ -2444,8 +2441,8 @@ class SELinuxGui(): self.wait_mouse() try: self.dbus.semanage(update_buffer) @@ -259657,11 +261622,85 @@ index 0123e6c..fdabedf 100644 self.ready_mouse() self.init_cur() -@@ -2728,7 +2728,7 @@ class SELinuxGui(): +@@ -2539,34 +2536,7 @@ class SELinuxGui(): + self.network_mls_label.set_visible(advanced) + self.network_mls_entry.set_visible(advanced) + +- def advanced_search_initialize(self, path): +- try: +- if path[0] == '/': +- domain = sepolicy.get_init_transtype(path) +- else: +- domain = path +- except IndexError: +- return +- except OSError: +- return +- iter = self.advanced_search_liststore.append() +- self.advanced_search_liststore.set_value(iter, 0, path) +- self.advanced_search_liststore.set_value(iter, 1, domain) +- user_types = sepolicy.get_user_types() +- if domain in user_types + ['initrc_t']: +- return +- +- entrypoints = sepolicy.get_entrypoints(domain) +- # From entry_point = 0 to the number of keys in the dic +- for exe in entrypoints: +- if len(entrypoints[exe]): +- file_class = entrypoints[exe][1] +- for path in entrypoints[exe][0]: +- iter = self.advanced_search_liststore.append() +- self.advanced_search_liststore.set_value(iter, 1, domain) +- self.advanced_search_liststore.set_value(iter, 0, path) +- +- def advanced_label_main(self, label, *args): ++ def on_show_advanced_search_window(self, label, *args): + if label.get_text() == ADVANCED_SEARCH_LABEL[1]: + label.set_text(ADVANCED_SEARCH_LABEL[0]) + self.close_popup() +@@ -2574,25 +2544,6 @@ class SELinuxGui(): + label.set_text(ADVANCED_SEARCH_LABEL[1]) + self.show_popup(self.advanced_search_window) + +- def advanced_radio_select(self, button): +- label = "" +- if button.get_active(): +- label = button.get_label() +- if label == '': +- return +- self.advanced_search_liststore.clear() +- if label == "All": +- for items in self.all_list: +- self.advanced_search_initialize(items) +- self.idle_func() +- +- elif label == "Installed": +- if self.installed_list == []: +- return +- for items in self.installed_list: +- self.advanced_search_initialize(items) +- self.idle_func() +- + def set_enforce_text(self, value): + if value: + self.status_bar.push(self.context_id, _("System Status: Enforcing")) +@@ -2601,6 +2552,9 @@ class SELinuxGui(): + self.current_status_permissive.set_active(True) + + def set_enforce(self, button): ++ if not self.finish_init: ++ return ++ + self.dbus.setenforce(button.get_active()) + self.set_enforce_text(button.get_active()) + +@@ -2727,8 +2681,8 @@ class SELinuxGui(): + if not active and not exists: return try: - self.dbus.relabel_on_boots(active) +- self.dbus.relabel_on_boots(active) - except dbus.exceptions.DBusException, e: ++ self.dbus.relabel_on_boot(active) + except dbus.exceptions.DBusException as e: self.error(e) @@ -261370,22 +263409,36 @@ index ba15b2c..1765b1c 100755 SELinux policy also controls which roles can transition to a different role. You can list these rules using the following command. diff --git a/policycoreutils/sepolicy/sepolicy/network.py b/policycoreutils/sepolicy/sepolicy/network.py -index 3a75d7c..d1bcd65 100755 +index 3a75d7c..dca1b79 100755 --- a/policycoreutils/sepolicy/sepolicy/network.py +++ b/policycoreutils/sepolicy/sepolicy/network.py -@@ -28,9 +28,9 @@ def get_types(src, tclass, perm): +@@ -24,20 +24,22 @@ import sepolicy + search=sepolicy.search + info=sepolicy.info + +-def get_types(src, tclass, perm): ++def get_types(src, tclass, perm, check_bools=False): allows=search([sepolicy.ALLOW],{sepolicy.SOURCE:src,sepolicy.CLASS:tclass, sepolicy.PERMS:perm}) nlist=[] if allows: - for i in map(lambda y: y[sepolicy.TARGET], filter(lambda x: set(perm).issubset(x[sepolicy.PERMS]), allows)): -- if i not in nlist: -- nlist.append(i) -+ for i in [y[sepolicy.TARGET] for y in [x for x in allows if set(perm).issubset(x[sepolicy.PERMS])]]: -+ if i not in nlist: -+ nlist.append(i) ++ for i in [y[sepolicy.TARGET] for y in ++ [x for x in allows ++ if set(perm).issubset(x[sepolicy.PERMS]) and (not check_bools or x["enabled"])]]: + if i not in nlist: + nlist.append(i) return nlist +-def get_network_connect(src, protocol, perm): ++def get_network_connect(src, protocol, perm, check_bools=False): + portrecs, portrecsbynum = sepolicy.gen_port_dict() + d={} +- tlist = get_types(src, "%s_socket" % protocol, [perm]) ++ tlist = get_types(src, "%s_socket" % protocol, [perm], check_bools) + if len(tlist) > 0: + d[(src,protocol,perm)] = [] + for i in tlist: diff --git a/policycoreutils/sepolicy/sepolicy/sedbus.py b/policycoreutils/sepolicy/sepolicy/sedbus.py index c6645ef..8965795 100644 --- a/policycoreutils/sepolicy/sepolicy/sedbus.py @@ -261398,6 +263451,117 @@ index c6645ef..8965795 100644 - print e + except dbus.DBusException as e: + print (e) +diff --git a/policycoreutils/sepolicy/sepolicy/sepolicy.glade b/policycoreutils/sepolicy/sepolicy/sepolicy.glade +index 1275c7f..e3137db 100644 +--- a/policycoreutils/sepolicy/sepolicy/sepolicy.glade ++++ b/policycoreutils/sepolicy/sepolicy/sepolicy.glade +@@ -2,7 +2,7 @@ + + + +- ++ + + + +@@ -82,7 +82,7 @@ + + + +- ++ + + + True +@@ -225,7 +225,7 @@ + + + +- Advanced_search_liststore ++ application_liststore + + + advanced_filter +@@ -256,24 +256,6 @@ + + application_files_filter + +- +- +- +- +- +- +- +- application_liststore +- +- +- application_filter +- +- +- +- +- +- +- + + + +@@ -4328,46 +4310,7 @@ allow alternative access control. + 0 + + +- +- +- All +- True +- True +- False +- 0.5 +- True +- True +- +- +- +- True +- True +- 1 +- +- +- +- +- Installed +- True +- True +- False +- 0.5 +- True +- All_advanced_button +- +- +- +- True +- True +- 2 +- +- + +- +- False +- True +- 0 +- + + + +@@ -4377,7 +4320,6 @@ allow alternative access control. + + True + True +- advanced_sort + False + + diff --git a/policycoreutils/sepolicy/sepolicy/templates/spec.py b/policycoreutils/sepolicy/sepolicy/templates/spec.py index 16a2208..d8ee42f 100644 --- a/policycoreutils/sepolicy/sepolicy/templates/spec.py @@ -261443,6 +263607,26 @@ index 11834c7..96bf96c 100755 self.seen = [] - print self.out(self.source) + print(self.out(self.source)) +diff --git a/policycoreutils/sepolicy/sepolicy_16.png b/policycoreutils/sepolicy/sepolicy_16.png +new file mode 100644 +index 0000000..199aae5 +Binary files /dev/null and b/policycoreutils/sepolicy/sepolicy_16.png differ +diff --git a/policycoreutils/sepolicy/sepolicy_22.png b/policycoreutils/sepolicy/sepolicy_22.png +new file mode 100644 +index 0000000..fa1f137 +Binary files /dev/null and b/policycoreutils/sepolicy/sepolicy_22.png differ +diff --git a/policycoreutils/sepolicy/sepolicy_256.png b/policycoreutils/sepolicy/sepolicy_256.png +new file mode 100644 +index 0000000..40f1df5 +Binary files /dev/null and b/policycoreutils/sepolicy/sepolicy_256.png differ +diff --git a/policycoreutils/sepolicy/sepolicy_32.png b/policycoreutils/sepolicy/sepolicy_32.png +new file mode 100644 +index 0000000..c57a734 +Binary files /dev/null and b/policycoreutils/sepolicy/sepolicy_32.png differ +diff --git a/policycoreutils/sepolicy/sepolicy_48.png b/policycoreutils/sepolicy/sepolicy_48.png +new file mode 100644 +index 0000000..6cc0a03 +Binary files /dev/null and b/policycoreutils/sepolicy/sepolicy_48.png differ diff --git a/policycoreutils/sepolicy/setup.py b/policycoreutils/sepolicy/setup.py index d8e2d64..cac667c 100644 --- a/policycoreutils/sepolicy/setup.py @@ -261457,16 +263641,40 @@ index d8e2d64..cac667c 100644 sources=[ "policy.c", "info.c", "search.c"] ) diff --git a/policycoreutils/sepolicy/test_sepolicy.py b/policycoreutils/sepolicy/test_sepolicy.py -index aef799f..18de8e9 100644 +index aef799f..5ded03d 100644 --- a/policycoreutils/sepolicy/test_sepolicy.py +++ b/policycoreutils/sepolicy/test_sepolicy.py -@@ -1,4 +1,4 @@ +@@ -1,28 +1,28 @@ -import unittest, os, shutil +import unittest, os, shutil from tempfile import mkdtemp from subprocess import Popen, PIPE -@@ -22,7 +22,7 @@ class SepolicyTests(unittest.TestCase): + class SepolicyTests(unittest.TestCase): + def assertDenied(self, err): +- self.assert_('Permission denied' in err, +- '"Permission denied" not found in %r' % err) ++ self.assertTrue('Permission denied' in err, ++ '"Permission denied" not found in %r' % err) + def assertNotFound(self, err): +- self.assert_('not found' in err, +- '"not found" not found in %r' % err) ++ self.assertTrue('not found' in err, ++ '"not found" not found in %r' % err) + + def assertFailure(self, status): +- self.assert_(status != 0, +- '"Succeeded when it should have failed') ++ self.assertTrue(status != 0, ++ '"Succeeded when it should have failed') + + def assertSuccess(self, status, err): +- self.assert_(status == 0, +- '"sepolicy should have succeeded for this test %r' % err) ++ self.assertTrue(status == 0, ++ '"sepolicy should have succeeded for this test %r' % err) + + def test_man_domain(self): "Verify sepolicy manpage -d works" p = Popen(['sepolicy', 'manpage', '-d', 'httpd_t'], stdout = PIPE) out, err = p.communicate() diff --git a/policycoreutils.spec b/policycoreutils.spec index ec7a533..36f7a12 100644 --- a/policycoreutils.spec +++ b/policycoreutils.spec @@ -2,11 +2,11 @@ %global libsepolver 2.1.9-1 %global libsemanagever 2.1.10-1 %global libselinuxver 2.1.13-1 -%global sepolgenver 1.2 +%global sepolgenver 1.2.1 Summary: SELinux policy core utilities Name: policycoreutils -Version: 2.2 +Version: 2.2.2 Release: 1%{?dist} License: GPLv2 Group: System Environment/Base @@ -16,9 +16,9 @@ Source1:git://oss.tresys.com/git/selinux/sepolgen-%{sepolgenver}.tgz URL: http://www.selinuxproject.org Source2: policycoreutils_man_ru2.tar.bz2 Source3: system-config-selinux.png -Source4: sepolicy-help.tgz +Source4: sepolicy-icons.tgz Patch: policycoreutils-rhat.patch -Patch1: policycoreutils-sepolgen.patch +#Patch1: policycoreutils-sepolgen.patch Obsoletes: policycoreutils < 2.0.61-2 Conflicts: filesystem < 3 Provides: /sbin/fixfiles @@ -49,7 +49,7 @@ to switch roles. %prep %setup -q -a 1 %patch -p2 -b .rhat -%patch1 -p2 -b .sepolgen -d sepolgen-%{sepolgenver} +#%patch1 -p2 -b .sepolgen -d sepolgen-%{sepolgenver} cp %{SOURCE3} gui/ tar xvf %{SOURCE4} @@ -68,10 +68,12 @@ mkdir -p %{buildroot}%{_mandir}/man8 cp COPYING %{buildroot}/%{_usr}/share/doc/%{name}/ make LSPP_PRIV=y DESTDIR="%{buildroot}" SBINDIR="%{buildroot}%{_sbindir}" LIBDIR="%{buildroot}%{_libdir}" SEMODULE_PATH="/usr/sbin" install +make PYTHON=python3 LSPP_PRIV=y DESTDIR="%{buildroot}" SBINDIR="%{buildroot}%{_sbindir}" LIBDIR="%{buildroot}%{_libdir}" SEMODULE_PATH="/usr/sbin" install # Systemd rm -rf %{buildroot}/%{_sysconfdir}/rc.d/init.d/restorecond +make -C sepolgen-%{sepolgenver} DESTDIR="%{buildroot}" SBINDIR="%{buildroot}%{_sbindir}" LIBDIR="%{buildroot}%{_libdir}" install make -C sepolgen-%{sepolgenver} DESTDIR="%{buildroot}" SBINDIR="%{buildroot}%{_sbindir}" LIBDIR="%{buildroot}%{_libdir}" install tar -jxf %{SOURCE2} -C %{buildroot}/ @@ -105,8 +107,8 @@ Group: System Environment/Base Requires:policycoreutils = %{version}-%{release} Requires:libsemanage-python >= %{libsemanagever} libselinux-python libcgroup Requires:audit-libs-python >= %{libauditver} -Requires(pre): python >= 2.6 Obsoletes: policycoreutils < 2.0.61-2 +Requires: checkpolicy Requires: python-IPy yum %description python @@ -121,8 +123,13 @@ an SELinux environment. %{_bindir}/audit2why %{_mandir}/man1/audit2allow.1* %{_mandir}/ru/man1/audit2allow.1* +%{_bindir}/semodule_package +%{_mandir}/man8/semodule_package.8* +%{_mandir}/ru/man8/semodule_package.8* %{_mandir}/man1/audit2why.1* -%{python_sitearch}/seobject.py* +%dir %{python_sitelib}/seobject +%{python_sitelib}/seobject/__init__.py* +%{python_sitelib}/seobject*.egg-info %{python_sitearch}/sepolgen %dir %{python_sitearch}/sepolicy %{python_sitearch}/sepolicy/*so @@ -147,19 +154,33 @@ an SELinux environment. %{_mandir}/man8/sandbox.8* %{_mandir}/man8/semanage*.8* %{_mandir}/ru/man8/semanage.8* -%{_datadir}/system-config-selinux/selinux_server.py -%{_datadir}/dbus-1/system-services/org.selinux.service -%{_datadir}/polkit-1/actions/org.selinux.policy -%{_datadir}/polkit-1/actions/org.selinux.config.policy %{_datadir}/bash-completion/completions/semanage %{_datadir}/bash-completion/completions/setsebool +%dir %{python3_sitelib}/seobject +%{python3_sitelib}/seobject/__init__.py* +%{python3_sitelib}/seobject/__pycache__/* +%{python3_sitelib}/seobject*.egg-info +%dir %{python3_sitearch}/sepolicy +%{python3_sitearch}/sepolicy/*so +%{python3_sitearch}/sepolicy/templates +%dir %{python3_sitearch}/sepolicy/help +%{python3_sitearch}/sepolicy/help/* +%{python3_sitearch}/sepolicy/__init__.py* +%{python3_sitearch}/sepolicy/booleans.py* +%{python3_sitearch}/sepolicy/communicate.py* +%{python3_sitearch}/sepolicy/interface.py* +%{python3_sitearch}/sepolicy/manpage.py* +%{python3_sitearch}/sepolicy/network.py* +%{python3_sitearch}/sepolicy/transition.py* +%{python3_sitearch}/sepolicy/sedbus.py* +%{python3_sitearch}/sepolicy*.egg-info +%{python3_sitearch}/sepolicy/__pycache__/* %package devel Summary: SELinux policy core policy devel utilities Group: System Environment/Base Requires: policycoreutils-python = %{version}-%{release} Requires: /usr/bin/make -Requires: checkpolicy Requires: selinux-policy-devel %description devel @@ -173,6 +194,7 @@ The policycoreutils-devel package contains the management tools use to develop p /var/lib/sepolgen/perm_map %{_bindir}/sepolicy %{python_sitearch}/sepolicy/generate.py* +%{python3_sitearch}/sepolicy/generate.py* %{_mandir}/man8/sepolgen.8* %{_mandir}/man8/sepolicy-booleans.8* %{_mandir}/man8/sepolicy-generate.8* @@ -183,6 +205,17 @@ The policycoreutils-devel package contains the management tools use to develop p %{_mandir}/man8/sepolicy-manpage.8* %{_mandir}/man8/sepolicy-transition.8* %{_usr}/share/bash-completion/completions/sepolicy +%{_bindir}/semodule_deps +%{_bindir}/semodule_expand +%{_bindir}/semodule_link +%{_bindir}/semodule_unpackage +%{_mandir}/man8/semodule_deps.8* +%{_mandir}/ru/man8/semodule_deps.8* +%{_mandir}/man8/semodule_expand.8* +%{_mandir}/ru/man8/semodule_expand.8* +%{_mandir}/man8/semodule_link.8* +%{_mandir}/ru/man8/semodule_link.8* +%{_mandir}/man8/semodule_unpackage.8* %package sandbox Summary: SELinux sandbox utilities @@ -216,9 +249,12 @@ or level of a logged in user. %files newrole %attr(0755,root,root) %caps(cap_dac_read_search,cap_setpcap,cap_audit_write,cap_sys_admin,cap_fowner,cap_chown,cap_dac_override=pe) %{_bindir}/newrole - +%{_sbindir}/run_init +%{_mandir}/man8/run_init.8* +%{_mandir}/ru/man8/run_init.8* %{_mandir}/man1/newrole.1.gz %config(noreplace) %{_sysconfdir}/pam.d/newrole +%config(noreplace) %{_sysconfdir}/pam.d/run_init %package gui Summary: SELinux configuration GUI @@ -246,9 +282,17 @@ system-config-selinux is a utility for managing the SELinux environment %{_datadir}/system-config-selinux/*.glade %{python_sitearch}/sepolicy/gui.py* %{python_sitearch}/sepolicy/sepolicy.glade +%{python3_sitearch}/sepolicy/gui.py* +%{python3_sitearch}/sepolicy/sepolicy.glade +%{_datadir}/icons/hicolor/*/apps/sepolicy.png +%{_datadir}/pixmaps/sepolicy.png %{_mandir}/man8/system-config-selinux.8* %{_mandir}/man8/selinux-polgengui.8* %{_mandir}/man8/sepolicy-gui.8* +%{_datadir}/system-config-selinux/selinux_server.py +%{_datadir}/dbus-1/system-services/org.selinux.service +%{_datadir}/polkit-1/actions/org.selinux.policy +%{_datadir}/polkit-1/actions/org.selinux.config.policy %post gui /bin/touch --no-create %{_datadir}/icons/hicolor &>/dev/null || : @@ -266,42 +310,24 @@ fi %{_sbindir}/restorecon %{_sbindir}/fixfiles %{_sbindir}/setfiles -%{_sbindir}/run_init %{_sbindir}/load_policy %{_sbindir}/genhomedircon %{_sbindir}/setsebool %{_sbindir}/semodule %{_sbindir}/sestatus %{_bindir}/secon -%{_bindir}/semodule_deps -%{_bindir}/semodule_expand -%{_bindir}/semodule_link -%{_bindir}/semodule_package -%{_bindir}/semodule_unpackage %config(noreplace) %{_sysconfdir}/sestatus.conf -%config(noreplace) %{_sysconfdir}/pam.d/run_init # selinux-policy Requires: policycoreutils, so we own this set of directories and our files within them %{_mandir}/man5/selinux_config.5.gz %{_mandir}/man5/sestatus.conf.5.gz %{_mandir}/man8/fixfiles.8* %{_mandir}/ru/man8/fixfiles.8* -%{_mandir}/man8/run_init.8* -%{_mandir}/ru/man8/run_init.8* %{_mandir}/man8/load_policy.8* %{_mandir}/ru/man8/load_policy.8* %{_mandir}/man8/restorecon.8* %{_mandir}/ru/man8/restorecon.8* %{_mandir}/man8/semodule.8* %{_mandir}/ru/man8/semodule.8* -%{_mandir}/man8/semodule_deps.8* -%{_mandir}/ru/man8/semodule_deps.8* -%{_mandir}/man8/semodule_expand.8* -%{_mandir}/ru/man8/semodule_expand.8* -%{_mandir}/man8/semodule_link.8* -%{_mandir}/ru/man8/semodule_link.8* -%{_mandir}/man8/semodule_package.8* -%{_mandir}/man8/semodule_unpackage.8* -%{_mandir}/ru/man8/semodule_package.8* %{_mandir}/man8/sestatus.8* %{_mandir}/ru/man8/sestatus.8* %{_mandir}/man8/setfiles.8* @@ -344,6 +370,17 @@ The policycoreutils-restorecond package contains the restorecond service. %systemd_postun_with_restart restorecond.service %changelog +* Fri Nov 15 2013 Dan Walsh - 2.2.2-1 +- Speed up startup time of sepolicy gui +- Clean up ports screen to only show enabled ports. +- Update to upstream + * Remove import policycoreutils.default_encoding_utf8 from semanage from Dan Walsh. + * Make yum/extract_rpms optional for sepolicy generate from Dan Walsh. + * Add test suite for audit2allow and sepolgen-ifgen from Dan Walsh. + +* Thu Oct 31 2013 Dan Walsh - 2.2-2 +- Shift around some of the files to more appropriate packages. + * semodule_* packages are required for devel. * Thu Oct 31 2013 Dan Walsh - 2.2-1 - Update to upstream * Properly build the swig exception file from Laurent Bigonville. diff --git a/sepolicy-icons.tgz b/sepolicy-icons.tgz new file mode 100644 index 0000000000000000000000000000000000000000..722135fb6947a2cea2f89fc3be2308b13498046d GIT binary patch literal 31883 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 literal 0 HcmV?d00001 diff --git a/sources b/sources index 2f4f5db..de5e882 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ 59d33101d57378ce69889cc078addf90 policycoreutils_man_ru2.tar.bz2 -12a573b3e0e40c932a8b08baf7105d4c sepolgen-1.2.tgz -220ac2cb43d6f8882de22d7f6b65545e policycoreutils-2.2.tgz +332411668be7367aa74257048ac762d6 policycoreutils-2.2.2.tgz +e9134b52e6620c14cbce9234a6b67b20 sepolgen-1.2.1.tgz