From 1cc95772be12520bd9dde99d6bf3baf67a04a6f7 Mon Sep 17 00:00:00 2001 From: rhatdan Date: Thu, 1 Nov 2012 14:36:52 -0400 Subject: [PATCH] Fix some build problems in sepolicy manpage and sepolicy transition --- policycoreutils-rhat.patch | 1174 ++++++++++++++++++------------------ policycoreutils.spec | 5 +- 2 files changed, 600 insertions(+), 579 deletions(-) diff --git a/policycoreutils-rhat.patch b/policycoreutils-rhat.patch index 156f3fc..9a48d6b 100644 --- a/policycoreutils-rhat.patch +++ b/policycoreutils-rhat.patch @@ -341594,10 +341594,10 @@ index 0000000..13d7a56 + diff --git a/policycoreutils/sepolicy/sepolicy-generate.8 b/policycoreutils/sepolicy/sepolicy-generate.8 new file mode 100644 -index 0000000..22876a0 +index 0000000..a592d85 --- /dev/null +++ b/policycoreutils/sepolicy/sepolicy-generate.8 -@@ -0,0 +1,99 @@ +@@ -0,0 +1,106 @@ +.TH "sepolicy-generate" "8" "20121005" "" "" +.SH "NAME" +sepolicy-generate \- Generate an initial SELinux policy module template. @@ -341623,9 +341623,14 @@ index 0000000..22876a0 +This file defines the default file context for the system, it takes the file types created in the te file and associates +file paths to the types. Tools like restorecon and RPM will use these paths to put down labels. + ++.B RPM Spec File NAME_selinux.spec ++.br ++This file is an RPM SPEC file that can be used to install the SELinux policy on to machines and setup the labeling. The spec file also installs the interface file and a man page describing the policy. You can use sepolicy manpage -d NAME to generate the man page. ++ +.B Shell File NAME.sh +.br -+This is a helper shell script to compile, install and fix the labeling on your test system. ++This is a helper shell script to compile, install and fix the labeling on your test system. It will also generate a man page based on the installed policy, and ++compile and build an RPM suitable to be installed on other machines + +If a generate is possible, this tool will print out all generate paths from the source domain to the target domain + @@ -341676,7 +341681,7 @@ index 0000000..22876a0 +Specify alternate name of policy. The policy will default to the executable or name specified. + +.SH "EXAMPLE" -+.B sepolicy generate /usr/sbin/rwhod ++.B > sepolicy generate /usr/sbin/rwhod +.br +Generating Policy for /usr/sbin/rwhod named rwhod +.br @@ -341690,6 +341695,8 @@ index 0000000..22876a0 +.br +rwhod.fc # File Contexts file +.br ++rwhod_selinux.spec # Spec file ++.br +rwhod.sh # Setup Script + +.SH "AUTHOR" @@ -343679,10 +343686,10 @@ index 0000000..93b0762 + return out diff --git a/policycoreutils/sepolicy/sepolicy/manpage.py b/policycoreutils/sepolicy/sepolicy/manpage.py new file mode 100755 -index 0000000..94d89b2 +index 0000000..e3f9b70 --- /dev/null +++ b/policycoreutils/sepolicy/sepolicy/manpage.py -@@ -0,0 +1,1287 @@ +@@ -0,0 +1,1297 @@ +#! /usr/bin/python -Es +# Copyright (C) 2012 Red Hat +# AUTHOR: Dan Walsh @@ -343717,141 +343724,141 @@ index 0000000..94d89b2 +import commands +import sys, os, re, time + -+equiv_dict={ "smbd" : ( "samba" ), "httpd" : ( "apache" ), "virtd" : ( "virt", "libvirtd" ) } ++equiv_dict={ "smbd" : ( "samba" ), "httpd" : ( "apache" ), "virtd" : ( "virt", "libvirt" ) } + ++modules_dict = None +def _gen_modules_dict(): -+ import xml.etree.ElementTree -+ modules_dict = {} -+ try: -+ tree = xml.etree.ElementTree.parse("/usr/share/selinux/devel/policy.xml") -+ for l in tree.findall("layer"): -+ for m in l.findall("module"): -+ name = m.get("name") -+ if name == "user" or name == "unconfined": -+ continue -+ if name == "unprivuser": -+ name = "user" -+ if name == "unconfineduser": -+ name = "unconfined" -+ for b in m.findall("summary"): -+ modules_dict[name] = b.text -+ except IOError, e: -+ pass -+ return modules_dict -+modules_dict = _gen_modules_dict() ++ import xml.etree.ElementTree ++ modules_dict = {} ++ try: ++ tree = xml.etree.ElementTree.parse("/usr/share/selinux/devel/policy.xml") ++ for l in tree.findall("layer"): ++ for m in l.findall("module"): ++ name = m.get("name") ++ if name == "user" or name == "unconfined": ++ continue ++ if name == "unprivuser": ++ name = "user" ++ if name == "unconfineduser": ++ name = "unconfined" ++ for b in m.findall("summary"): ++ modules_dict[name] = b.text ++ except IOError, e: ++ pass ++ return modules_dict + +all_attributes = map(lambda x: x['name'], sepolicy.info(sepolicy.ATTRIBUTE)) +entrypoints = sepolicy.info(sepolicy.ATTRIBUTE,"entry_type")[0]["types"] +alldomains = sepolicy.info(sepolicy.ATTRIBUTE,"domain")[0]["types"] + +def _gen_fcdict(): -+ fc_path = selinux.selinux_file_context_path() -+ fd = open(selinux.selinux_file_context_path(), "r") -+ fc = fd.readlines() -+ fd.close() -+ fd = open(selinux.selinux_file_context_path()+".homedirs", "r") -+ fc += fd.readlines() -+ fd.close() -+ fcdict = {} -+ for i in fc: -+ rec = i.split() -+ try: -+ t = rec[-1].split(":")[2] -+ if t in fcdict: -+ fcdict[t].append(rec[0]) -+ else: -+ fcdict[t] = [ rec[0] ] -+ except: -+ pass -+ fcdict["logfile"] = [ "all log files" ] -+ fcdict["user_tmp_type"] = [ "all user tmp files" ] -+ fcdict["user_home_type"] = [ "all user home files" ] -+ fcdict["virt_image_type"] = [ "all virtual image files" ] -+ fcdict["noxattrfs"] = [ "all files on file systems which do not support extended attributes" ] -+ fcdict["sandbox_tmpfs_type"] = [ "all sandbox content in tmpfs file systems" ] -+ fcdict["user_tmpfs_type"] = [ "all user content in tmpfs file systems" ] -+ fcdict["file_type"] = [ "all files on the system" ] -+ fcdict["samba_share_t"] = [ "use this label for random content that will be shared using samba" ] -+ return fcdict ++ fc_path = selinux.selinux_file_context_path() ++ fd = open(selinux.selinux_file_context_path(), "r") ++ fc = fd.readlines() ++ fd.close() ++ fd = open(selinux.selinux_file_context_path()+".homedirs", "r") ++ fc += fd.readlines() ++ fd.close() ++ fcdict = {} ++ for i in fc: ++ rec = i.split() ++ try: ++ t = rec[-1].split(":")[2] ++ if t in fcdict: ++ fcdict[t].append(rec[0]) ++ else: ++ fcdict[t] = [ rec[0] ] ++ except: ++ pass ++ fcdict["logfile"] = [ "all log files" ] ++ fcdict["user_tmp_type"] = [ "all user tmp files" ] ++ fcdict["user_home_type"] = [ "all user home files" ] ++ fcdict["virt_image_type"] = [ "all virtual image files" ] ++ fcdict["noxattrfs"] = [ "all files on file systems which do not support extended attributes" ] ++ fcdict["sandbox_tmpfs_type"] = [ "all sandbox content in tmpfs file systems" ] ++ fcdict["user_tmpfs_type"] = [ "all user content in tmpfs file systems" ] ++ fcdict["file_type"] = [ "all files on the system" ] ++ fcdict["samba_share_t"] = [ "use this label for random content that will be shared using samba" ] ++ return fcdict +fcdict = _gen_fcdict() + +def _gen_role_allows(): -+ role_allows = {} -+ for r in sepolicy.search([sepolicy.ROLE_ALLOW]): -+ if r["source"] == "system_r" or r["target"] == "system_r": -+ continue -+ if r["source"] in role_allows: -+ role_allows[r["source"]].append(r["target"]) -+ else: -+ role_allows[r["source"]] = [ r["target"] ] ++ role_allows = {} ++ for r in sepolicy.search([sepolicy.ROLE_ALLOW]): ++ if r["source"] == "system_r" or r["target"] == "system_r": ++ continue ++ if r["source"] in role_allows: ++ role_allows[r["source"]].append(r["target"]) ++ else: ++ role_allows[r["source"]] = [ r["target"] ] + -+ return role_allows ++ return role_allows +role_allows = _gen_role_allows() + +def _gen_roles(): -+ roles = [] -+ allroles = map(lambda x: x['name'], sepolicy.info(sepolicy.ROLE)) -+ for r in allroles: -+ if r not in [ "system_r", "object_r" ]: -+ roles.append(r[:-2]) -+ return roles ++ roles = [] ++ allroles = map(lambda x: x['name'], sepolicy.info(sepolicy.ROLE)) ++ for r in allroles: ++ if r not in [ "system_r", "object_r" ]: ++ roles.append(r[:-2]) ++ return roles + +roles = _gen_roles() + +def _gen_domains(): -+ domains = [] -+ for d in alldomains: -+ found = False -+ domain = d[:-2] -+ if domain + "_exec_t" not in entrypoints: -+ continue -+ if domain in domains: -+ continue -+ domains.append(domain) ++ domains = [] ++ for d in alldomains: ++ found = False ++ domain = d[:-2] ++ if domain + "_exec_t" not in entrypoints: ++ continue ++ if domain in domains: ++ continue ++ domains.append(domain) + -+ for role in roles: -+ if role in domains: -+ continue -+ domains.append(role) ++ for role in roles: ++ if role in domains: ++ continue ++ domains.append(role) + -+ domains.sort() -+ return domains ++ domains.sort() ++ return domains + +domains = _gen_domains() + +def _gen_users(): -+ users = [] -+ allusers = map(lambda x: x['name'], sepolicy.info(sepolicy.USER)) -+ for u in allusers: -+ if u not in [ "system_u", "root", "unconfined_u" ]: -+ users.append(u.replace("_u","")) -+ users.sort() -+ return users ++ users = [] ++ allusers = map(lambda x: x['name'], sepolicy.info(sepolicy.USER)) ++ for u in allusers: ++ if u not in [ "system_u", "root", "unconfined_u" ]: ++ users.append(u.replace("_u","")) ++ users.sort() ++ return users + +users = _gen_users() + +def _gen_types(): -+ all_types = sepolicy.info(sepolicy.TYPE) -+ types = {} -+ for rec in all_types: -+ try: -+ types[rec["name"]] = rec["attributes"] -+ except: -+ types[rec["name"]] = [] -+ return types ++ all_types = sepolicy.info(sepolicy.TYPE) ++ types = {} ++ for rec in all_types: ++ try: ++ types[rec["name"]] = rec["attributes"] ++ except: ++ types[rec["name"]] = [] ++ return types + +types = _gen_types() + +def _gen_file_types(): -+ file_types = sepolicy.info(sepolicy.ATTRIBUTE,"file_type")[0]["types"] -+ file_types.sort() -+ return file_types ++ file_types = sepolicy.info(sepolicy.ATTRIBUTE,"file_type")[0]["types"] ++ file_types.sort() ++ return file_types +file_types = _gen_file_types() + +def _gen_port_types(): -+ port_types = sepolicy.info(sepolicy.ATTRIBUTE,"port_type")[0]["types"] -+ port_types.sort() -+ return port_types ++ port_types = sepolicy.info(sepolicy.ATTRIBUTE,"port_type")[0]["types"] ++ port_types.sort() ++ return port_types +port_types = _gen_port_types() + +portrecs = network.portrecs @@ -343865,19 +343872,19 @@ index 0000000..94d89b2 + os_version = "" + pkg_name = "selinux-policy" + try: -+ import commands -+ rc, output = commands.getstatusoutput("rpm -q '%s'" % pkg_name) -+ if rc == 0: -+ os_version = output.split(".")[-2] ++ import commands ++ rc, output = commands.getstatusoutput("rpm -q '%s'" % pkg_name) ++ if rc == 0: ++ os_version = output.split(".")[-2] + except: -+ os_version = "" ++ os_version = "" + + if os_version[0:2] == "fc": -+ os_version = "Fedora"+os_version[2:] ++ os_version = "Fedora"+os_version[2:] + elif os_version[0:2] == "el": -+ os_version = "RHEL"+os_version[2:] ++ os_version = "RHEL"+os_version[2:] + else: -+ os_version = "" ++ os_version = "" + + return os_version + @@ -343891,71 +343898,71 @@ index 0000000..94d89b2 +rhel_releases = ["RHEL6","RHEL7"] + +def get_alphabet_manpages(manpage_list): -+ alphabet_manpages = dict.fromkeys(string.ascii_letters, []) -+ for i in string.ascii_letters: -+ temp = [] -+ for j in manpage_list: -+ if j.split("/")[-1][0] == i: -+ temp.append(j.split("/")[-1]) ++ alphabet_manpages = dict.fromkeys(string.ascii_letters, []) ++ for i in string.ascii_letters: ++ temp = [] ++ for j in manpage_list: ++ if j.split("/")[-1][0] == i: ++ temp.append(j.split("/")[-1]) + -+ alphabet_manpages[i] = temp ++ alphabet_manpages[i] = temp + -+ return alphabet_manpages ++ return alphabet_manpages + +def convert_manpage_to_html(html_manpage,manpage): -+ fd = open(html_manpage,'w') -+ rc, output = commands.getstatusoutput("man2html -r %s" % manpage) -+ if rc == 0: -+ fd.write(output) -+ else: -+ fd.write("Man page does not exist") ++ fd = open(html_manpage,'w') ++ rc, output = commands.getstatusoutput("man2html -r %s" % manpage) ++ if rc == 0: ++ fd.write(output) ++ else: ++ fd.write("Man page does not exist") + -+ fd.close() ++ fd.close() + +class HTMLManPages: -+ """ -+ Generate a HHTML Manpages on an given SELinux domains -+ """ ++ """ ++ Generate a HHTML Manpages on an given SELinux domains ++ """ + -+ def __init__(self, manpage_roles, manpage_domains, path, os_version): ++ def __init__(self, manpage_roles, manpage_domains, path, os_version): + -+ self.manpage_roles = get_alphabet_manpages(manpage_roles) -+ self.manpage_domains = get_alphabet_manpages(manpage_domains) -+ self.os_version = os_version -+ self.old_path = path + "/" -+ self.new_path = self.old_path + self.os_version+"/" ++ self.manpage_roles = get_alphabet_manpages(manpage_roles) ++ self.manpage_domains = get_alphabet_manpages(manpage_domains) ++ self.os_version = os_version ++ self.old_path = path + "/" ++ self.new_path = self.old_path + self.os_version+"/" + -+ if self.os_version in fedora_releases or rhel_releases: -+ self.__gen_html_manpages() -+ else: -+ print("SELinux HTML man pages can not be generated for this %s" % os_version) -+ exit(1) ++ if self.os_version in fedora_releases or rhel_releases: ++ self.__gen_html_manpages() ++ else: ++ print("SELinux HTML man pages can not be generated for this %s" % os_version) ++ exit(1) + -+ def __gen_html_manpages(self): -+ self._write_html_manpage() -+ self._gen_index() -+ self._gen_body() -+ self._gen_css() ++ def __gen_html_manpages(self): ++ self._write_html_manpage() ++ self._gen_index() ++ self._gen_body() ++ self._gen_css() + -+ def _write_html_manpage(self): -+ if not os.path.isdir(self.new_path): -+ os.mkdir(self.new_path) ++ def _write_html_manpage(self): ++ if not os.path.isdir(self.new_path): ++ os.mkdir(self.new_path) + -+ for domain in self.manpage_domains.values(): -+ if len(domain): -+ for d in domain: -+ convert_manpage_to_html((self.new_path+d.split("_selinux")[0]+".html"),self.old_path+d) ++ for domain in self.manpage_domains.values(): ++ if len(domain): ++ for d in domain: ++ convert_manpage_to_html((self.new_path+d.split("_selinux")[0]+".html"),self.old_path+d) + -+ for role in self.manpage_roles.values(): -+ if len(role): -+ for r in role: -+ convert_manpage_to_html((self.new_path+r.split("_selinux")[0]+".html"),self.old_path+r) ++ for role in self.manpage_roles.values(): ++ if len(role): ++ for r in role: ++ convert_manpage_to_html((self.new_path+r.split("_selinux")[0]+".html"),self.old_path+r) + + -+ def _gen_index(self): -+ index = self.old_path+"index.html" -+ fd = open(index,'w') -+ fd.write(""" ++ def _gen_index(self): ++ index = self.old_path+"index.html" ++ fd = open(index,'w') ++ fd.write(""" + + + @@ -343974,11 +343981,11 @@ index 0000000..94d89b2 + +
 +""")
-+                for f in fedora_releases:
-+                        fd.write("""
++		for f in fedora_releases:
++			fd.write("""
 +%s - SELinux man pages for %s """  % (f,f,f,f))
 +
-+                fd.write("""
++		fd.write("""
 +
+
+

RHEL

@@ -343988,24 +343995,24 @@ index 0000000..94d89b2 + +
 +""")
-+                for r in rhel_releases:
-+                        fd.write("""
++		for r in rhel_releases:
++			fd.write("""
 +%s - SELinux man pages for %s """ % (r,r,r,r))
 +
-+                fd.write("""
++		fd.write("""
 +
-+ """) -+ fd.close() -+ print("%s has been created") % index ++ """) ++ fd.close() ++ print("%s has been created") % index + -+ def _gen_body(self): -+ html = self.new_path+self.os_version+".html" -+ fd = open(html,'w') -+ fd.write(""" ++ def _gen_body(self): ++ html = self.new_path+self.os_version+".html" ++ fd = open(html,'w') ++ fd.write(""" + + -+ -+ Linux man-pages online for Fedora18 ++ ++ Linux man-pages online for Fedora18 + + +

SELinux man pages for Fedora18

@@ -344014,26 +344021,26 @@ index 0000000..94d89b2 + +

SELinux roles

+""") -+ for letter in self.manpage_roles: -+ if len(self.manpage_roles[letter]): -+ fd.write(""" ++ for letter in self.manpage_roles: ++ if len(self.manpage_roles[letter]): ++ fd.write(""" +%s""" -+ % (letter,letter)) ++ % (letter,letter)) + -+ fd.write(""" ++ fd.write(""" + + +
 +""")
-+                rolename_body = ""
-+                for letter in self.manpage_roles:
-+                        if len(self.manpage_roles[letter]):
-+                                rolename_body += "

" -+ for r in self.manpage_roles[letter]: -+ rolename = r.split("_selinux")[0] -+ rolename_body += "%s_selinux(8) - Security Enhanced Linux Policy for the %s SELinux user\n" % (letter,rolename,rolename,rolename) ++ rolename_body = "" ++ for letter in self.manpage_roles: ++ if len(self.manpage_roles[letter]): ++ rolename_body += "

" ++ for r in self.manpage_roles[letter]: ++ rolename = r.split("_selinux")[0] ++ rolename_body += "%s_selinux(8) - Security Enhanced Linux Policy for the %s SELinux user\n" % (letter,rolename,rolename,rolename) + -+ fd.write("""%s ++ fd.write("""%s +

+
+ @@ -344041,38 +344048,38 @@ index 0000000..94d89b2 +

SELinux domains

""" +% rolename_body) + -+ for letter in self.manpage_domains: -+ if len(self.manpage_domains[letter]): -+ fd.write(""" ++ for letter in self.manpage_domains: ++ if len(self.manpage_domains[letter]): ++ fd.write(""" +%s -+ """ % (letter,letter)) ++ """ % (letter,letter)) + -+ fd.write(""" ++ fd.write(""" + +
+
 +""")
-+                domainname_body = ""
-+                for letter in self.manpage_domains:
-+                        if len(self.manpage_domains[letter]):
-+                                domainname_body += "

" -+ for r in self.manpage_domains[letter]: -+ domainname = r.split("_selinux")[0] -+ domainname_body += "%s_selinux(8) - Security Enhanced Linux Policy for the %s SELinux processes\n" % (letter,domainname,domainname,domainname) ++ domainname_body = "" ++ for letter in self.manpage_domains: ++ if len(self.manpage_domains[letter]): ++ domainname_body += "

" ++ for r in self.manpage_domains[letter]: ++ domainname = r.split("_selinux")[0] ++ domainname_body += "%s_selinux(8) - Security Enhanced Linux Policy for the %s SELinux processes\n" % (letter,domainname,domainname,domainname) + -+ fd.write("""%s ++ fd.write("""%s +

+ + +""" % domainname_body) + -+ fd.close() -+ print("%s has been created") % html ++ fd.close() ++ print("%s has been created") % html + -+ def _gen_css(self): -+ style_css = self.old_path+"style.css" -+ fd = open(style_css,'w') -+ fd.write(""" ++ def _gen_css(self): ++ style_css = self.old_path+"style.css" ++ fd = open(style_css,'w') ++ fd.write(""" +html, body { + background-color: #fcfcfc; + font-family: arial, sans-serif; @@ -344081,9 +344088,9 @@ index 0000000..94d89b2 +} + +h1, h2, h3, h4, h5, h5 { -+ color: #2d7c0b; -+ font-family: arial, sans-serif; -+ margin-top: 25px; ++ color: #2d7c0b; ++ font-family: arial, sans-serif; ++ margin-top: 25px; +} + +a { @@ -344129,30 +344136,37 @@ index 0000000..94d89b2 +} +""") + -+ fd.close() -+ print("%s has been created") % style_css ++ fd.close() ++ print("%s has been created") % style_css + +class ManPage: + """ -+ Generate a Manpage on an SELinux domain in the specified path ++ Generate a Manpage on an SELinux domain in the specified path + """ + def __init__(self, domainname, path = "/tmp", html = False): -+ self.html = html ++ self.html = html + self.path = path -+ self.domainname = domainname -+ self.short_name = domainname -+ self.type = self.domainname + "_t" -+ self.man_page_path = "%s/%s_selinux.8" % (path, domainname) -+ self.fd = open(self.man_page_path, 'w') -+ if domainname in roles: -+ self.__gen_user_man_page() -+ if self.html: -+ manpage_roles.append(self.man_page_path) -+ else: -+ if self.html: -+ manpage_domains.append(self.man_page_path) -+ self.__gen_man_page() -+ self.fd.close() ++ if domainname.endswith("_t"): ++ self.domainname = domainname[:-2] ++ else: ++ self.domainname = domainname ++ ++ if self.domainname + "_t" not in alldomains: ++ raise ValueError("domain %s_t does not exist" % self.domainname) ++ self.short_name = self.domainname ++ ++ self.type = self.domainname + "_t" ++ self.man_page_path = "%s/%s_selinux.8" % (path, self.domainname) ++ self.fd = open(self.man_page_path, 'w') ++ if domainname in roles: ++ self.__gen_user_man_page() ++ if self.html: ++ manpage_roles.append(self.man_page_path) ++ else: ++ if self.html: ++ manpage_domains.append(self.man_page_path) ++ self.__gen_man_page() ++ self.fd.close() + + for k in equiv_dict.keys(): + if k == self.domainname: @@ -344160,35 +344174,38 @@ index 0000000..94d89b2 + self.__gen_man_page_link(alias) + + def get_man_page_path(self): -+ return self.man_page_path ++ return self.man_page_path + + def __gen_user_man_page(self): -+ self.role = self.domainname + "_r" ++ self.role = self.domainname + "_r" ++ global modules_dict ++ if not modules_dict: ++ modules_dict = _gen_modules_dict() + -+ try: -+ self.desc = modules_dict[self.domainname] -+ except: -+ self.desc = "%s user role" % self.domainname ++ try: ++ self.desc = modules_dict[self.domainname] ++ except: ++ self.desc = "%s user role" % self.domainname + -+ if self.domainname in users: -+ self.attributes = sepolicy.info(sepolicy.TYPE,(self.type))[0]["attributes"] -+ self._user_header() -+ self._user_attribute() -+ self._can_sudo() -+ self._xwindows_login() -+ # until a new policy build with login_userdomain attribute -+ #self.terminal_login() -+ self._network() -+ self._booleans() -+ self._home_exec() -+ self._transitions() -+ else: -+ self._role_header() -+ self._booleans() ++ if self.domainname in users: ++ self.attributes = sepolicy.info(sepolicy.TYPE,(self.type))[0]["attributes"] ++ self._user_header() ++ self._user_attribute() ++ self._can_sudo() ++ self._xwindows_login() ++ # until a new policy build with login_userdomain attribute ++ #self.terminal_login() ++ self._network() ++ self._booleans() ++ self._home_exec() ++ self._transitions() ++ else: ++ self._role_header() ++ self._booleans() + -+ self._port_types() -+ self._writes() -+ self._footer() ++ self._port_types() ++ self._writes() ++ self._footer() + + def __gen_man_page_link(self, alias): + path = "%s/%s_selinux.8" % (self.path, alias) @@ -344198,49 +344215,49 @@ index 0000000..94d89b2 + print path + + def __gen_man_page(self): -+ if self.domainname[-1]=='d': -+ self.short_name = self.domainname[:-1] ++ if self.domainname[-1]=='d': ++ self.short_name = self.domainname[:-1] + -+ self.anon_list = [] ++ self.anon_list = [] + -+ self.attributes = {} -+ self.ptypes = [] -+ self._get_ptypes() ++ self.attributes = {} ++ self.ptypes = [] ++ self._get_ptypes() + -+ for domain_type in self.ptypes: -+ self.attributes[domain_type] = sepolicy.info(sepolicy.TYPE,("%s") % domain_type)[0]["attributes"] ++ for domain_type in self.ptypes: ++ self.attributes[domain_type] = sepolicy.info(sepolicy.TYPE,("%s") % domain_type)[0]["attributes"] + -+ self._header() -+ self._entrypoints() -+ self._process_types() -+ self._booleans() -+ self._public_content() -+ self._file_context() -+ self._port_types() -+ self._writes() -+ self._nsswitch_domain() -+ self._footer() ++ self._header() ++ self._entrypoints() ++ self._process_types() ++ self._booleans() ++ self._public_content() ++ self._file_context() ++ self._port_types() ++ self._writes() ++ self._nsswitch_domain() ++ self._footer() + + def _get_ptypes(self): -+ for f in alldomains: -+ if f.startswith(self.short_name): -+ self.ptypes.append(f) ++ for f in alldomains: ++ if f.startswith(self.short_name): ++ self.ptypes.append(f) + + def __whoami(self): -+ import pwd -+ fd = open("/proc/self/loginuid", "r") -+ uid = int(fd.read()) -+ fd.close() -+ pw = pwd.getpwuid(uid) -+ if len(pw.pw_gecos) > 0: -+ return pw.pw_gecos -+ else: -+ return pw.pw_name ++ import pwd ++ fd = open("/proc/self/loginuid", "r") ++ uid = int(fd.read()) ++ fd.close() ++ pw = pwd.getpwuid(uid) ++ if len(pw.pw_gecos) > 0: ++ return pw.pw_gecos ++ else: ++ return pw.pw_name + + def _header(self): -+ self.fd.write('.TH "%(domainname)s_selinux" "8" "%(date)s" "%(domainname)s" "SELinux Policy documentation for %(domainname)s"' -+ % {'domainname':self.domainname, 'date': time.strftime("%y-%m-%d")}) -+ self.fd.write(r""" ++ self.fd.write('.TH "%(domainname)s_selinux" "8" "%(date)s" "%(domainname)s" "SELinux Policy documentation for %(domainname)s"' ++ % {'domainname':self.domainname, 'date': time.strftime("%y-%m-%d")}) ++ self.fd.write(r""" +.SH "NAME" +%(domainname)s_selinux \- Security Enhanced Linux Policy for the %(domainname)s processes +.SH "DESCRIPTION" @@ -344257,108 +344274,108 @@ index 0000000..94d89b2 + + + def _explain(self, f): -+ if f.endswith("_var_run_t"): -+ return "store the %s files under the /run directory." % prettyprint(f, "_var_run_t") -+ if f.endswith("_pid_t"): -+ return "store the %s files under the /run directory." % prettyprint(f, "_pid_t") -+ if f.endswith("_var_lib_t"): -+ return "store the %s files under the /var/lib directory." % prettyprint(f, "_var_lib_t") -+ if f.endswith("_var_t"): -+ return "store the %s files under the /var directory." % prettyprint(f, "_var_lib_t") -+ if f.endswith("_var_spool_t"): -+ return "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t") -+ if f.endswith("_spool_t"): -+ return "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t") -+ if f.endswith("_cache_t") or f.endswith("_var_cache_t"): -+ return "store the files under the /var/cache directory." -+ if f.endswith("_keytab_t"): -+ return "treat the files as kerberos keytab files." -+ if f.endswith("_lock_t"): -+ return "treat the files as %s lock data, stored under the /var/lock directory" % prettyprint(f,"_lock_t") -+ if f.endswith("_log_t"): -+ return "treat the data as %s log data, usually stored under the /var/log directory." % prettyprint(f,"_log_t") -+ if f.endswith("_config_t"): -+ return "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_config_t") -+ if f.endswith("_conf_t"): -+ return "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_conf_t") -+ if f.endswith("_exec_t"): -+ return "transition an executable to the %s_t domain." % f[:-len("_exec_t")] -+ if f.endswith("_cgi_content_t"): -+ return "treat the files as %s cgi content." % prettyprint(f, "_cgi_content_t") -+ if f.endswith("_rw_content_t"): -+ return "treat the files as %s read/write content." % prettyprint(f,"_rw_content_t") -+ if f.endswith("_rw_t"): -+ return "treat the files as %s read/write content." % prettyprint(f,"_rw_t") -+ if f.endswith("_write_t"): -+ return "treat the files as %s read/write content." % prettyprint(f,"_write_t") -+ if f.endswith("_db_t"): -+ return "treat the files as %s database content." % prettyprint(f,"_db_t") -+ if f.endswith("_ra_content_t"): -+ return "treat the files as %s read/append content." % prettyprint(f,"_ra_conten_t") -+ if f.endswith("_cert_t"): -+ return "treat the files as %s certificate data." % prettyprint(f,"_cert_t") -+ if f.endswith("_key_t"): -+ return "treat the files as %s key data." % prettyprint(f,"_key_t") ++ if f.endswith("_var_run_t"): ++ return "store the %s files under the /run directory." % prettyprint(f, "_var_run_t") ++ if f.endswith("_pid_t"): ++ return "store the %s files under the /run directory." % prettyprint(f, "_pid_t") ++ if f.endswith("_var_lib_t"): ++ return "store the %s files under the /var/lib directory." % prettyprint(f, "_var_lib_t") ++ if f.endswith("_var_t"): ++ return "store the %s files under the /var directory." % prettyprint(f, "_var_lib_t") ++ if f.endswith("_var_spool_t"): ++ return "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t") ++ if f.endswith("_spool_t"): ++ return "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t") ++ if f.endswith("_cache_t") or f.endswith("_var_cache_t"): ++ return "store the files under the /var/cache directory." ++ if f.endswith("_keytab_t"): ++ return "treat the files as kerberos keytab files." ++ if f.endswith("_lock_t"): ++ return "treat the files as %s lock data, stored under the /var/lock directory" % prettyprint(f,"_lock_t") ++ if f.endswith("_log_t"): ++ return "treat the data as %s log data, usually stored under the /var/log directory." % prettyprint(f,"_log_t") ++ if f.endswith("_config_t"): ++ return "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_config_t") ++ if f.endswith("_conf_t"): ++ return "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_conf_t") ++ if f.endswith("_exec_t"): ++ return "transition an executable to the %s_t domain." % f[:-len("_exec_t")] ++ if f.endswith("_cgi_content_t"): ++ return "treat the files as %s cgi content." % prettyprint(f, "_cgi_content_t") ++ if f.endswith("_rw_content_t"): ++ return "treat the files as %s read/write content." % prettyprint(f,"_rw_content_t") ++ if f.endswith("_rw_t"): ++ return "treat the files as %s read/write content." % prettyprint(f,"_rw_t") ++ if f.endswith("_write_t"): ++ return "treat the files as %s read/write content." % prettyprint(f,"_write_t") ++ if f.endswith("_db_t"): ++ return "treat the files as %s database content." % prettyprint(f,"_db_t") ++ if f.endswith("_ra_content_t"): ++ return "treat the files as %s read/append content." % prettyprint(f,"_ra_conten_t") ++ if f.endswith("_cert_t"): ++ return "treat the files as %s certificate data." % prettyprint(f,"_cert_t") ++ if f.endswith("_key_t"): ++ return "treat the files as %s key data." % prettyprint(f,"_key_t") + -+ if f.endswith("_secret_t"): -+ return "treat the files as %s secret data." % prettyprint(f,"_key_t") ++ if f.endswith("_secret_t"): ++ return "treat the files as %s secret data." % prettyprint(f,"_key_t") + -+ if f.endswith("_ra_t"): -+ return "treat the files as %s read/append content." % prettyprint(f,"_ra_t") ++ if f.endswith("_ra_t"): ++ return "treat the files as %s read/append content." % prettyprint(f,"_ra_t") + -+ if f.endswith("_ro_t"): -+ return "treat the files as %s read/only content." % prettyprint(f,"_ro_t") ++ if f.endswith("_ro_t"): ++ return "treat the files as %s read/only content." % prettyprint(f,"_ro_t") + -+ if f.endswith("_modules_t"): -+ return "treat the files as %s modules." % prettyprint(f, "_modules_t") ++ if f.endswith("_modules_t"): ++ return "treat the files as %s modules." % prettyprint(f, "_modules_t") + -+ if f.endswith("_content_t"): -+ return "treat the files as %s content." % prettyprint(f, "_content_t") ++ if f.endswith("_content_t"): ++ return "treat the files as %s content." % prettyprint(f, "_content_t") + -+ if f.endswith("_state_t"): -+ return "treat the files as %s state data." % prettyprint(f, "_state_t") ++ if f.endswith("_state_t"): ++ return "treat the files as %s state data." % prettyprint(f, "_state_t") + -+ if f.endswith("_files_t"): -+ return "treat the files as %s content." % prettyprint(f, "_files_t") ++ if f.endswith("_files_t"): ++ return "treat the files as %s content." % prettyprint(f, "_files_t") + -+ if f.endswith("_file_t"): -+ return "treat the files as %s content." % prettyprint(f, "_file_t") ++ if f.endswith("_file_t"): ++ return "treat the files as %s content." % prettyprint(f, "_file_t") + -+ if f.endswith("_data_t"): -+ return "treat the files as %s content." % prettyprint(f, "_data_t") ++ if f.endswith("_data_t"): ++ return "treat the files as %s content." % prettyprint(f, "_data_t") + -+ if f.endswith("_file_t"): -+ return "treat the data as %s content." % prettyprint(f, "_file_t") ++ if f.endswith("_file_t"): ++ return "treat the data as %s content." % prettyprint(f, "_file_t") + -+ if f.endswith("_tmp_t"): -+ return "store %s temporary files in the /tmp directories." % prettyprint(f, "_tmp_t") -+ if f.endswith("_etc_t"): -+ return "store %s files in the /etc directories." % prettyprint(f, "_tmp_t") -+ if f.endswith("_home_t"): -+ return "store %s files in the users home directory." % prettyprint(f, "_home_t") -+ if f.endswith("_tmpfs_t"): -+ return "store %s files on a tmpfs file system." % prettyprint(f, "_tmpfs_t") -+ if f.endswith("_unit_file_t"): -+ return "treat files as a systemd unit file." -+ if f.endswith("_htaccess_t"): -+ return "treat the file as a %s access file." % prettyprint(f, "_htaccess_t") ++ if f.endswith("_tmp_t"): ++ return "store %s temporary files in the /tmp directories." % prettyprint(f, "_tmp_t") ++ if f.endswith("_etc_t"): ++ return "store %s files in the /etc directories." % prettyprint(f, "_tmp_t") ++ if f.endswith("_home_t"): ++ return "store %s files in the users home directory." % prettyprint(f, "_home_t") ++ if f.endswith("_tmpfs_t"): ++ return "store %s files on a tmpfs file system." % prettyprint(f, "_tmpfs_t") ++ if f.endswith("_unit_file_t"): ++ return "treat files as a systemd unit file." ++ if f.endswith("_htaccess_t"): ++ return "treat the file as a %s access file." % prettyprint(f, "_htaccess_t") + -+ return "treat the files as %s data." % prettyprint(f,"_t") ++ return "treat the files as %s data." % prettyprint(f,"_t") + + def _gen_bool_text(self, name): -+ booltext = "" -+ for bdict in bools: -+ b = bdict['name'] -+ if b.find(name) >= 0: -+ if b.endswith("anon_write"): -+ self.anon_list.append(b) -+ else: -+ if b not in booleans_dict: -+ continue -+ desc = booleans_dict[b][2][0].lower() + booleans_dict[b][2][1:] -+ if desc[-1] == ".": -+ desc = desc[:-1] -+ booltext += """ ++ booltext = "" ++ for bdict in bools: ++ b = bdict['name'] ++ if b.find(name) >= 0: ++ if b.endswith("anon_write"): ++ self.anon_list.append(b) ++ else: ++ if b not in booleans_dict: ++ continue ++ desc = booleans_dict[b][2][0].lower() + booleans_dict[b][2][1:] ++ if desc[-1] == ".": ++ desc = desc[:-1] ++ booltext += """ +.PP +If you want to %s, you must turn on the %s boolean. + @@ -344366,25 +344383,25 @@ index 0000000..94d89b2 +.B setsebool -P %s 1 +.EE +""" % (desc, b, b) -+ return booltext ++ return booltext + def _booleans(self): -+ self.booltext = self._gen_bool_text(self.short_name) -+ if self.domainname in equiv_dict.keys(): ++ self.booltext = self._gen_bool_text(self.short_name) ++ if self.domainname in equiv_dict.keys(): + for alias in equiv_dict[self.domainname]: + self.booltext += self._gen_bool_text(alias) + -+ for bdict in bools: -+ b = bdict['name'] -+ if b.find(self.short_name) >= 0: -+ if b.endswith("anon_write"): -+ self.anon_list.append(b) -+ else: -+ if b not in booleans_dict: -+ continue -+ desc = booleans_dict[b][2][0].lower() + booleans_dict[b][2][1:] -+ if desc[-1] == ".": -+ desc = desc[:-1] -+ self.booltext += """ ++ for bdict in bools: ++ b = bdict['name'] ++ if b.find(self.short_name) >= 0: ++ if b.endswith("anon_write"): ++ self.anon_list.append(b) ++ else: ++ if b not in booleans_dict: ++ continue ++ desc = booleans_dict[b][2][0].lower() + booleans_dict[b][2][1:] ++ if desc[-1] == ".": ++ desc = desc[:-1] ++ self.booltext += """ +.PP +If you want to %s, you must turn on the %s boolean. + @@ -344393,31 +344410,31 @@ index 0000000..94d89b2 +.EE +""" % (desc, b, b) + -+ if self.booltext != "": -+ self.fd.write(""" ++ if self.booltext != "": ++ self.fd.write(""" +.SH BOOLEANS +SELinux policy is customizable based on least access required. %s policy is extremely flexible and has several booleans that allow you to manipulate the policy and run %s with the tightest access possible. + +""" % (self.domainname, self.domainname)) + -+ self.fd.write(self.booltext) ++ self.fd.write(self.booltext) + + def _nsswitch_domain(self): -+ nsswitch_types = [] -+ nsswitch_booleans = ['authlogin_nsswitch_use_ldap', 'kerberos_enabled'] -+ nsswitchbooltext = "" -+ if "nsswitch_domain" in all_attributes: -+ self.fd.write(""" ++ nsswitch_types = [] ++ nsswitch_booleans = ['authlogin_nsswitch_use_ldap', 'kerberos_enabled'] ++ nsswitchbooltext = "" ++ if "nsswitch_domain" in all_attributes: ++ self.fd.write(""" +.SH NSSWITCH DOMAIN +""") -+ for k in self.attributes.keys(): -+ if "nsswitch_domain" in self.attributes[k]: -+ nsswitch_types.append(k) ++ for k in self.attributes.keys(): ++ if "nsswitch_domain" in self.attributes[k]: ++ nsswitch_types.append(k) + -+ if len(nsswitch_types): -+ for i in nsswitch_booleans: -+ desc = booleans_dict[i][2][0].lower() + booleans_dict[i][2][1:-1] -+ nsswitchbooltext += """ ++ if len(nsswitch_types): ++ for i in nsswitch_booleans: ++ desc = booleans_dict[i][2][0].lower() + booleans_dict[i][2][1:-1] ++ nsswitchbooltext += """ +.PP +If you want to %s for the %s, you must turn on the %s boolean. + @@ -344426,12 +344443,12 @@ index 0000000..94d89b2 +.EE +""" % (desc,(", ".join(nsswitch_types)), i, i) + -+ self.fd.write(nsswitchbooltext) ++ self.fd.write(nsswitchbooltext) + + def _process_types(self): -+ if len(self.ptypes) == 0: -+ return -+ self.fd.write(r""" ++ if len(self.ptypes) == 0: ++ return ++ self.fd.write(r""" +.SH PROCESS TYPES +SELinux defines process types (domains) for each process running on the system +.PP @@ -344442,11 +344459,11 @@ index 0000000..94d89b2 +.PP +The following process types are defined for %(domainname)s: +""" % {'domainname':self.domainname}) -+ self.fd.write(""" ++ self.fd.write(""" +.EX +.B %s +.EE""" % ", ".join(self.ptypes)) -+ self.fd.write(""" ++ self.fd.write(""" +.PP +Note: +.B semanage permissive -a PROCESS_TYPE @@ -344454,14 +344471,14 @@ index 0000000..94d89b2 +""") + + def _port_types(self): -+ self.ports = [] -+ for f in port_types: -+ if f.startswith(self.short_name): -+ self.ports.append(f) ++ self.ports = [] ++ for f in port_types: ++ if f.startswith(self.short_name): ++ self.ports.append(f) + -+ if len(self.ports) == 0: -+ return -+ self.fd.write(""" ++ if len(self.ports) == 0: ++ return ++ self.fd.write(""" +.SH PORT TYPES +SELinux defines port types to represent TCP and UDP ports. +.PP @@ -344475,8 +344492,8 @@ index 0000000..94d89b2 +.PP +The following port types are defined for %(domainname)s:""" % {'domainname':self.domainname}) + -+ for p in self.ports: -+ self.fd.write(""" ++ for p in self.ports: ++ self.fd.write(""" + +.EX +.TP 5 @@ -344484,20 +344501,20 @@ index 0000000..94d89b2 +.TP 10 +.EE +""" % p) -+ once = True -+ for prot in ( "tcp", "udp" ): -+ if (p,prot) in portrecs: -+ if once: -+ self.fd.write(""" ++ once = True ++ for prot in ( "tcp", "udp" ): ++ if (p,prot) in portrecs: ++ if once: ++ self.fd.write(""" + +Default Defined Ports:""") -+ once = False -+ self.fd.write(r""" ++ once = False ++ self.fd.write(r""" +%s %s +.EE""" % (prot, ",".join(portrecs[(p,prot)]))) + + def _file_context(self): -+ self.fd.write(r""" ++ self.fd.write(r""" +.SH FILE CONTEXTS +SELinux requires files to have an extended attribute to define the file type. +.PP @@ -344508,9 +344525,9 @@ index 0000000..94d89b2 +.PP +The following file types are defined for %(domainname)s: +""" % {'domainname':self.domainname}) -+ for f in file_types: -+ if f.startswith(self.domainname): -+ self.fd.write(""" ++ for f in file_types: ++ if f.startswith(self.domainname): ++ self.fd.write(""" + +.EX +.PP @@ -344520,19 +344537,19 @@ index 0000000..94d89b2 +- Set files with the %s type, if you want to %s +""" % (f, f, self._explain(f))) + -+ if f in files_dict: -+ plural = "" -+ if len(files_dict[f]) > 1: -+ plural = "s" -+ self.fd.write(""" ++ if f in files_dict: ++ plural = "" ++ if len(files_dict[f]) > 1: ++ plural = "s" ++ self.fd.write(""" +.br +.TP 5 +Path%s: +%s""" % (plural, files_dict[f][0][0])) -+ for x in files_dict[f][1:]: -+ self.fd.write(", %s" % x[0]) ++ for x in files_dict[f][1:]: ++ self.fd.write(", %s" % x[0]) + -+ self.fd.write(""" ++ self.fd.write(""" + +.PP +Note: File context can be temporarily modified with the chcon command. If you want to permanently change the file context you need to use the @@ -344543,20 +344560,20 @@ index 0000000..94d89b2 +""") + + def _see_also(self): -+ ret = "" -+ prefix = self.short_name.split("_")[0] -+ for d in domains: -+ if d == self.domainname: -+ continue -+ if d.startswith(prefix): -+ ret += ", %s_selinux(8)" % d -+ if self.domainname.startswith(d): -+ ret += ", %s_selinux(8)" % d -+ self.fd.write(ret) ++ ret = "" ++ prefix = self.short_name.split("_")[0] ++ for d in domains: ++ if d == self.domainname: ++ continue ++ if d.startswith(prefix): ++ ret += ", %s_selinux(8)" % d ++ if self.domainname.startswith(d): ++ ret += ", %s_selinux(8)" % d ++ self.fd.write(ret) + + def _public_content(self): -+ if len(self.anon_list) > 0: -+ self.fd.write(""" ++ if len(self.anon_list) > 0: ++ self.fd.write(""" +.SH SHARING FILES +If you want to share files with multiple domains (Apache, FTP, rsync, Samba), you can set a file context of public_content_t and public_content_rw_t. These context allow any of the above domains to read the content. If you want a particular domain to write to the public_content_rw_t domain, you must set the appropriate boolean. +.TP @@ -344576,9 +344593,9 @@ index 0000000..94d89b2 +.B restorecon -F -R -v /var/%(domainname)s/incoming + +""" % {'domainname':self.domainname}) -+ for b in self.anon_list: -+ desc = booleans_dict[b][2][0].lower() + booleans_dict[b][2][1:] -+ self.fd.write(""" ++ for b in self.anon_list: ++ desc = booleans_dict[b][2][0].lower() + booleans_dict[b][2][1:] ++ self.fd.write(""" +.PP +If you want to %s, you must turn on the %s boolean. + @@ -344588,7 +344605,7 @@ index 0000000..94d89b2 +""" % (desc, b, b)) + + def _footer(self): -+ self.fd.write(""" ++ self.fd.write(""" +.SH "COMMANDS" +.B semanage fcontext +can also be used to manipulate default file context mappings. @@ -344600,19 +344617,19 @@ index 0000000..94d89b2 +can also be used to enable/disable/install/remove policy modules. +""") + -+ if len(self.ports) > 0: -+ self.fd.write(""" ++ if len(self.ports) > 0: ++ self.fd.write(""" +.B semanage port +can also be used to manipulate the port definitions +""") + -+ if self.booltext != "": -+ self.fd.write(""" ++ if self.booltext != "": ++ self.fd.write(""" +.B semanage boolean +can also be used to manipulate the booleans +""") + -+ self.fd.write(""" ++ self.fd.write(""" +.PP +.B system-config-selinux +is a GUI tool available to customize SELinux policy settings. @@ -344626,88 +344643,88 @@ index 0000000..94d89b2 +selinux(8), %s(8), semanage(8), restorecon(8), chcon(1), sepolicy(8) +""" % (self.__whoami(), self.domainname)) + -+ if self.booltext != "": -+ self.fd.write(", setsebool(8)") ++ if self.booltext != "": ++ self.fd.write(", setsebool(8)") + -+ self._see_also() ++ self._see_also() + + def _valid_write(self, check, attributes): -+ if check in [ self.type, "domain" ]: -+ return False -+ if check.endswith("_t"): -+ for a in attributes: -+ if a in types[check]: -+ return False -+ return True ++ if check in [ self.type, "domain" ]: ++ return False ++ if check.endswith("_t"): ++ for a in attributes: ++ if a in types[check]: ++ return False ++ return True + + def _entrypoints(self): -+ entrypoints = map(lambda x: x['target'], sepolicy.search([sepolicy.ALLOW],{'source':self.type, 'permlist':['entrypoint'], 'class':'file'})) -+ if entrypoints == None: -+ return -+ self.fd.write (""" ++ entrypoints = map(lambda x: x['target'], sepolicy.search([sepolicy.ALLOW],{'source':self.type, 'permlist':['entrypoint'], 'class':'file'})) ++ if entrypoints == None: ++ return ++ self.fd.write (""" +.SH "ENTRYPOINTS" +""") -+ if len(entrypoints) > 1: -+ entrypoints_str = "\"%s\" file types" % ",".join(entrypoints) -+ else: -+ entrypoints_str = "\"%s\" file type" % entrypoints[0] ++ if len(entrypoints) > 1: ++ entrypoints_str = "\"%s\" file types" % ",".join(entrypoints) ++ else: ++ entrypoints_str = "\"%s\" file type" % entrypoints[0] + -+ self.fd.write (""" ++ self.fd.write (""" +The %s_t SELinux type can be entered via the %s. The default entrypoint paths for the %s_t domain are the following:" +""" % (self.domainname, entrypoints_str, self.domainname)) -+ paths=[] -+ for entrypoint in entrypoints: -+ if entrypoint in fcdict: -+ paths += fcdict[entrypoint] ++ paths=[] ++ for entrypoint in entrypoints: ++ if entrypoint in fcdict: ++ paths += fcdict[entrypoint] + -+ self.fd.write(""" ++ self.fd.write(""" +%s""" % ", ".join(paths)) + + def _writes(self): -+ permlist = sepolicy.search([sepolicy.ALLOW],{'source':self.type, 'permlist':['open', 'write'], 'class':'file'}) -+ if permlist == None or len(permlist) == 0: -+ return ++ permlist = sepolicy.search([sepolicy.ALLOW],{'source':self.type, 'permlist':['open', 'write'], 'class':'file'}) ++ if permlist == None or len(permlist) == 0: ++ return + -+ all_writes = [] -+ attributes = ["proc_type", "sysctl_type"] -+ for i in permlist: -+ if not i['target'].endswith("_t"): -+ attributes.append(i['target']) ++ all_writes = [] ++ attributes = ["proc_type", "sysctl_type"] ++ for i in permlist: ++ if not i['target'].endswith("_t"): ++ attributes.append(i['target']) + -+ for i in permlist: -+ if self._valid_write(i['target'],attributes): -+ if i['target'] not in all_writes: -+ all_writes.append(i['target']) ++ for i in permlist: ++ if self._valid_write(i['target'],attributes): ++ if i['target'] not in all_writes: ++ all_writes.append(i['target']) + -+ if len(all_writes) == 0: -+ return -+ self.fd.write (""" ++ if len(all_writes) == 0: ++ return ++ self.fd.write (""" +.SH "MANAGED FILES" +""") -+ self.fd.write (""" ++ self.fd.write (""" +The SELinux process type %s_t can manage files labeled with the following file types. The paths listed are the default paths for these file types. Note the processes UID still need to have DAC permissions. +""" % self.domainname) + -+ all_writes.sort() -+ if "file_type" in all_writes: -+ all_writes = [ "file_type" ] -+ for f in all_writes: -+ self.fd.write(""" ++ all_writes.sort() ++ if "file_type" in all_writes: ++ all_writes = [ "file_type" ] ++ for f in all_writes: ++ self.fd.write(""" +.br +.B %s + +""" % f) -+ if f in fcdict: -+ for path in fcdict[f]: -+ self.fd.write("""\t%s ++ if f in fcdict: ++ for path in fcdict[f]: ++ self.fd.write("""\t%s +.br +""" % path) + + def _user_header(self): -+ self.fd.write('.TH "%(type)s_selinux" "8" "%(type)s" "mgrepl@redhat.com" "%(type)s SELinux Policy documentation"' -+ % {'type':self.domainname}) ++ self.fd.write('.TH "%(type)s_selinux" "8" "%(type)s" "mgrepl@redhat.com" "%(type)s SELinux Policy documentation"' ++ % {'type':self.domainname}) + -+ self.fd.write(r""" ++ self.fd.write(r""" +.SH "NAME" +%(user)s_u \- \fB%(desc)s\fP - Security Enhanced Linux Policy + @@ -344740,8 +344757,8 @@ index 0000000..94d89b2 + +""" % {'desc': self.desc, 'type':self.type, 'user':self.domainname}) + -+ if "login_userdomain" in self.attributes and "login_userdomain" in all_attributes: -+ self.fd.write(""" ++ if "login_userdomain" in self.attributes and "login_userdomain" in all_attributes: ++ self.fd.write(""" +If you want to map the one Linux user (joe) to the SELinux user %(user)s, you would execute: + +.B $ semanage login -a -s %(user)s_u joe @@ -344749,13 +344766,13 @@ index 0000000..94d89b2 +""" % {'user':self.domainname}) + + def _can_sudo(self): -+ sudotype = "%s_sudo_t" % self.domainname -+ self.fd.write(""" ++ sudotype = "%s_sudo_t" % self.domainname ++ self.fd.write(""" +.SH SUDO +""") -+ if sudotype in types: -+ role = self.domainname + "_r" -+ self.fd.write(""" ++ if sudotype in types: ++ role = self.domainname + "_r" ++ self.fd.write(""" +The SELinux user %(user)s can execute sudo. + +You can set up sudo to allow %(user)s to transition to an administrative domain: @@ -344763,14 +344780,14 @@ index 0000000..94d89b2 +Add one or more of the following record to sudoers using visudo. + +""" % { 'user':self.domainname } ) -+ for adminrole in role_allows[role]: -+ self.fd.write(""" ++ for adminrole in role_allows[role]: ++ self.fd.write(""" +USERNAME ALL=(ALL) ROLE=%(admin)s_r TYPE=%(admin)s_t COMMAND +.br +sudo will run COMMAND as %(user)s_u:%(admin)s_r:%(admin)s_t:LEVEL +""" % {'admin':adminrole[:-2], 'user':self.domainname } ) + -+ self.fd.write(""" ++ self.fd.write(""" +You might also need to add one or more of these new roles to your SELinux user record. + +List the SELinux roles your SELinux user can reach by executing: @@ -344784,103 +344801,103 @@ index 0000000..94d89b2 +For more details you can see semanage man page. + +""" % {'user':self.domainname, "roles": " ".join([role] + role_allows[role]) } ) -+ else: -+ self.fd.write(""" ++ else: ++ self.fd.write(""" +The SELinux type %s_t is not allowed to execute sudo. +""" % self.domainname) + + def _user_attribute(self): -+ self.fd.write(""" ++ self.fd.write(""" +.SH USER DESCRIPTION +""") -+ if "unconfined_usertype" in self.attributes: -+ self.fd.write(""" ++ if "unconfined_usertype" in self.attributes: ++ self.fd.write(""" +The SELinux user %s_u is an unconfined user. It means that a mapped Linux user to this SELinux user is supposed to be allow all actions. +""" % self.domainname) + -+ if "unpriv_userdomain" in self.attributes: -+ self.fd.write(""" ++ if "unpriv_userdomain" in self.attributes: ++ self.fd.write(""" +The SELinux user %s_u is defined in policy as a unprivileged user. SELinux prevents unprivileged users from doing administration tasks without transitioning to a different role. +""" % self.domainname) + -+ if "admindomain" in self.attributes: -+ self.fd.write(""" ++ if "admindomain" in self.attributes: ++ self.fd.write(""" +The SELinux user %s_u is an admin user. It means that a mapped Linux user to this SELinux user is intended for administrative actions. Usually this is assigned to a root Linux user. +""" % self.domainname) + + def _xwindows_login(self): -+ if "x_domain" in all_attributes: -+ self.fd.write(""" ++ if "x_domain" in all_attributes: ++ self.fd.write(""" +.SH X WINDOWS LOGIN +""") -+ if "x_domain" in self.attributes: -+ self.fd.write(""" ++ if "x_domain" in self.attributes: ++ self.fd.write(""" +The SELinux user %s_u is able to X Windows login. +""" % self.domainname) -+ else: -+ self.fd.write(""" ++ else: ++ self.fd.write(""" +The SELinux user %s_u is not able to X Windows login. +""" % self.domainname) + + def _terminal_login(self): -+ if "login_userdomain" in all_attributes: -+ self.fd.write(""" ++ if "login_userdomain" in all_attributes: ++ self.fd.write(""" +.SH TERMINAL LOGIN +""") -+ if "login_userdomain" in self.attributes: -+ self.fd.write(""" ++ if "login_userdomain" in self.attributes: ++ self.fd.write(""" +The SELinux user %s_u is able to terminal login. +""" % self.domainname) -+ else: -+ self.fd.write(""" ++ else: ++ self.fd.write(""" +The SELinux user %s_u is not able to terminal login. +""" % self.domainname) + + def _network(self): -+ self.fd.write(""" ++ self.fd.write(""" +.SH NETWORK +""") -+ for net in ("tcp", "udp"): -+ portdict = sepolicy.network.get_network_connect(self.type, net, "name_bind") -+ if len(portdict) > 0: -+ self.fd.write(""" ++ for net in ("tcp", "udp"): ++ portdict = sepolicy.network.get_network_connect(self.type, net, "name_bind") ++ if len(portdict) > 0: ++ self.fd.write(""" +.TP +The SELinux user %s_u is able to listen on the following %s ports. +""" % (self.domainname, net)) -+ for p in portdict: -+ for recs in portdict[p]: -+ self.fd.write(""" ++ for p in portdict: ++ for recs in portdict[p]: ++ self.fd.write(""" +.B %s +""" % recs) -+ portdict = network.get_network_connect(self.type, "tcp", "name_connect") -+ if len(portdict) > 0: -+ self.fd.write(""" ++ portdict = network.get_network_connect(self.type, "tcp", "name_connect") ++ if len(portdict) > 0: ++ self.fd.write(""" +.TP +The SELinux user %s_u is able to connect to the following tcp ports. +""" % (self.domainname)) -+ for p in portdict: -+ for recs in portdict[p]: -+ self.fd.write(""" ++ for p in portdict: ++ for recs in portdict[p]: ++ self.fd.write(""" +.B %s +""" % recs) + + def _home_exec(self): -+ permlist = sepolicy.search([sepolicy.ALLOW],{'source':self.type,'target':'user_home_type', 'class':'file', 'permlist':['ioctl', 'read', 'getattr', 'execute', 'execute_no_trans', 'open']}) -+ self.fd.write(""" ++ permlist = sepolicy.search([sepolicy.ALLOW],{'source':self.type,'target':'user_home_type', 'class':'file', 'permlist':['ioctl', 'read', 'getattr', 'execute', 'execute_no_trans', 'open']}) ++ self.fd.write(""" +.SH HOME_EXEC +""" ) -+ if permlist is not None: -+ self.fd.write(""" ++ if permlist is not None: ++ self.fd.write(""" +The SELinux user %s_u is able execute home content files. +""" % self.domainname) + -+ else: -+ self.fd.write(""" ++ else: ++ self.fd.write(""" +The SELinux user %s_u is not able execute home content files. +""" % self.domainname) + + def _transitions(self): -+ self.fd.write(r""" ++ self.fd.write(r""" +.SH TRANSITIONS + +Three things can happen when %(type)s attempts to execute a program. @@ -344906,10 +344923,10 @@ index 0000000..94d89b2 +""" % {'user':self.domainname, 'type':self.type}) + + def _role_header(self): -+ self.fd.write('.TH "%(user)s_selinux" "8" "%(user)s" "mgrepl@redhat.com" "%(user)s SELinux Policy documentation"' -+ % {'user':self.domainname}) ++ self.fd.write('.TH "%(user)s_selinux" "8" "%(user)s" "mgrepl@redhat.com" "%(user)s SELinux Policy documentation"' ++ % {'user':self.domainname}) + -+ self.fd.write(r""" ++ self.fd.write(r""" +.SH "NAME" +%(user)s_r \- \fB%(desc)s\fP - Security Enhanced Linux Policy + @@ -344951,16 +344968,16 @@ index 0000000..94d89b2 +.B $ semanage user -m -R 'staff_r system_r %(user)s_r' staff_u + +""" % {'desc': self.desc, 'user':self.domainname}) -+ troles = [] -+ for i in role_allows: -+ if self.domainname +"_r" in role_allows[i]: -+ troles.append(i) -+ if len(troles) > 0: -+ plural = "" -+ if len(troles) > 1: -+ plural = "s" ++ troles = [] ++ for i in role_allows: ++ if self.domainname +"_r" in role_allows[i]: ++ troles.append(i) ++ if len(troles) > 0: ++ plural = "" ++ if len(troles) > 1: ++ plural = "s" + -+ self.fd.write(""" ++ self.fd.write(""" + +SELinux policy also controls which roles can transition to a different role. +You can list these rules using the following command. @@ -347419,10 +347436,10 @@ index 0000000..dccb5f1 +""" diff --git a/policycoreutils/sepolicy/sepolicy/transition.py b/policycoreutils/sepolicy/sepolicy/transition.py new file mode 100755 -index 0000000..72f5f65 +index 0000000..90ca85f --- /dev/null +++ b/policycoreutils/sepolicy/sepolicy/transition.py -@@ -0,0 +1,71 @@ +@@ -0,0 +1,72 @@ +#! /usr/bin/python -Es +# Copyright (C) 2011 Red Hat +# see file 'COPYING' for use and warranty information @@ -347476,7 +347493,8 @@ index 0000000..72f5f65 + + if not dest: + for t in targets: -+ slist.append((src, _entrypoint(t)[0], t)) ++ if len(_entrypoint(t)): ++ slist.append((src, _entrypoint(t)[0], t)) + return True + + if dest in targets: diff --git a/policycoreutils.spec b/policycoreutils.spec index 5f85c8d..621e6da 100644 --- a/policycoreutils.spec +++ b/policycoreutils.spec @@ -7,7 +7,7 @@ Summary: SELinux policy core utilities Name: policycoreutils Version: 2.1.13 -Release: 22%{?dist} +Release: 23%{?dist} License: GPLv2 Group: System Environment/Base # Based on git repository with tag 20101221 @@ -329,6 +329,9 @@ The policycoreutils-restorecond package contains the restorecond service. %{_bindir}/systemctl try-restart restorecond.service >/dev/null 2>&1 || : %changelog +* Thu Nov 1 2012 Dan Walsh - 2.1.12-23 +- Fix some build problems in sepolicy manpage and sepolicy transition + * Tue Oct 30 2012 Dan Walsh - 2.1.12-22 - Add alias man pages to sepolicy manpage