policycoreutils/selinux-python-fedora.patch
Petr Lautrbach 8fd0cedde2 policycoreutils-2.7-4.fc28
- restorecond: check write() and daemon() results
- sepolicy: do not fail when file_contexts.local or .subs do not exist
- sepolicy: remove stray space in section "SEE ALSO"
- sepolicy: fix misspelling of _ra_content_t suffix
- gui: port to Python 3 by migrating to PyGI
- gui: remove the status bar
- gui: fix parsing of "semodule -lfull" in tab Modules
- gui: delete overridden definition of usersPage.delete()
- Enable listing file_contexts.homedirs (#1409813)
- remove semodule_deps
2017-10-20 13:51:23 +02:00

566 lines
21 KiB
Diff

diff --git selinux-python-2.7/semanage/semanage.8 selinux-python-2.7/semanage/semanage.8
index 0bdb90f..0cdcfcc 100644
--- selinux-python-2.7/semanage/semanage.8
+++ selinux-python-2.7/semanage/semanage.8
@@ -57,9 +57,8 @@ to SELinux user identities (which controls the initial security context
assigned to Linux users when they login and bounds their authorized role set)
as well as security context mappings for various kinds of objects, such
as network ports, interfaces, infiniband pkeys and endports, and nodes (hosts)
-as well as the file context mapping. See the EXAMPLES section below for some
-examples of common usage. Note that the semanage login command deals with the
-mapping from Linux usernames (logins) to SELinux user identities,
+as well as the file context mapping. Note that the semanage login command deals
+with the mapping from Linux usernames (logins) to SELinux user identities,
while the semanage user command deals with the mapping from SELinux
user identities to authorized role sets. In most cases, only the
former mapping needs to be adjusted by the administrator; the latter
diff --git selinux-python-2.7/semanage/seobject.py selinux-python-2.7/semanage/seobject.py
index 70fd192..55127de 100644
--- selinux-python-2.7/semanage/seobject.py
+++ selinux-python-2.7/semanage/seobject.py
@@ -386,6 +386,8 @@ class moduleRecords(semanageRecords):
print("%-25s %-9s %-5s %s" % (t[0], t[2], t[3], disabled))
def add(self, file, priority):
+ if not file:
+ raise ValueError(_("You did not define module."))
if not os.path.exists(file):
raise ValueError(_("Module does not exist: %s ") % file)
@@ -398,6 +400,8 @@ class moduleRecords(semanageRecords):
self.commit()
def set_enabled(self, module, enable):
+ if not module:
+ raise ValueError(_("You did not define module name."))
for m in module.split():
rc, key = semanage_module_key_create(self.sh)
if rc < 0:
@@ -416,11 +420,15 @@ class moduleRecords(semanageRecords):
self.commit()
def modify(self, file):
+ if not file:
+ raise ValueError(_("You did not define module."))
rc = semanage_module_update_file(self.sh, file)
if rc >= 0:
self.commit()
def delete(self, module, priority):
+ if not module:
+ raise ValueError(_("You did not define module name."))
rc = semanage_set_default_priority(self.sh, priority)
if rc < 0:
raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
@@ -2566,10 +2574,15 @@ class fcontextRecords(semanageRecords):
if rc < 0:
raise ValueError(_("Could not list file contexts"))
+ (rc, fchomedirs) = semanage_fcontext_list_homedirs(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list file contexts for home directories"))
+
(rc, fclocal) = semanage_fcontext_list_local(self.sh)
if rc < 0:
raise ValueError(_("Could not list local file contexts"))
+ self.flist += fchomedirs
self.flist += fclocal
ddict = {}
diff --git selinux-python-2.7/sepolicy/sepolicy/__init__.py selinux-python-2.7/sepolicy/sepolicy/__init__.py
index 5cfc071..24e3526 100644
--- selinux-python-2.7/sepolicy/sepolicy/__init__.py
+++ selinux-python-2.7/sepolicy/sepolicy/__init__.py
@@ -4,6 +4,7 @@
# Author: Ryan Hallisey <rhallise@redhat.com>
# Author: Jason Zaman <perfinion@gentoo.org>
+import errno
import selinux
import setools
import glob
@@ -207,10 +208,17 @@ def info(setype, name=None):
elif len(ports) == 1:
q.ports = (ports[0], ports[0])
+ if _pol.mls:
+ return ({
+ 'high': x.ports.high,
+ 'protocol': str(x.protocol),
+ 'range': str(x.context.range_),
+ 'type': str(x.context.type_),
+ 'low': x.ports.low,
+ } for x in q.results())
return ({
'high': x.ports.high,
'protocol': str(x.protocol),
- 'range': str(x.context.range_),
'type': str(x.context.type_),
'low': x.ports.low,
} for x in q.results())
@@ -220,11 +228,16 @@ def info(setype, name=None):
if name:
q.name = name
+ if _pol.mls:
+ return ({
+ 'range': str(x.mls_range),
+ 'name': str(x),
+ 'roles': list(map(str, x.roles)),
+ 'level': str(x.mls_level),
+ } for x in q.results())
return ({
- 'range': str(x.mls_range),
'name': str(x),
'roles': list(map(str, x.roles)),
- 'level': str(x.mls_level),
} for x in q.results())
elif setype == BOOLEAN:
@@ -511,12 +524,15 @@ def find_entrypoint_path(exe, exclude_list=[]):
def read_file_equiv(edict, fc_path, modify):
- fd = open(fc_path, "r")
- fc = fd.readlines()
- fd.close()
- for e in fc:
- f = e.split()
- edict[f[0]] = {"equiv": f[1], "modify": modify}
+ try:
+ with open(fc_path, "r") as fd:
+ for e in fd:
+ f = e.split()
+ if f and not f[0].startswith('#'):
+ edict[f[0]] = {"equiv": f[1], "modify": modify}
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise
return edict
@@ -543,9 +559,13 @@ def get_local_file_paths(fc_path=selinux.selinux_file_context_path()):
if local_files:
return local_files
local_files = []
- fd = open(fc_path + ".local", "r")
- fc = fd.readlines()
- fd.close()
+ try:
+ with open(fc_path + ".local", "r") as fd:
+ fc = fd.readlines()
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise
+ return []
for i in fc:
rec = i.split()
if len(rec) == 0:
@@ -573,9 +593,12 @@ def get_fcdict(fc_path=selinux.selinux_file_context_path()):
fc += fd.readlines()
fd.close()
fcdict = {}
- fd = open(fc_path + ".local", "r")
- fc += fd.readlines()
- fd.close()
+ try:
+ with open(fc_path + ".local", "r") as fd:
+ fc += fd.readlines()
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise
for i in fc:
rec = i.split()
@@ -856,8 +879,9 @@ def get_selinux_users():
global selinux_user_list
if not selinux_user_list:
selinux_user_list = list(info(USER))
- for x in selinux_user_list:
- x['range'] = "".join(x['range'].split(" "))
+ if _pol.mls:
+ for x in selinux_user_list:
+ x['range'] = "".join(x['range'].split(" "))
return selinux_user_list
@@ -955,7 +979,7 @@ def get_description(f, markup=markup):
if f.endswith("_db_t"):
return txt + "treat the files as %s database content." % prettyprint(f, "_db_t")
if f.endswith("_ra_content_t"):
- return txt + "treat the files as %s read/append content." % prettyprint(f, "_ra_conten_t")
+ return txt + "treat the files as %s read/append content." % prettyprint(f, "_ra_content_t")
if f.endswith("_cert_t"):
return txt + "treat the files as %s certificate data." % prettyprint(f, "_cert_t")
if f.endswith("_key_t"):
@@ -1136,27 +1160,14 @@ def boolean_desc(boolean):
def get_os_version():
- os_version = ""
- pkg_name = "selinux-policy"
+ system_release = ""
try:
- try:
- from commands import getstatusoutput
- except ImportError:
- from subprocess import getstatusoutput
- rc, output = getstatusoutput("rpm -q '%s'" % pkg_name)
- if rc == 0:
- os_version = output.split(".")[-2]
- except:
- os_version = ""
-
- if os_version[0:2] == "fc":
- os_version = "Fedora" + os_version[2:]
- elif os_version[0:2] == "el":
- os_version = "RHEL" + os_version[2:]
- else:
- os_version = ""
+ with open('/etc/system-release') as f:
+ system_release = f.readline().rstrip()
+ except IOError:
+ system_release = "Misc"
- return os_version
+ return system_release
def reinit():
diff --git selinux-python-2.7/sepolicy/sepolicy/gui.py selinux-python-2.7/sepolicy/sepolicy/gui.py
index 007c94a..6562aa8 100644
--- selinux-python-2.7/sepolicy/sepolicy/gui.py
+++ selinux-python-2.7/sepolicy/sepolicy/gui.py
@@ -907,8 +907,8 @@ class SELinuxGui():
if "object_r" in roles:
roles.remove("object_r")
self.user_liststore.set_value(iter, 1, ", ".join(roles))
- self.user_liststore.set_value(iter, 2, u["level"])
- self.user_liststore.set_value(iter, 3, u["range"])
+ self.user_liststore.set_value(iter, 2, u.get("level", ""))
+ self.user_liststore.set_value(iter, 3, u.get("range", ""))
self.user_liststore.set_value(iter, 4, True)
self.ready_mouse()
@@ -1755,14 +1755,14 @@ class SELinuxGui():
if self.login_mls_entry.get_text() == "":
for u in sepolicy.get_selinux_users():
if seuser == u['name']:
- self.login_mls_entry.set_text(u['range'])
+ self.login_mls_entry.set_text(u.get('range', ''))
def user_roles_combobox_change(self, combo, *args):
serole = self.combo_get_active_text(combo)
if self.user_mls_entry.get_text() == "":
for u in sepolicy.get_all_roles():
if serole == u['name']:
- self.user_mls_entry.set_text(u['range'])
+ self.user_mls_entry.set_text(u.get('range', ''))
def get_selected_iter(self):
iter = None
@@ -1973,7 +1973,10 @@ class SELinuxGui():
self.cur_dict["user"][name] = {"action": "-m", "range": mls_range, "level": level, "role": roles, "oldrange": oldrange, "oldlevel": oldlevel, "oldroles": oldroles, "oldname": oldname}
else:
iter = self.liststore.append(None)
- self.cur_dict["user"][name] = {"action": "-a", "range": mls_range, "level": level, "role": roles}
+ if mls_range or level:
+ self.cur_dict["user"][name] = {"action": "-a", "range": mls_range, "level": level, "role": roles}
+ else:
+ self.cur_dict["user"][name] = {"action": "-a", "role": roles}
self.liststore.set_value(iter, 0, name)
self.liststore.set_value(iter, 1, roles)
@@ -2089,8 +2092,8 @@ class SELinuxGui():
user_dict = self.cust_dict["user"]
for user in user_dict:
roles = user_dict[user]["role"]
- mls = user_dict[user]["range"]
- level = user_dict[user]["level"]
+ mls = user_dict[user].get("range", "")
+ level = user_dict[user].get("level", "")
iter = self.user_delete_liststore.append()
self.user_delete_liststore.set_value(iter, 1, user)
self.user_delete_liststore.set_value(iter, 2, roles)
@@ -2104,7 +2107,7 @@ class SELinuxGui():
login_dict = self.cust_dict["login"]
for login in login_dict:
seuser = login_dict[login]["seuser"]
- mls = login_dict[login]["range"]
+ mls = login_dict[login].get("range", "")
iter = self.login_delete_liststore.append()
self.login_delete_liststore.set_value(iter, 1, seuser)
self.login_delete_liststore.set_value(iter, 2, login)
@@ -2268,7 +2271,7 @@ class SELinuxGui():
self.update_treestore.set_value(niter, 3, False)
roles = self.cur_dict["user"][user]["role"]
self.update_treestore.set_value(niter, 1, (_("Roles: %s")) % roles)
- mls = self.cur_dict["user"][user]["range"]
+ mls = self.cur_dict["user"][user].get("range", "")
niter = self.update_treestore.append(iter)
self.update_treestore.set_value(niter, 3, False)
self.update_treestore.set_value(niter, 1, _("MLS/MCS Range: %s") % mls)
@@ -2293,7 +2296,7 @@ class SELinuxGui():
self.update_treestore.set_value(niter, 3, False)
seuser = self.cur_dict["login"][login]["seuser"]
self.update_treestore.set_value(niter, 1, (_("SELinux User: %s")) % seuser)
- mls = self.cur_dict["login"][login]["range"]
+ mls = self.cur_dict["login"][login].get("range", "")
niter = self.update_treestore.append(iter)
self.update_treestore.set_value(niter, 3, False)
self.update_treestore.set_value(niter, 1, _("MLS/MCS Range: %s") % mls)
@@ -2487,14 +2490,18 @@ class SELinuxGui():
for l in self.cur_dict[k]:
if self.cur_dict[k][l]["action"] == "-d":
update_buffer += "login -d %s\n" % l
- else:
+ elif "range" in self.cur_dict[k][l]:
update_buffer += "login %s -s %s -r %s %s\n" % (self.cur_dict[k][l]["action"], self.cur_dict[k][l]["seuser"], self.cur_dict[k][l]["range"], l)
+ else:
+ update_buffer += "login %s -s %s %s\n" % (self.cur_dict[k][l]["action"], self.cur_dict[k][l]["seuser"], l)
if k in "user":
for u in self.cur_dict[k]:
if self.cur_dict[k][u]["action"] == "-d":
update_buffer += "user -d %s\n" % u
- else:
+ elif "level" in self.cur_dict[k][u] and "range" in self.cur_dict[k][u]:
update_buffer += "user %s -L %s -r %s -R %s %s\n" % (self.cur_dict[k][u]["action"], self.cur_dict[k][u]["level"], self.cur_dict[k][u]["range"], self.cur_dict[k][u]["role"], u)
+ else:
+ update_buffer += "user %s -R %s %s\n" % (self.cur_dict[k][u]["action"], self.cur_dict[k][u]["role"], u)
if k in "fcontext-equiv":
for f in self.cur_dict[k]:
diff --git selinux-python-2.7/sepolicy/sepolicy/manpage.py selinux-python-2.7/sepolicy/sepolicy/manpage.py
index 4d84636..b463165 100755
--- selinux-python-2.7/sepolicy/sepolicy/manpage.py
+++ selinux-python-2.7/sepolicy/sepolicy/manpage.py
@@ -84,7 +84,8 @@ def get_all_users_info():
for d in allusers_info:
allusers.append(d['name'])
- users_range[d['name'].split("_")[0]] = d['range']
+ if 'range' in d:
+ users_range[d['name'].split("_")[0]] = d['range']
for u in allusers:
if u not in ["system_u", "root", "unconfined_u"]:
@@ -125,8 +126,36 @@ def gen_domains():
domains.sort()
return domains
-types = None
+exec_types = None
+
+def _gen_exec_types():
+ global exec_types
+ if exec_types is None:
+ exec_types = next(sepolicy.info(sepolicy.ATTRIBUTE, "exec_type"))["types"]
+ return exec_types
+
+entry_types = None
+
+def _gen_entry_types():
+ global entry_types
+ if entry_types is None:
+ entry_types = next(sepolicy.info(sepolicy.ATTRIBUTE, "entry_type"))["types"]
+ return entry_types
+
+mcs_constrained_types = None
+
+def _gen_mcs_constrained_types():
+ global mcs_constrained_types
+ if mcs_constrained_types is None:
+ try:
+ mcs_constrained_types = next(sepolicy.info(sepolicy.ATTRIBUTE, "mcs_constrained_type"))
+ except StopIteration:
+ mcs_constrained_types = []
+ return mcs_constrained_types
+
+
+types = None
def _gen_types():
global types
@@ -149,10 +178,6 @@ def prettyprint(f, trim):
manpage_domains = []
manpage_roles = []
-fedora_releases = ["Fedora17", "Fedora18"]
-rhel_releases = ["RHEL6", "RHEL7"]
-
-
def get_alphabet_manpages(manpage_list):
alphabet_manpages = dict.fromkeys(string.ascii_letters, [])
for i in string.ascii_letters:
@@ -182,7 +207,7 @@ def convert_manpage_to_html(html_manpage, manpage):
class HTMLManPages:
"""
- Generate a HHTML Manpages on an given SELinux domains
+ Generate a HTML Manpages on an given SELinux domains
"""
def __init__(self, manpage_roles, manpage_domains, path, os_version):
@@ -190,9 +215,9 @@ class HTMLManPages:
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.new_path = self.old_path
- if self.os_version in fedora_releases or rhel_releases:
+ if self.os_version:
self.__gen_html_manpages()
else:
print("SELinux HTML man pages can not be generated for this %s" % os_version)
@@ -201,7 +226,6 @@ class HTMLManPages:
def __gen_html_manpages(self):
self._write_html_manpage()
self._gen_index()
- self._gen_body()
self._gen_css()
def _write_html_manpage(self):
@@ -219,67 +243,21 @@ class HTMLManPages:
convert_manpage_to_html((self.new_path + r.rsplit("_selinux", 1)[0] + ".html"), self.old_path + r)
def _gen_index(self):
- index = self.old_path + "index.html"
- fd = open(index, 'w')
- fd.write("""
-<html>
-<head>
- <link rel=stylesheet type="text/css" href="style.css" title="style">
- <title>SELinux man pages online</title>
-</head>
-<body>
-<h1>SELinux man pages</h1>
-<br></br>
-Fedora or Red Hat Enterprise Linux Man Pages.</h2>
-<br></br>
-<hr>
-<h3>Fedora</h3>
-<table><tr>
-<td valign="middle">
-</td>
-</tr></table>
-<pre>
-""")
- for f in fedora_releases:
- fd.write("""
-<a href=%s/%s.html>%s</a> - SELinux man pages for %s """ % (f, f, f, f))
-
- fd.write("""
-</pre>
-<hr>
-<h3>RHEL</h3>
-<table><tr>
-<td valign="middle">
-</td>
-</tr></table>
-<pre>
-""")
- for r in rhel_releases:
- fd.write("""
-<a href=%s/%s.html>%s</a> - SELinux man pages for %s """ % (r, r, r, r))
-
- fd.write("""
-</pre>
- """)
- 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("""
<html>
<head>
- <link rel=stylesheet type="text/css" href="../style.css" title="style">
- <title>Linux man-pages online for Fedora18</title>
+ <link rel=stylesheet type="text/css" href="style.css" title="style">
+ <title>SELinux man pages</title>
</head>
<body>
-<h1>SELinux man pages for Fedora18</h1>
+<h1>SELinux man pages for %s</h1>
<hr>
<table><tr>
<td valign="middle">
<h3>SELinux roles</h3>
-""")
+""" % self.os_version)
for letter in self.manpage_roles:
if len(self.manpage_roles[letter]):
fd.write("""
@@ -423,6 +401,9 @@ class ManPage:
self.all_file_types = sepolicy.get_all_file_types()
self.role_allows = sepolicy.get_all_role_allows()
self.types = _gen_types()
+ self.exec_types = _gen_exec_types()
+ self.entry_types = _gen_entry_types()
+ self.mcs_constrained_types = _gen_mcs_constrained_types()
if self.source_files:
self.fcpath = self.root + "file_contexts"
@@ -735,10 +716,13 @@ Default Defined Ports:""")
def _file_context(self):
flist = []
+ flist_non_exec = []
mpaths = []
for f in self.all_file_types:
if f.startswith(self.domainname):
flist.append(f)
+ if not f in self.exec_types or not f in self.entry_types:
+ flist_non_exec.append(f)
if f in self.fcdict:
mpaths = mpaths + self.fcdict[f]["regex"]
if len(mpaths) == 0:
@@ -790,19 +774,20 @@ SELinux %(domainname)s policy is very flexible allowing users to setup their %(d
.PP
""" % {'domainname': self.domainname, 'equiv': e, 'alt': e.split('/')[-1]})
- self.fd.write(r"""
+ if flist_non_exec:
+ self.fd.write(r"""
.PP
.B STANDARD FILE CONTEXT
SELinux defines the file context types for the %(domainname)s, if you wanted to
store files with these types in a diffent paths, you need to execute the semanage command to sepecify alternate labeling and then use restorecon to put the labels on disk.
-.B semanage fcontext -a -t %(type)s '/srv/%(domainname)s/content(/.*)?'
+.B semanage fcontext -a -t %(type)s '/srv/my%(domainname)s_content(/.*)?'
.br
.B restorecon -R -v /srv/my%(domainname)s_content
Note: SELinux often uses regular expressions to specify labels that match multiple files.
-""" % {'domainname': self.domainname, "type": flist[0]})
+""" % {'domainname': self.domainname, "type": flist_non_exec[-1]})
self.fd.write(r"""
.I The following file types are defined for %(domainname)s:
@@ -921,8 +906,7 @@ This manual page was auto-generated using
.B "sepolicy manpage".
.SH "SEE ALSO"
-selinux(8), %s(8), semanage(8), restorecon(8), chcon(1), sepolicy(8)
-""" % (self.domainname))
+selinux(8), %s(8), semanage(8), restorecon(8), chcon(1), sepolicy(8)""" % (self.domainname))
if self.booltext != "":
self.fd.write(", setsebool(8)")
@@ -974,8 +958,7 @@ All executeables with the default executable label, usually stored in /usr/bin a
%s""" % ", ".join(paths))
def _mcs_types(self):
- mcs_constrained_type = next(sepolicy.info(sepolicy.ATTRIBUTE, "mcs_constrained_type"))
- if self.type not in mcs_constrained_type['types']:
+ if self.type not in self.mcs_constrained_types['types']:
return
self.fd.write ("""
.SH "MCS Constrained"