From 893a20e39a37bb8f07cf75de3f601537d4f28c27 Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Tue, 14 May 2013 08:22:26 -0400 Subject: [PATCH] Add support for Xephyr -resizable, so sandbox can now resize window - Add support for compressed policy.xml - Miroslav Grepl patch to allow sepolicy interface on individual interface fil - Also add capability to test interfaces for correctness. --- policycoreutils-rhat.patch | 247 ++++++++++++++++++++++++++----------- policycoreutils.spec | 17 ++- 2 files changed, 185 insertions(+), 79 deletions(-) diff --git a/policycoreutils-rhat.patch b/policycoreutils-rhat.patch index 7a8d613..54702b6 100644 --- a/policycoreutils-rhat.patch +++ b/policycoreutils-rhat.patch @@ -34,18 +34,9 @@ index 88635d4..fc290ea 100644 clean: rm -f *~ diff --git a/policycoreutils/audit2allow/audit2allow b/policycoreutils/audit2allow/audit2allow -index 8e0c396..4fa07a1 100644 +index 8e0c396..1059bea 100644 --- a/policycoreutils/audit2allow/audit2allow +++ b/policycoreutils/audit2allow/audit2allow -@@ -1,7 +1,7 @@ - #! /usr/bin/python -Es - # Authors: Karl MacMillan - # --# Copyright (C) 2006-2007 Red Hat -+# Copyright (C) 2006-2013 Red Hat - # see file 'COPYING' for use and warranty information - # - # This program is free software; you can redistribute it and/or @@ -18,7 +18,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # @@ -74,16 +65,7 @@ index 8e0c396..4fa07a1 100644 help="Translates SELinux audit messages into a description of why the access was denied") options, args = parser.parse_args() -@@ -178,6 +179,8 @@ class AuditToPolicy: - if self.__options.interface_info: - fn = self.__options.interface_info - else: -+ import sepolicy -+ sepolicy.gen_interfaces() - fn = defaults.interface_info() - try: - fd = open(fn) -@@ -267,12 +270,10 @@ class AuditToPolicy: +@@ -267,12 +268,10 @@ class AuditToPolicy: continue if rc == audit2why.CONSTRAINT: @@ -100,7 +82,7 @@ index 8e0c396..4fa07a1 100644 if rc == audit2why.RBAC: print "\t\tMissing role allow rule.\n" -@@ -350,6 +351,9 @@ class AuditToPolicy: +@@ -350,6 +349,9 @@ class AuditToPolicy: except ValueError, e: print e sys.exit(1) @@ -249387,13 +249369,14 @@ index 521afcd..0c8cd1e 100644 .SH "SEE ALSO" .TP diff --git a/policycoreutils/sandbox/sandboxX.sh b/policycoreutils/sandbox/sandboxX.sh -index 23de6f6..171bb05 100644 +index 23de6f6..eaa500d 100644 --- a/policycoreutils/sandbox/sandboxX.sh +++ b/policycoreutils/sandbox/sandboxX.sh -@@ -6,6 +6,20 @@ export TITLE="Sandbox $context -- `grep ^#TITLE: ~/.sandboxrc | /usr/bin/cut -b8 +@@ -6,7 +6,21 @@ export TITLE="Sandbox $context -- `grep ^#TITLE: ~/.sandboxrc | /usr/bin/cut -b8 [ -z $2 ] && export DPI="96" || export DPI="$2" trap "exit 0" HUP +-(/usr/bin/Xephyr -title "$TITLE" -terminate -screen $SCREENSIZE -dpi $DPI -nolisten tcp -displayfd 5 5>&1 2>/dev/null) | while read D; do +mkdir -p ~/.config/openbox +cat > ~/.config/openbox/rc.xml << EOF + +EOF + - (/usr/bin/Xephyr -title "$TITLE" -terminate -screen $SCREENSIZE -dpi $DPI -nolisten tcp -displayfd 5 5>&1 2>/dev/null) | while read D; do ++(/usr/bin/Xephyr -resizeable -title "$TITLE" -terminate -screen $SCREENSIZE -dpi $DPI -nolisten tcp -displayfd 5 5>&1 2>/dev/null) | while read D; do export DISPLAY=:$D cat > ~/seremote << __EOF + #!/bin/sh diff --git a/policycoreutils/sandbox/seunshare.c b/policycoreutils/sandbox/seunshare.c index dbd5977..b3f1275 100644 --- a/policycoreutils/sandbox/seunshare.c @@ -250886,7 +250870,7 @@ index b6abdf5..c05c943 100644 Generate an additional HTML man pages for the specified domain(s). diff --git a/policycoreutils/sepolicy/sepolicy.py b/policycoreutils/sepolicy/sepolicy.py -index b25d3b2..7ca5554 100755 +index b25d3b2..a0b262b 100755 --- a/policycoreutils/sepolicy/sepolicy.py +++ b/policycoreutils/sepolicy/sepolicy.py @@ -22,6 +22,8 @@ @@ -251101,7 +251085,7 @@ index b25d3b2..7ca5554 100755 help=_("boolean to get description")) bools.set_defaults(func=booleans) -@@ -319,22 +365,50 @@ def gen_transition_args(parser): +@@ -319,22 +365,49 @@ def gen_transition_args(parser): help=_("target process domain")) trans.set_defaults(func=transition) @@ -251123,22 +251107,21 @@ index b25d3b2..7ca5554 100755 + def interface(args): - from sepolicy.interface import get_admin, get, get_user -+ from sepolicy.interface import get_admin, get_user -+ from sepolicy import get_methods ++ from sepolicy.interface import get_admin, get_user, get_interface_dict, get_all_interfaces if args.list_admin: - for a in get_admin(): - print a -+ print_interfaces(get_admin(), args, "_admin") ++ print_interfaces(get_admin(args.file), args, "_admin") if args.list_user: - for a in get_user(): - print a -+ print_interfaces(get_user(), args, "_role") ++ print_interfaces(get_user(args.file), args, "_role") if args.list: - for m in get(): - print m -+ print_interfaces(get_methods(), args) ++ print_interfaces(get_all_interfaces(args.file), args) + if args.interfaces: -+ print_interfaces(args.interfaces, args) ++ print_interfaces(args.interfaces, args) def generate(args): - from sepolicy.generate import policy, USERS, SANDBOX, APPLICATIONS, NEWTYPE @@ -251161,7 +251144,7 @@ index b25d3b2..7ca5554 100755 if not args.command: raise ValueError(_("Command required for this type of policy")) cmd = os.path.realpath(args.command) -@@ -346,8 +420,18 @@ def generate(args): +@@ -346,8 +419,18 @@ def generate(args): mypolicy.set_program(cmd) if args.types: @@ -251180,7 +251163,7 @@ index b25d3b2..7ca5554 100755 for p in args.writepaths: if os.path.isdir(p): mypolicy.add_dir(p) -@@ -366,20 +450,32 @@ def generate(args): +@@ -366,20 +449,34 @@ def generate(args): def gen_interface_args(parser): itf = parser.add_parser("interface", help=_('List SELinux Policy interfaces')) @@ -251190,6 +251173,8 @@ index b25d3b2..7ca5554 100755 + itf.add_argument("-v", "--verbose", dest="verbose", + action="store_true", default=False, + help="Show verbose information") ++ itf.add_argument("-f", "--file", dest="file", ++ help="Interface file") group = itf.add_mutually_exclusive_group(required=True) group.add_argument("-a", "--list_admin", dest="list_admin",action="store_true", default=False, - help="List all domains with admin interface") @@ -251216,7 +251201,7 @@ index b25d3b2..7ca5554 100755 help=_('Generate SELinux Policy module template')) pol.add_argument("-d", "--domain", dest="domain", default=[], action=CheckDomain, nargs="*", -@@ -397,53 +493,57 @@ def gen_generate_args(parser): +@@ -397,53 +494,57 @@ def gen_generate_args(parser): help=argparse.SUPPRESS) pol.add_argument("-t", "--type", dest="types", default=[], nargs="*", action=CheckType, @@ -251300,7 +251285,7 @@ index b25d3b2..7ca5554 100755 pol.set_defaults(func=generate) if __name__ == '__main__': -@@ -461,11 +561,17 @@ if __name__ == '__main__': +@@ -461,11 +562,17 @@ if __name__ == '__main__': gen_transition_args(subparsers) try: @@ -251320,7 +251305,7 @@ index b25d3b2..7ca5554 100755 except KeyboardInterrupt: sys.exit(0) diff --git a/policycoreutils/sepolicy/sepolicy/__init__.py b/policycoreutils/sepolicy/sepolicy/__init__.py -index 5e7415c..3f0372c 100644 +index 5e7415c..a24063a 100644 --- a/policycoreutils/sepolicy/sepolicy/__init__.py +++ b/policycoreutils/sepolicy/sepolicy/__init__.py @@ -7,6 +7,9 @@ import _policy @@ -251472,7 +251457,7 @@ index 5e7415c..3f0372c 100644 return all_domains roles = None -@@ -139,48 +235,48 @@ def get_all_attributes(): +@@ -139,50 +235,51 @@ def get_all_attributes(): return all_attributes def policy(policy_file): @@ -251545,7 +251530,21 @@ index 5e7415c..3f0372c 100644 + return booleans booleans_dict = None ++import gzip def gen_bool_dict(path="/usr/share/selinux/devel/policy.xml"): + global booleans_dict + if booleans_dict: +@@ -191,7 +288,9 @@ def gen_bool_dict(path="/usr/share/selinux/devel/policy.xml"): + import re + booleans_dict = {} + try: +- tree = xml.etree.ElementTree.parse(path) ++ fd = gzip.open(path) ++ tree = xml.etree.ElementTree.fromstring(fd.read()) ++ fd.close() + for l in tree.findall("layer"): + for m in l.findall("module"): + for b in m.findall("tunable"): diff --git a/policycoreutils/sepolicy/sepolicy/communicate.py b/policycoreutils/sepolicy/sepolicy/communicate.py index a179d95..9b9a09a 100755 --- a/policycoreutils/sepolicy/sepolicy/communicate.py @@ -251715,7 +251714,7 @@ index 26f8390..4739025 100644 tmp = re.sub("TEMPLATETYPE", self.name, script.admin_trans) newsh += re.sub("USER", u, tmp) diff --git a/policycoreutils/sepolicy/sepolicy/interface.py b/policycoreutils/sepolicy/sepolicy/interface.py -index 8b063ca..407ce20 100644 +index 8b063ca..c7dac62 100644 --- a/policycoreutils/sepolicy/sepolicy/interface.py +++ b/policycoreutils/sepolicy/sepolicy/interface.py @@ -21,15 +21,13 @@ @@ -251734,11 +251733,11 @@ index 8b063ca..407ce20 100644 +import selinux -__all__ = [ 'get', 'get_admin', 'get_user' ] -+__all__ = [ 'get_admin', 'get_user' ,'get_interface_dict', 'get_interface_format_text', 'get_interface_compile_format_text', 'interface_compile_test' ] ++__all__ = [ 'get_all_interfaces', 'get_interfaces_from_xml', 'get_admin', 'get_user' ,'get_interface_dict', 'get_interface_format_text', 'get_interface_compile_format_text', 'get_xml_file', 'interface_compile_test' ] ## ## I18N -@@ -48,24 +46,10 @@ except IOError: +@@ -48,34 +46,173 @@ except IOError: import __builtin__ __builtin__.__dict__['_'] = unicode @@ -251756,38 +251755,108 @@ index 8b063ca..407ce20 100644 - - return methods - - def get_admin(): - """ Get all domains with an admin interface""" +-def get_admin(): +- """ Get all domains with an admin interface""" ++def get_interfaces_from_xml(path): ++ """ Get all interfaces from given xml file""" ++ interfaces_list = [] ++ interface_dict = get_interface_dict(path) ++ for k in interface_dict.keys(): ++ interfaces_list.append(k) ++ return interfaces_list ++ ++ ++def get_all_interfaces(path=""): ++ from sepolicy import get_methods ++ all_interfaces = [] ++ if not path: ++ all_interfaces = get_methods() ++ else: ++ xml_path = get_xml_file(path) ++ all_interfaces = get_interfaces_from_xml(xml_path) ++ ++ return all_interfaces ++ ++def get_admin(path=""): ++ """ Get all domains with an admin interface from installed policy.""" ++ """ If xml_path is specified, func returns an admin interface from specified xml file""" admin_list = [] - for i in get(): -+ for i in sepolicy.get_methods(): - if i.endswith("_admin"): - admin_list.append(i.split("_admin")[0]) +- if i.endswith("_admin"): +- admin_list.append(i.split("_admin")[0]) ++ if path: ++ try: ++ xml_path = get_xml_file(path) ++ interface_dict = get_interface_dict(xml_path) ++ for k in interface_dict.keys(): ++ if k.endswith("_admin"): ++ admin_list.append(k) ++ except IOError, e: ++ sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) ++ sys.exit(1) ++ else: ++ for i in sepolicy.get_methods(): ++ if i.endswith("_admin"): ++ admin_list.append(i.split("_admin")[0]) ++ return admin_list -@@ -73,9 +57,87 @@ def get_admin(): - def get_user(): + +-def get_user(): ++def get_user(path=""): """ Get all domains with SELinux user role interface""" ++ """ If xml_path is specified, func returns an user role interface from specified xml file""" trans_list = [] - for i in get(): -+ for i in sepolicy.get_methods(): - m = re.findall("(.*)%s" % USER_TRANSITION_INTERFACE, i) - if len(m) > 0: +- m = re.findall("(.*)%s" % USER_TRANSITION_INTERFACE, i) +- if len(m) > 0: - if "%s_exec_t" % m[0] in get_all_types(): -+ if "%s_exec_t" % m[0] in sepolicy.get_all_types(): - trans_list.append(m[0]) +- trans_list.append(m[0]) ++ if path: ++ try: ++ xml_path = get_xml_file(path) ++ interface_dict = get_interface_dict(xml_path) ++ for k in interface_dict.keys(): ++ if k.endswith("_role"): ++ if (("%s_exec_t" % k[:-5]) in sepolicy.get_all_types()): ++ trans_list.append(k) ++ except IOError, e: ++ sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) ++ sys.exit(1) ++ else: ++ for i in sepolicy.get_methods(): ++ m = re.findall("(.*)%s" % USER_TRANSITION_INTERFACE, i) ++ if len(m) > 0: ++ if "%s_exec_t" % m[0] in sepolicy.get_all_types(): ++ trans_list.append(m[0]) ++ return trans_list + +interface_dict = None -+def get_interface_dict(path = "/usr/share/selinux/devel/policy.xml"): ++def get_interface_dict(path="/usr/share/selinux/devel/policy.xml"): + global interface_dict ++ import os + import xml.etree.ElementTree + if interface_dict: + return interface_dict + + interface_dict = {} + param_list = [] ++ ++ xml_path = """ ++ ++ ++""" ++ xml_path += path ++ xml_path +=""" ++ ++ ++""" ++ + try: -+ tree = xml.etree.ElementTree.parse(path) ++ if os.path.isfile(path): ++ tree = xml.etree.ElementTree.parse(path) ++ else: ++ tree = xml.etree.ElementTree.fromstring(xml_path) + for l in tree.findall("layer"): + for m in l.findall("module"): + for i in m.getiterator('interface'): @@ -251827,38 +251896,51 @@ index 8b063ca..407ce20 100644 + + return te + ++def get_xml_file(if_file): ++ """ Returns xml format of interfaces for given .if policy file""" ++ import os, commands ++ basedir = os.path.dirname(if_file)+"/" ++ filename = os.path.basename(if_file).split(".")[0] ++ rc, output=commands.getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir+filename) ++ if rc != 0: ++ sys.stderr.write("\n Could not proceed selected interface file.\n") ++ sys.stderr.write("\n%s" % output) ++ sys.exit(1) ++ else: ++ return output ++ +def interface_compile_test(interface, path = "/usr/share/selinux/devel/policy.xml"): + exclude_interfaces = ["userdom","kernel","corenet","files", "dev"] + exclude_interface_type = ["template"] + + import commands, os -+ te = "compiletest.te" -+ pp = "compiletest.pp" ++ policy_files = {'pp':"compiletest.pp", 'te':"compiletest.te", 'fc':"compiletest.fc", 'if':"compiletest.if"} + interface_dict = get_interface_dict(path) + + if not (interface.split("_")[0] in exclude_interfaces or interface_dict[interface][2] in exclude_interface_type): + print(_("Compiling %s interface" % interface)) + try: -+ fd = open(te, "w") ++ fd = open(policy_files['te'], "w") + fd.write(generate_compile_te(interface, interface_dict)) + fd.close() -+ rc, output=commands.getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % pp ) ++ rc, output=commands.getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'] ) + if rc != 0: + sys.stderr.write(output) + sys.stderr.write(_("\nCompile test for %s failed.\n") % interface) + + except EnvironmentError, e: + sys.stderr.write(_("\nCompile test for %s has not run.\n") % interface) -+ if os.path.exists(te): -+ os.remove(te) ++ for v in policy_files.values(): ++ if os.path.exists(v): ++ os.remove(v) + + else: + sys.stderr.write(_("\nCompiling of %s interface is not supported." % interface)) diff --git a/policycoreutils/sepolicy/sepolicy/manpage.py b/policycoreutils/sepolicy/sepolicy/manpage.py -index 25062da..63efc6d 100755 +index 25062da..c4e1970 100755 --- a/policycoreutils/sepolicy/sepolicy/manpage.py +++ b/policycoreutils/sepolicy/sepolicy/manpage.py -@@ -28,12 +28,12 @@ import string +@@ -28,15 +28,16 @@ import string import argparse import selinux import sepolicy @@ -251873,7 +251955,22 @@ index 25062da..63efc6d 100755 equiv_dirs=[ "/var" ] modules_dict = None -@@ -100,8 +100,8 @@ def gen_domains(): ++import gzip + def gen_modules_dict(path = "/usr/share/selinux/devel/policy.xml"): + global modules_dict + if modules_dict: +@@ -45,7 +46,9 @@ def gen_modules_dict(path = "/usr/share/selinux/devel/policy.xml"): + import xml.etree.ElementTree + modules_dict = {} + try: +- tree = xml.etree.ElementTree.parse(path) ++ fd = gzip.open(path) ++ tree = xml.etree.ElementTree.fromstring(fd.read()) ++ fd.close() + for l in tree.findall("layer"): + for m in l.findall("module"): + name = m.get("name") +@@ -100,8 +103,8 @@ def gen_domains(): for d in get_all_domains(): found = False domain = d[:-2] @@ -251884,7 +251981,7 @@ index 25062da..63efc6d 100755 if domain in domains: continue domains.append(domain) -@@ -184,14 +184,12 @@ def get_alphabet_manpages(manpage_list): +@@ -184,14 +187,12 @@ def get_alphabet_manpages(manpage_list): return alphabet_manpages def convert_manpage_to_html(html_manpage,manpage): @@ -251903,7 +252000,7 @@ index 25062da..63efc6d 100755 class HTMLManPages: """ -@@ -416,40 +414,33 @@ class ManPage: +@@ -416,40 +417,33 @@ class ManPage: """ Generate a Manpage on an SELinux domain in the specified path """ @@ -251962,7 +252059,7 @@ index 25062da..63efc6d 100755 self.booleans_dict = gen_bool_dict(self.xmlpath) if domainname.endswith("_t"): -@@ -459,13 +450,16 @@ class ManPage: +@@ -459,13 +453,16 @@ class ManPage: if self.domainname + "_t" not in self.all_domains: raise ValueError("domain %s_t does not exist" % self.domainname) @@ -251981,7 +252078,7 @@ index 25062da..63efc6d 100755 self.__gen_user_man_page() if self.html: manpage_roles.append(self.man_page_path) -@@ -483,16 +477,23 @@ class ManPage: +@@ -483,16 +480,23 @@ class ManPage: def _gen_bools(self): self.bools=[] self.domainbools=[] @@ -252015,7 +252112,7 @@ index 25062da..63efc6d 100755 self.bools.sort() self.domainbools.sort() -@@ -538,9 +539,6 @@ class ManPage: +@@ -538,9 +542,6 @@ class ManPage: print path def __gen_man_page(self): @@ -252025,7 +252122,7 @@ index 25062da..63efc6d 100755 self.anon_list = [] self.attributes = {} -@@ -563,22 +561,11 @@ class ManPage: +@@ -563,22 +564,11 @@ class ManPage: def _get_ptypes(self): for f in self.all_domains: @@ -252051,7 +252148,7 @@ index 25062da..63efc6d 100755 % {'domainname':self.domainname, 'date': time.strftime("%y-%m-%d")}) self.fd.write(r""" .SH "NAME" -@@ -774,7 +761,7 @@ can be used to make the process type %(domainname)s_t permissive. SELinux does n +@@ -774,7 +764,7 @@ can be used to make the process type %(domainname)s_t permissive. SELinux does n def _port_types(self): self.ports = [] for f in self.all_port_types: @@ -252060,7 +252157,7 @@ index 25062da..63efc6d 100755 self.ports.append(f) if len(self.ports) == 0: -@@ -923,13 +910,12 @@ to apply the labels. +@@ -923,13 +913,12 @@ to apply the labels. def _see_also(self): ret = "" @@ -252076,7 +252173,7 @@ index 25062da..63efc6d 100755 ret += ", %s_selinux(8)" % d self.fd.write(ret) -@@ -947,13 +933,14 @@ semanage fcontext -a -t public_content_t "/var/%(domainname)s(/.*)?" +@@ -947,13 +936,14 @@ semanage fcontext -a -t public_content_t "/var/%(domainname)s(/.*)?" .B restorecon -F -R -v /var/%(domainname)s .pp .TP @@ -252093,7 +252190,7 @@ index 25062da..63efc6d 100755 """ % {'domainname':self.domainname}) for b in self.anon_list: desc = self.booleans_dict[b][2][0].lower() + self.booleans_dict[b][2][1:] -@@ -998,12 +985,11 @@ is a GUI tool available to customize SELinux policy settings. +@@ -998,12 +988,11 @@ is a GUI tool available to customize SELinux policy settings. .SH AUTHOR This manual page was auto-generated using @@ -252108,7 +252205,7 @@ index 25062da..63efc6d 100755 if self.booltext != "": self.fd.write(", setsebool(8)") -@@ -1230,6 +1216,7 @@ The SELinux user %s_u is not able to terminal login. +@@ -1230,6 +1219,7 @@ The SELinux user %s_u is not able to terminal login. """ % self.domainname) def _network(self): diff --git a/policycoreutils.spec b/policycoreutils.spec index 83f84ba..9f77ed9 100644 --- a/policycoreutils.spec +++ b/policycoreutils.spec @@ -7,7 +7,7 @@ Summary: SELinux policy core utilities Name: policycoreutils Version: 2.1.14 -Release: 40%{?dist} +Release: 42%{?dist} License: GPLv2 Group: System Environment/Base # Based on git repository with tag 20101221 @@ -160,7 +160,7 @@ The policycoreutils-devel package contains the management tools use to develop p Summary: SELinux sandbox utilities Group: System Environment/Base Requires: policycoreutils-python = %{version}-%{release} -Requires: xorg-x11-server-Xephyr /usr/bin/rsync /usr/bin/xmodmap +Requires: xorg-x11-server-Xephyr >= 1.14.1-2 /usr/bin/rsync /usr/bin/xmodmap Requires: openbox BuildRequires: openbox BuildRequires: libcap-ng-devel @@ -315,10 +315,19 @@ The policycoreutils-restorecond package contains the restorecond service. %{_bindir}/systemctl try-restart restorecond.service >/dev/null 2>&1 || : %changelog -* Mon May 11 2013 Dan Walsh - 2.1.14-40 +* Tue May 14 2013 Dan Walsh - 2.1.14-42 +- Add support for Xephyr -resizable, so sandbox can now resize window +- Add support for compressed policy.xml +- Miroslav Grepl patch to allow sepolicy interface on individual interface fil +- Also add capability to test interfaces for correctness. + +* Mon May 13 2013 Dan Walsh - 2.1.14-41 +- Apply patches from Sven Vermeulen for sepolgen to fix typos. + +* Mon May 13 2013 Dan Walsh - 2.1.14-40 - Only require selinux-policy-devel for policycoreutils-devel, this will shrink the size of the livecd. -* Sun May 10 2013 Dan Walsh - 2.1.14-39 +* Sun May 12 2013 Dan Walsh - 2.1.14-39 - Run sepolgen-ifgen in audit2allow and sepolicy generate, if needed, first time - Add Sven Vermeulen patches to cleanup man pages