From c83a9507f0ac72d2d1d8985831f59c9398d3c14f Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Fri, 24 Nov 2017 14:17:33 +0100 Subject: [PATCH] policycoreutils-2.7-2.fc27 - sepolicy: Fix sepolicy manpage. - semanage: Update Infiniband code to work on python3 - semanage: Fix export of ibendport entries - semanage: Enforce noreload only if it's requested by -N option - semanage: Don't use global setup variable - semanage: drop *_ini functions - semanage: Enable listing file_contexts.homedirs - semanage: make seobject.py backward compatible - gui: remove mappingsPage - gui: delete overridden definition of usersPage.delete() - gui: fix parsing of "semodule -lfull" in tab Modules - gui: remove the status bar - sepolicy: support non-MLS policy in gui - sepolicy: ignore comments and empty lines in file_contexts.subs_dist - gui: port to Python 3 by migrating to PyGI - sepolicy: do not fail when file_contexts.local or .subs do not exist - restorecond: check write() and daemon() results - sepolicy: remove stray space in section "SEE ALSO" - sepolicy: support non-MCS policy in manpage - sepolicy: support non-MLS policy in manpage - sepolicy: fix misspelling of _ra_content_t suffix - sepolicy: do not fail when file_contexts.local does not exist --- policycoreutils-fedora.patch | 45 + policycoreutils.spec | 42 +- restorecond-fedora.patch | 29 + selinux-gui-fedora.patch | 3355 +++++++++++++++++++++++++++++++++- selinux-python-fedora.patch | 847 ++++++++- 5 files changed, 4290 insertions(+), 28 deletions(-) create mode 100644 restorecond-fedora.patch diff --git a/policycoreutils-fedora.patch b/policycoreutils-fedora.patch index c32e96d..c8aaba7 100644 --- a/policycoreutils-fedora.patch +++ b/policycoreutils-fedora.patch @@ -1,3 +1,35 @@ +diff --git policycoreutils-2.7/load_policy/load_policy.8 policycoreutils-2.7/load_policy/load_policy.8 +index 5f5550d..0810995 100644 +--- policycoreutils-2.7/load_policy/load_policy.8 ++++ policycoreutils-2.7/load_policy/load_policy.8 +@@ -39,4 +39,4 @@ Initial policy load failed and enforcing mode requested + .SH AUTHORS + .nf + This manual page was written by Dan Walsh . +-The program was written by Stephen Smalley . ++The program was written by Stephen Smalley . +diff --git policycoreutils-2.7/newrole/hashtab.c policycoreutils-2.7/newrole/hashtab.c +index 77ed143..24c65c4 100644 +--- policycoreutils-2.7/newrole/hashtab.c ++++ policycoreutils-2.7/newrole/hashtab.c +@@ -1,5 +1,5 @@ + +-/* Author : Stephen Smalley, */ ++/* Author : Stephen Smalley, */ + + /* FLASK */ + +diff --git policycoreutils-2.7/newrole/hashtab.h policycoreutils-2.7/newrole/hashtab.h +index 9f737df..3790f0a 100644 +--- policycoreutils-2.7/newrole/hashtab.h ++++ policycoreutils-2.7/newrole/hashtab.h +@@ -1,5 +1,5 @@ + +-/* Author : Stephen Smalley, */ ++/* Author : Stephen Smalley, */ + + /* FLASK */ + diff --git policycoreutils-2.7/scripts/fixfiles policycoreutils-2.7/scripts/fixfiles index 1aa330f..7ec0396 100755 --- policycoreutils-2.7/scripts/fixfiles @@ -10,3 +42,16 @@ index 1aa330f..7ec0396 100755 FORCEFLAG="" RPMFILES="" PREFC="" +diff --git policycoreutils-2.7/setfiles/setfiles.8 policycoreutils-2.7/setfiles/setfiles.8 +index 9501845..ccaaf4d 100644 +--- policycoreutils-2.7/setfiles/setfiles.8 ++++ policycoreutils-2.7/setfiles/setfiles.8 +@@ -255,7 +255,7 @@ being updated provided there are no errors. + + .SH "AUTHOR" + This man page was written by Russell Coker . +-The program was written by Stephen Smalley ++The program was written by Stephen Smalley + + .SH "SEE ALSO" + .BR restorecon (8), diff --git a/policycoreutils.spec b/policycoreutils.spec index 085b746..bb68bad 100644 --- a/policycoreutils.spec +++ b/policycoreutils.spec @@ -1,7 +1,7 @@ %global libauditver 2.1.3-4 -%global libsepolver 2.7-1 -%global libsemanagever 2.7-1 -%global libselinuxver 2.7-1 +%global libsepolver 2.7-2 +%global libsemanagever 2.7-2 +%global libselinuxver 2.7-3 %global sepolgenver 2.7 %global generatorsdir %{_prefix}/lib/systemd/system-generators @@ -9,7 +9,7 @@ Summary: SELinux policy core utilities Name: policycoreutils Version: 2.7 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv2 Group: System Environment/Base # https://github.com/SELinuxProject/selinux/wiki/Releases @@ -31,8 +31,10 @@ Source18: selinux-autorelabel.target Source19: selinux-autorelabel-generator.sh # download https://raw.githubusercontent.com/fedora-selinux/scripts/master/selinux/make-fedora-selinux-patch.sh # run: -# $ VERSION=2.7 ./make-fedora-selinux-patch.sh policycoreutils -# HEAD https://github.com/fedora-selinux/selinux/commit/70a12c5e7b56a81223d67ce2469292826b84efe9 +# HEAD https://github.com/fedora-selinux/selinux/commit/e5a6540888e254b245d42b7cecf0b895d64ddc43 +# $ for i in policycoreutils selinux-python selinux-gui selinux-sandbox selinux-dbus semodule-utils restorecond; do +# BRANCH=f27 VERSION=2.7 ./make-fedora-selinux-patch.sh $i +# done Patch: policycoreutils-fedora.patch # $ VERSION=2.7 ./make-fedora-selinux-patch.sh selinux-python Patch1: selinux-python-fedora.patch @@ -40,7 +42,7 @@ Patch2: selinux-gui-fedora.patch Patch3: selinux-sandbox-fedora.patch Patch4: selinux-dbus-fedora.patch # Patch5: semodule-utils-fedora.patch -# Patch6: restorecond +Patch6: restorecond-fedora.patch Obsoletes: policycoreutils < 2.0.61-2 Conflicts: filesystem < 3, selinux-policy-base < 3.13.1-138 # initscripts < 9.66 shipped fedora-autorelabel services which are renamed to selinux-relabel @@ -185,6 +187,7 @@ sed -i '1s%\(#! *\)/usr/bin/python\([^3].*\|\)$%\1%{__python3}\2%' \ %{buildroot}%{_bindir}/audit2why \ %{buildroot}%{_bindir}/sepolicy \ %{buildroot}%{_bindir}/sepolgen{,-ifgen} \ + %{buildroot}%{_datadir}/system-config-selinux/system-config-selinux.py \ %{buildroot}%{_datadir}/system-config-selinux/selinux_server.py \ %nil @@ -400,6 +403,7 @@ system-config-selinux is a utility for managing the SELinux environment %{_datadir}/system-config-selinux/polgengui.py* %{_datadir}/system-config-selinux/system-config-selinux.py* %{_datadir}/system-config-selinux/*.glade +%{_datadir}/system-config-selinux/*.ui %{python_sitelib}/sepolicy/gui.py* %{python_sitelib}/sepolicy/sepolicy.glade %dir %{python_sitelib}/sepolicy/help @@ -498,6 +502,30 @@ The policycoreutils-restorecond package contains the restorecond service. %systemd_postun_with_restart restorecond.service %changelog +* Fri Nov 24 2017 Petr Lautrbach - 2.7-2 +- sepolicy: Fix sepolicy manpage. +- semanage: Update Infiniband code to work on python3 +- semanage: Fix export of ibendport entries +- semanage: Enforce noreload only if it's requested by -N option +- semanage: Don't use global setup variable +- semanage: drop *_ini functions +- semanage: Enable listing file_contexts.homedirs +- semanage: make seobject.py backward compatible +- gui: remove mappingsPage +- gui: delete overridden definition of usersPage.delete() +- gui: fix parsing of "semodule -lfull" in tab Modules +- gui: remove the status bar +- sepolicy: support non-MLS policy in gui +- sepolicy: ignore comments and empty lines in file_contexts.subs_dist +- gui: port to Python 3 by migrating to PyGI +- sepolicy: do not fail when file_contexts.local or .subs do not exist +- restorecond: check write() and daemon() results +- sepolicy: remove stray space in section "SEE ALSO" +- sepolicy: support non-MCS policy in manpage +- sepolicy: support non-MLS policy in manpage +- sepolicy: fix misspelling of _ra_content_t suffix +- sepolicy: do not fail when file_contexts.local does not exist + * Mon Aug 07 2017 Petr Lautrbach - 2.7-1 - Update to upstream release 2017-08-04 - Move DBUS API from -gui to -dbus package diff --git a/restorecond-fedora.patch b/restorecond-fedora.patch new file mode 100644 index 0000000..5e07eac --- /dev/null +++ b/restorecond-fedora.patch @@ -0,0 +1,29 @@ +diff --git restorecond-2.7/restorecond.c restorecond-2.7/restorecond.c +index f379db1..6fbbd35 100644 +--- restorecond-2.7/restorecond.c ++++ restorecond-2.7/restorecond.c +@@ -103,7 +103,10 @@ static int write_pid_file(void) + pidfile = 0; + return 1; + } +- (void)write(pidfd, val, (unsigned int)len); ++ if (write(pidfd, val, (unsigned int)len) != len) { ++ syslog(LOG_ERR, "Unable to write to pidfile (%s)", strerror(errno)); ++ return 1; ++ } + close(pidfd); + return 0; + } +@@ -204,8 +207,10 @@ int main(int argc, char **argv) + watch_file = server_watch_file; + read_config(master_fd, watch_file); + +- if (!debug_mode) +- daemon(0, 0); ++ if (!debug_mode) { ++ if (daemon(0, 0) < 0) ++ exitApp("daemon"); ++ } + + write_pid_file(); + diff --git a/selinux-gui-fedora.patch b/selinux-gui-fedora.patch index 2ecb394..7ba7ab5 100644 --- a/selinux-gui-fedora.patch +++ b/selinux-gui-fedora.patch @@ -1,7 +1,513 @@ +diff --git selinux-gui-2.7/Makefile selinux-gui-2.7/Makefile +index 4fc2c1a..cfe4740 100644 +--- selinux-gui-2.7/Makefile ++++ selinux-gui-2.7/Makefile +@@ -11,14 +11,13 @@ domainsPage.py \ + fcontextPage.py \ + html_util.py \ + loginsPage.py \ +-mappingsPage.py \ + modulesPage.py \ + polgen.glade \ + portsPage.py \ + semanagePage.py \ + statusPage.py \ +-system-config-selinux.glade \ + system-config-selinux.png \ ++system-config-selinux.ui \ + usersPage.py + + all: $(TARGETS) system-config-selinux.py polgengui.py +diff --git selinux-gui-2.7/booleansPage.py selinux-gui-2.7/booleansPage.py +index a5d04bf..7849bea 100644 +--- selinux-gui-2.7/booleansPage.py ++++ selinux-gui-2.7/booleansPage.py +@@ -18,13 +18,8 @@ + # You should have received a copy of the GNU General Public License + # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + # +-import string +-import gtk +-import gtk.glade +-import os +-import gobject + import sys +-import tempfile ++from gi.repository import Gdk, GObject, Gtk + import seobject + import semanagePage + +@@ -61,8 +56,6 @@ except: + import __builtin__ + __builtin__.__dict__['_'] = unicode + +-from glob import fnmatch +- + + class Modifier: + +@@ -94,56 +87,53 @@ class booleansPage: + + def __init__(self, xml, doDebug=None): + self.xml = xml +- self.window = self.xml.get_widget("mainWindow").get_root_window() ++ self.window = self.xml.get_object("mainWindow").get_root_window() + self.local = False + self.types = [] + self.selinuxsupport = True + self.typechanged = False + self.doDebug = doDebug +- self.busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH) +- self.ready_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR) ++ self.busy_cursor = Gdk.Cursor.new(Gdk.CursorType.WATCH) ++ self.ready_cursor = Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR) + + # Bring in widgets from glade file. +- self.typeHBox = xml.get_widget("typeHBox") +- self.booleanSW = xml.get_widget("booleanSW") +- self.booleansFilter = xml.get_widget("booleansFilter") ++ self.booleansFilter = xml.get_object("booleansFilter") + self.booleansFilter.connect("focus_out_event", self.filter_changed) + self.booleansFilter.connect("activate", self.filter_changed) ++ self.booleansFilter.connect("changed", self.filter_changed) + +- self.booleansView = xml.get_widget("booleansView") +- self.typeLabel = xml.get_widget("typeLabel") +- self.modifySeparator = xml.get_widget("modifySeparator") ++ self.booleansView = xml.get_object("booleansView") + +- self.revertButton = xml.get_widget("booleanRevertButton") ++ self.revertButton = xml.get_object("booleanRevertButton") + self.revertButton.set_sensitive(self.local) + self.revertButton.connect("clicked", self.on_revert_clicked) +- listStore = gtk.ListStore(gobject.TYPE_STRING) +- cell = gtk.CellRendererText() ++ listStore = Gtk.ListStore(GObject.TYPE_STRING) ++ cell = Gtk.CellRendererText() + +- self.store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) +- self.store.set_sort_column_id(1, gtk.SORT_ASCENDING) ++ self.store = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING) ++ self.store.set_sort_column_id(1, Gtk.SortType.ASCENDING) + self.booleansView.set_model(self.store) + +- checkbox = gtk.CellRendererToggle() ++ checkbox = Gtk.CellRendererToggle() + checkbox.connect("toggled", self.boolean_toggled) +- col = gtk.TreeViewColumn('Active', checkbox, active=ACTIVE) ++ col = Gtk.TreeViewColumn('Active', checkbox, active=ACTIVE) + col.set_clickable(True) + col.set_sort_column_id(ACTIVE) + self.booleansView.append_column(col) + +- col = gtk.TreeViewColumn("Module", gtk.CellRendererText(), text=MODULE) ++ col = Gtk.TreeViewColumn("Module", Gtk.CellRendererText(), text=MODULE) + col.set_sort_column_id(MODULE) + col.set_resizable(True) + self.booleansView.append_column(col) + +- col = gtk.TreeViewColumn("Description", gtk.CellRendererText(), text=DESC) +- col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) ++ col = Gtk.TreeViewColumn("Description", Gtk.CellRendererText(), text=DESC) ++ col.set_sizing(Gtk.TreeViewColumnSizing.FIXED) + col.set_fixed_width(400) + col.set_sort_column_id(DESC) + col.set_resizable(True) + self.booleansView.append_column(col) + +- col = gtk.TreeViewColumn("Name", gtk.CellRendererText(), text=BOOLEAN) ++ col = Gtk.TreeViewColumn("Name", Gtk.CellRendererText(), text=BOOLEAN) + col.set_sort_column_id(BOOLEAN) + col.set_resizable(True) + self.booleansView.set_search_equal_func(self.__search) +@@ -152,10 +142,10 @@ class booleansPage: + self.load(self.filter) + + def error(self, message): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, +- gtk.BUTTONS_CLOSE, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR, ++ Gtk.ButtonsType.CLOSE, + message) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + dlg.run() + dlg.destroy() +@@ -178,11 +168,11 @@ class booleansPage: + + def deleteDialog(self): + store, iter = self.booleansView.get_selection().get_selected() +- if iter == None: ++ if iter is None: + return + boolean = store.get_value(iter, BOOLEAN) + # change cursor +- if boolean == None: ++ if boolean is None: + return + try: + self.wait() +diff --git selinux-gui-2.7/domainsPage.py selinux-gui-2.7/domainsPage.py +index 66f882a..bad5140 100644 +--- selinux-gui-2.7/domainsPage.py ++++ selinux-gui-2.7/domainsPage.py +@@ -16,19 +16,14 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade + import os + try: + from subprocess import getstatusoutput + except ImportError: + from commands import getstatusoutput + +-import gobject + import sys +-import seobject +-import selinux ++from gi.repository import GObject, Gtk + import sepolicy + from semanagePage import * + +@@ -58,26 +53,26 @@ class domainsPage(semanagePage): + + def __init__(self, xml): + semanagePage.__init__(self, xml, "domains", _("Process Domain")) +- self.domain_filter = xml.get_widget("domainsFilterEntry") ++ self.domain_filter = xml.get_object("domainsFilterEntry") + self.domain_filter.connect("focus_out_event", self.filter_changed) + self.domain_filter.connect("activate", self.filter_changed) + +- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING) ++ self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING) + self.view.set_model(self.store) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Domain Name"), gtk.CellRendererText(), text=0) ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Domain Name"), Gtk.CellRendererText(), text=0) + col.set_sort_column_id(0) + col.set_resizable(True) + self.view.append_column(col) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Mode"), gtk.CellRendererText(), text=1) ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Mode"), Gtk.CellRendererText(), text=1) + col.set_sort_column_id(1) + col.set_resizable(True) + self.view.append_column(col) + self.view.get_selection().connect("changed", self.itemSelected) + +- self.permissive_button = xml.get_widget("permissiveButton") +- self.enforcing_button = xml.get_widget("enforcingButton") ++ self.permissive_button = xml.get_object("permissiveButton") ++ self.enforcing_button = xml.get_object("enforcingButton") + + self.domains = sepolicy.get_all_entrypoint_domains() + self.load() +@@ -112,7 +107,7 @@ class domainsPage(semanagePage): + + def itemSelected(self, selection): + store, iter = selection.get_selected() +- if iter == None: ++ if iter is None: + return + p = store.get_value(iter, 1) == _("Permissive") + self.permissive_button.set_sensitive(not p) +diff --git selinux-gui-2.7/fcontextPage.py selinux-gui-2.7/fcontextPage.py +index 2e26666..a6577ef 100644 +--- selinux-gui-2.7/fcontextPage.py ++++ selinux-gui-2.7/fcontextPage.py +@@ -16,10 +16,7 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import gtk +-import gtk.glade +-import os +-import gobject ++from gi.repository import GObject, Gtk + import seobject + try: + from subprocess import getstatusoutput +@@ -73,40 +70,40 @@ class fcontextPage(semanagePage): + + def __init__(self, xml): + semanagePage.__init__(self, xml, "fcontext", _("File Labeling")) +- self.fcontextFilter = xml.get_widget("fcontextFilterEntry") ++ self.fcontextFilter = xml.get_object("fcontextFilterEntry") + self.fcontextFilter.connect("focus_out_event", self.filter_changed) + self.fcontextFilter.connect("activate", self.filter_changed) + +- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) +- self.view = xml.get_widget("fcontextView") ++ self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING) ++ self.view = xml.get_object("fcontextView") + self.view.set_model(self.store) + self.view.set_search_equal_func(self.search) + +- col = gtk.TreeViewColumn(_("File\nSpecification"), gtk.CellRendererText(), text=SPEC_COL) +- col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) ++ col = Gtk.TreeViewColumn(_("File\nSpecification"), Gtk.CellRendererText(), text=SPEC_COL) ++ col.set_sizing(Gtk.TreeViewColumnSizing.FIXED) + col.set_fixed_width(250) + + col.set_sort_column_id(SPEC_COL) + col.set_resizable(True) + self.view.append_column(col) +- col = gtk.TreeViewColumn(_("Selinux\nFile Type"), gtk.CellRendererText(), text=TYPE_COL) ++ col = Gtk.TreeViewColumn(_("Selinux\nFile Type"), Gtk.CellRendererText(), text=TYPE_COL) + +- col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) ++ col.set_sizing(Gtk.TreeViewColumnSizing.FIXED) + col.set_fixed_width(250) + col.set_sort_column_id(TYPE_COL) + col.set_resizable(True) + self.view.append_column(col) +- col = gtk.TreeViewColumn(_("File\nType"), gtk.CellRendererText(), text=2) ++ col = Gtk.TreeViewColumn(_("File\nType"), Gtk.CellRendererText(), text=2) + col.set_sort_column_id(FTYPE_COL) + col.set_resizable(True) + self.view.append_column(col) + +- self.store.set_sort_column_id(SPEC_COL, gtk.SORT_ASCENDING) ++ self.store.set_sort_column_id(SPEC_COL, Gtk.SortType.ASCENDING) + self.load() +- self.fcontextEntry = xml.get_widget("fcontextEntry") +- self.fcontextFileTypeCombo = xml.get_widget("fcontextFileTypeCombo") +- self.fcontextTypeEntry = xml.get_widget("fcontextTypeEntry") +- self.fcontextMLSEntry = xml.get_widget("fcontextMLSEntry") ++ self.fcontextEntry = xml.get_object("fcontextEntry") ++ self.fcontextFileTypeCombo = xml.get_object("fcontextFileTypeCombo") ++ self.fcontextTypeEntry = xml.get_object("fcontextTypeEntry") ++ self.fcontextMLSEntry = xml.get_object("fcontextMLSEntry") + + def match(self, fcon_dict, k, filter): + try: +@@ -192,7 +189,7 @@ class fcontextPage(semanagePage): + mls = self.fcontextMLSEntry.get_text().strip() + list_model = self.fcontextFileTypeCombo.get_model() + it = self.fcontextFileTypeCombo.get_active_iter() +- ftype = list_model.get_value(it,0) ++ ftype = list_model.get_value(it, 0) + self.wait() + (rc, out) = getstatusoutput("semanage fcontext -a -t %s -r %s -f '%s' '%s'" % (type, mls, seobject.file_type_str_to_option[ftype], fspec)) + self.ready() +diff --git selinux-gui-2.7/loginsPage.py selinux-gui-2.7/loginsPage.py +index 1f35a57..b67eb8b 100644 +--- selinux-gui-2.7/loginsPage.py ++++ selinux-gui-2.7/loginsPage.py +@@ -16,17 +16,13 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade +-import os +-import gobject + import sys + try: + from subprocess import getstatusoutput + except ImportError: + from commands import getstatusoutput + ++from gi.repository import GObject, Gtk + import seobject + from semanagePage import * + +@@ -57,23 +53,23 @@ class loginsPage(semanagePage): + def __init__(self, xml): + self.firstTime = False + semanagePage.__init__(self, xml, "logins", _("User Mapping")) +- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) ++ self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING) + self.view.set_model(self.store) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Login\nName"), gtk.CellRendererText(), text=0) ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Login\nName"), Gtk.CellRendererText(), text=0) + col.set_sort_column_id(0) + col.set_resizable(True) + self.view.append_column(col) +- col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text=1) ++ col = Gtk.TreeViewColumn(_("SELinux\nUser"), Gtk.CellRendererText(), text=1) + col.set_resizable(True) + self.view.append_column(col) +- col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text=2) ++ col = Gtk.TreeViewColumn(_("MLS/\nMCS Range"), Gtk.CellRendererText(), text=2) + col.set_resizable(True) + self.view.append_column(col) + self.load() +- self.loginsNameEntry = xml.get_widget("loginsNameEntry") +- self.loginsSelinuxUserCombo = xml.get_widget("loginsSelinuxUserCombo") +- self.loginsMLSEntry = xml.get_widget("loginsMLSEntry") ++ self.loginsNameEntry = xml.get_object("loginsNameEntry") ++ self.loginsSelinuxUserCombo = xml.get_object("loginsSelinuxUserCombo") ++ self.loginsMLSEntry = xml.get_object("loginsMLSEntry") + + def load(self, filter=""): + self.filter = filter +@@ -91,12 +87,12 @@ class loginsPage(semanagePage): + self.view.get_selection().select_path((0,)) + + def __dialogSetup(self): +- if self.firstTime == True: ++ if self.firstTime: + return + self.firstTime = True +- liststore = gtk.ListStore(gobject.TYPE_STRING) ++ liststore = Gtk.ListStore(GObject.TYPE_STRING) + self.loginsSelinuxUserCombo.set_model(liststore) +- cell = gtk.CellRendererText() ++ cell = Gtk.CellRendererText() + self.loginsSelinuxUserCombo.pack_start(cell, True) + self.loginsSelinuxUserCombo.add_attribute(cell, 'text', 0) + +diff --git selinux-gui-2.7/modulesPage.py selinux-gui-2.7/modulesPage.py +index 3767896..34c5d9e 100644 +--- selinux-gui-2.7/modulesPage.py ++++ selinux-gui-2.7/modulesPage.py +@@ -16,21 +16,16 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade +-import os ++import sys ++from subprocess import Popen, PIPE + try: + from subprocess import getstatusoutput + except ImportError: + from commands import getstatusoutput + +-import gobject +-import sys +-import seobject ++from gi.repository import GObject, Gtk + import selinux + from semanagePage import * +-from subprocess import Popen, PIPE + + ## + ## I18N +@@ -58,27 +53,33 @@ class modulesPage(semanagePage): + + def __init__(self, xml): + semanagePage.__init__(self, xml, "modules", _("Policy Module")) +- self.module_filter = xml.get_widget("modulesFilterEntry") ++ self.module_filter = xml.get_object("modulesFilterEntry") + self.module_filter.connect("focus_out_event", self.filter_changed) + self.module_filter.connect("activate", self.filter_changed) + self.audit_enabled = False + +- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING) ++ self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING, ++ GObject.TYPE_STRING) + self.view.set_model(self.store) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Module Name"), gtk.CellRendererText(), text=0) ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Module Name"), Gtk.CellRendererText(), text=0) + col.set_sort_column_id(0) + col.set_resizable(True) + self.view.append_column(col) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Version"), gtk.CellRendererText(), text=1) +- self.enable_audit_button = xml.get_widget("enableAuditButton") ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Priority"), Gtk.CellRendererText(), text=1) ++ self.enable_audit_button = xml.get_object("enableAuditButton") + self.enable_audit_button.connect("clicked", self.enable_audit) +- self.new_button = xml.get_widget("newModuleButton") ++ self.new_button = xml.get_object("newModuleButton") + self.new_button.connect("clicked", self.new_module) + col.set_sort_column_id(1) + col.set_resizable(True) + self.view.append_column(col) ++ self.store.set_sort_column_id(2, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Kind"), Gtk.CellRendererText(), text=2) ++ col.set_sort_column_id(2) ++ col.set_resizable(True) ++ self.view.append_column(col) + self.store.set_sort_func(1, self.sort_int, "") + status, self.policy_type = selinux.selinux_getpolicytype() + +@@ -100,16 +101,17 @@ class modulesPage(semanagePage): + self.filter = filter + self.store.clear() + try: +- fd = Popen("semodule -l", shell=True, stdout=PIPE).stdout ++ fd = Popen("semodule -lfull", shell=True, stdout=PIPE).stdout + l = fd.readlines() + fd.close() + for i in l: +- module, ver, newline = i.split('\t') +- if not (self.match(module, filter) or self.match(ver, filter)): ++ priority, module, kind = i.decode('utf-8').split() ++ if not (self.match(module, filter) or self.match(priority, filter)): + continue + iter = self.store.append() + self.store.set_value(iter, 0, module.strip()) +- self.store.set_value(iter, 1, ver.strip()) ++ self.store.set_value(iter, 1, priority.strip()) ++ self.store.set_value(iter, 2, kind.strip()) + except: + pass + self.view.get_selection().select_path((0,)) +@@ -170,20 +172,20 @@ class modulesPage(semanagePage): + return + + def addDialog(self): +- dialog = gtk.FileChooserDialog(_("Load Policy Module"), ++ dialog = Gtk.FileChooserDialog(_("Load Policy Module"), + None, +- gtk.FILE_CHOOSER_ACTION_OPEN, +- (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, +- gtk.STOCK_OPEN, gtk.RESPONSE_OK)) +- dialog.set_default_response(gtk.RESPONSE_OK) ++ Gtk.FileChooserAction.OPEN, ++ (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, ++ Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) ++ dialog.set_default_response(Gtk.ResponseType.OK) + +- filter = gtk.FileFilter() ++ filter = Gtk.FileFilter() + filter.set_name("Policy Files") + filter.add_pattern("*.pp") + dialog.add_filter(filter) + + response = dialog.run() +- if response == gtk.RESPONSE_OK: ++ if response == Gtk.ResponseType.OK: + self.add(dialog.get_filename()) + dialog.destroy() + diff --git selinux-gui-2.7/polgengui.py selinux-gui-2.7/polgengui.py -index 7460cce..064001b 100644 +index 7460cce..bc01a62 100644 --- selinux-gui-2.7/polgengui.py +++ selinux-gui-2.7/polgengui.py +@@ -22,11 +22,11 @@ + # + import signal + import string +-import gtk +-import gtk.glade ++import gi ++gi.require_version('Gtk', '3.0') ++from gi.repository import Gtk + import os +-import gobject +-import gnome ++from gi.repository import GObject + import sys + try: + import sepolicy @@ -34,7 +34,9 @@ except ValueError as e: sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) sys.exit(1) @@ -12,6 +518,284 @@ index 7460cce..064001b 100644 try: from subprocess import getstatusoutput except ImportError: +@@ -79,8 +81,6 @@ except: + import __builtin__ + __builtin__.__dict__['_'] = unicode + +-gnome.program_init("SELinux Policy Generation Tool", "5") +- + version = "1.0" + + sys.path.append('/usr/share/system-config-selinux') +@@ -95,10 +95,12 @@ def foreach(model, path, iter, selected): + ## + ## Pull in the Glade file + ## ++xml = Gtk.Builder() ++xml.set_translation_domain(PROGNAME) + if os.access("polgen.glade", os.F_OK): +- xml = gtk.glade.XML("polgen.glade", domain=PROGNAME) ++ xml.add_from_file("polgen.glade") + else: +- xml = gtk.glade.XML("/usr/share/system-config-selinux/polgen.glade", domain=PROGNAME) ++ xml.add_from_file("/usr/share/system-config-selinux/polgen.glade") + + FILE = 1 + DIR = 2 +@@ -277,27 +279,27 @@ class childWindow: + b.connect("clicked", self.network_all_clicked) + + self.boolean_treeview = self.xml.get_widget("boolean_treeview") +- self.boolean_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING) ++ self.boolean_store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING) + self.boolean_treeview.set_model(self.boolean_store) +- self.boolean_store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Name"), gtk.CellRendererText(), text=0) ++ self.boolean_store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Name"), Gtk.CellRendererText(), text=0) + self.boolean_treeview.append_column(col) +- col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text=1) ++ col = Gtk.TreeViewColumn(_("Description"), Gtk.CellRendererText(), text=1) + self.boolean_treeview.append_column(col) + + self.role_treeview = self.xml.get_widget("role_treeview") +- self.role_store = gtk.ListStore(gobject.TYPE_STRING) ++ self.role_store = Gtk.ListStore(GObject.TYPE_STRING) + self.role_treeview.set_model(self.role_store) +- self.role_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) +- self.role_store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Role"), gtk.CellRendererText(), text=0) ++ self.role_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) ++ self.role_store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Role"), Gtk.CellRendererText(), text=0) + self.role_treeview.append_column(col) + + self.existing_user_treeview = self.xml.get_widget("existing_user_treeview") +- self.existing_user_store = gtk.ListStore(gobject.TYPE_STRING) ++ self.existing_user_store = Gtk.ListStore(GObject.TYPE_STRING) + self.existing_user_treeview.set_model(self.existing_user_store) +- self.existing_user_store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Existing_User"), gtk.CellRendererText(), text=0) ++ self.existing_user_store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Existing_User"), Gtk.CellRendererText(), text=0) + self.existing_user_treeview.append_column(col) + + for i in self.all_roles: +@@ -307,19 +309,19 @@ class childWindow: + self.in_tcp_reserved_checkbutton = xml.get_widget("in_tcp_reserved_checkbutton") + + self.transition_treeview = self.xml.get_widget("transition_treeview") +- self.transition_store = gtk.ListStore(gobject.TYPE_STRING) ++ self.transition_store = Gtk.ListStore(GObject.TYPE_STRING) + self.transition_treeview.set_model(self.transition_store) +- self.transition_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) +- self.transition_store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text=0) ++ self.transition_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) ++ self.transition_store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Application"), Gtk.CellRendererText(), text=0) + self.transition_treeview.append_column(col) + + self.user_transition_treeview = self.xml.get_widget("user_transition_treeview") +- self.user_transition_store = gtk.ListStore(gobject.TYPE_STRING) ++ self.user_transition_store = Gtk.ListStore(GObject.TYPE_STRING) + self.user_transition_treeview.set_model(self.user_transition_store) +- self.user_transition_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) +- self.user_transition_store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text=0) ++ self.user_transition_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) ++ self.user_transition_store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Application"), Gtk.CellRendererText(), text=0) + self.user_transition_treeview.append_column(col) + + for i in self.all_users: +@@ -329,11 +331,11 @@ class childWindow: + self.existing_user_store.set_value(iter, 0, i[:-2]) + + self.admin_treeview = self.xml.get_widget("admin_treeview") +- self.admin_store = gtk.ListStore(gobject.TYPE_STRING) ++ self.admin_store = Gtk.ListStore(GObject.TYPE_STRING) + self.admin_treeview.set_model(self.admin_store) +- self.admin_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) +- self.admin_store.set_sort_column_id(0, gtk.SORT_ASCENDING) +- col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text=0) ++ self.admin_treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) ++ self.admin_store.set_sort_column_id(0, Gtk.SortType.ASCENDING) ++ col = Gtk.TreeViewColumn(_("Application"), Gtk.CellRendererText(), text=0) + self.admin_treeview.append_column(col) + + try: +@@ -383,17 +385,17 @@ class childWindow: + + if self.pages[type][self.current_page] == self.FINISH_PAGE: + self.generate_policy() +- self.xml.get_widget("cancel_button").set_label(gtk.STOCK_CLOSE) ++ self.xml.get_widget("cancel_button").set_label(Gtk.STOCK_CLOSE) + else: + self.current_page = self.current_page + 1 + self.notebook.set_current_page(self.pages[type][self.current_page]) + if self.pages[type][self.current_page] == self.FINISH_PAGE: +- self.forward_button.set_label(gtk.STOCK_APPLY) ++ self.forward_button.set_label(Gtk.STOCK_APPLY) + + def back(self, arg): + type = self.get_type() + if self.pages[type][self.current_page] == self.FINISH_PAGE: +- self.forward_button.set_label(gtk.STOCK_GO_FORWARD) ++ self.forward_button.set_label(Gtk.STOCK_GO_FORWARD) + + self.current_page = self.current_page - 1 + self.notebook.set_current_page(self.pages[type][self.current_page]) +@@ -406,30 +408,30 @@ class childWindow: + b.set_sensitive(not active) + + def verify(self, message, title=""): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, +- gtk.BUTTONS_YES_NO, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO, ++ Gtk.ButtonsType.YES_NO, + message) + dlg.set_title(title) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + rc = dlg.run() + dlg.destroy() + return rc + + def info(self, message): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, +- gtk.BUTTONS_OK, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO, ++ Gtk.ButtonsType.OK, + message) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + dlg.run() + dlg.destroy() + + def error(self, message): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, +- gtk.BUTTONS_CLOSE, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR, ++ Gtk.ButtonsType.CLOSE, + message) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + dlg.run() + dlg.destroy() +@@ -550,7 +552,7 @@ class childWindow: + self.boolean_description_entry.set_text("") + rc = self.boolean_dialog.run() + self.boolean_dialog.hide() +- if rc == gtk.RESPONSE_CANCEL: ++ if rc == Gtk.ResponseType.CANCEL: + return + iter = self.boolean_store.append() + self.boolean_store.set_value(iter, 0, self.boolean_name_entry.get_text()) +@@ -559,7 +561,7 @@ class childWindow: + def __add(self, type): + rc = self.file_dialog.run() + self.file_dialog.hide() +- if rc == gtk.RESPONSE_CANCEL: ++ if rc == Gtk.ResponseType.CANCEL: + return + for i in self.file_dialog.get_filenames(): + iter = self.store.append() +@@ -569,29 +571,29 @@ class childWindow: + def exec_select(self, args): + self.file_dialog.set_select_multiple(0) + self.file_dialog.set_title(_("Select executable file to be confined.")) +- self.file_dialog.set_action(gtk.FILE_CHOOSER_ACTION_OPEN) ++ self.file_dialog.set_action(Gtk.FileChooserAction.OPEN) + self.file_dialog.set_current_folder("/usr/sbin") + rc = self.file_dialog.run() + self.file_dialog.hide() +- if rc == gtk.RESPONSE_CANCEL: ++ if rc == Gtk.ResponseType.CANCEL: + return + self.exec_entry.set_text(self.file_dialog.get_filename()) + + def init_script_select(self, args): + self.file_dialog.set_select_multiple(0) + self.file_dialog.set_title(_("Select init script file to be confined.")) +- self.file_dialog.set_action(gtk.FILE_CHOOSER_ACTION_OPEN) ++ self.file_dialog.set_action(Gtk.FileChooserAction.OPEN) + self.file_dialog.set_current_folder("/etc/rc.d/init.d") + rc = self.file_dialog.run() + self.file_dialog.hide() +- if rc == gtk.RESPONSE_CANCEL: ++ if rc == Gtk.ResponseType.CANCEL: + return + self.init_script_entry.set_text(self.file_dialog.get_filename()) + + def add(self, args): + self.file_dialog.set_title(_("Select file(s) that confined application creates or writes")) + self.file_dialog.set_current_folder("/") +- self.file_dialog.set_action(gtk.FILE_CHOOSER_ACTION_OPEN) ++ self.file_dialog.set_action(Gtk.FileChooserAction.OPEN) + self.file_dialog.set_select_multiple(1) + self.__add(FILE) + +@@ -599,7 +601,7 @@ class childWindow: + self.file_dialog.set_title(_("Select directory(s) that the confined application owns and writes into")) + self.file_dialog.set_current_folder("/") + self.file_dialog.set_select_multiple(1) +- self.file_dialog.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) ++ self.file_dialog.set_action(Gtk.FileChooserAction.SELECT_FOLDER) + self.__add(DIR) + + def on_about_clicked(self, args): +@@ -608,7 +610,7 @@ class childWindow: + dlg.hide() + + def quit(self, args): +- gtk.main_quit() ++ Gtk.main_quit() + + def setupScreen(self): + # Bring in widgets from glade file. +@@ -650,20 +652,20 @@ class childWindow: + self.view = self.xml.get_widget("write_treeview") + self.file_dialog = self.xml.get_widget("filechooserdialog") + +- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT) ++ self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_INT) + self.view.set_model(self.store) +- col = gtk.TreeViewColumn("", gtk.CellRendererText(), text=0) ++ col = Gtk.TreeViewColumn("", Gtk.CellRendererText(), text=0) + col.set_resizable(True) + self.view.append_column(col) + self.view.get_selection().select_path((0,)) + + def output_button_clicked(self, *args): + self.file_dialog.set_title(_("Select directory to generate policy files in")) +- self.file_dialog.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER) ++ self.file_dialog.set_action(Gtk.FileChooserAction.SELECT_FOLDER) + self.file_dialog.set_select_multiple(0) + rc = self.file_dialog.run() + self.file_dialog.hide() +- if rc == gtk.RESPONSE_CANCEL: ++ if rc == Gtk.ResponseType.CANCEL: + return + self.output_entry.set_text(self.file_dialog.get_filename()) + +@@ -675,11 +677,11 @@ class childWindow: + name = entry.get_text() + if self.name != name: + if name in self.all_types: +- if self.verify(_("Type %s_t already defined in current policy.\nDo you want to continue?") % name, _("Verify Name")) == gtk.RESPONSE_NO: ++ if self.verify(_("Type %s_t already defined in current policy.\nDo you want to continue?") % name, _("Verify Name")) == Gtk.ResponseType.NO: + entry.set_text("") + return False + if name in self.all_modules: +- if self.verify(_("Module %s already loaded in current policy.\nDo you want to continue?") % name, _("Verify Name")) == gtk.RESPONSE_NO: ++ if self.verify(_("Module %s already loaded in current policy.\nDo you want to continue?") % name, _("Verify Name")) == Gtk.ResponseType.NO: + entry.set_text("") + return False + @@ -696,16 +698,16 @@ class childWindow: def on_in_net_page_next(self, *args): @@ -33,11 +817,34 @@ index 7460cce..064001b 100644 except ValueError as e: self.error(e.message) return True +@@ -770,7 +772,7 @@ class childWindow: + self.mainWindow.connect("destroy", self.quit) + + self.mainWindow.show_all() +- gtk.main() ++ Gtk.main() + + if __name__ == "__main__": + signal.signal(signal.SIGINT, signal.SIG_DFL) diff --git selinux-gui-2.7/portsPage.py selinux-gui-2.7/portsPage.py -index b8fdaad..f86d2d3 100644 +index b8fdaad..03179c5 100644 --- selinux-gui-2.7/portsPage.py +++ selinux-gui-2.7/portsPage.py -@@ -40,6 +40,12 @@ from semanagePage import * +@@ -16,12 +16,8 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade +-import os +-import gobject + import sys ++from gi.repository import GObject, Gtk + import seobject + + TYPE_COL = 0 +@@ -40,6 +36,12 @@ from semanagePage import * ## I18N ## PROGNAME = "policycoreutils" @@ -50,3 +857,2545 @@ index b8fdaad..f86d2d3 100644 try: import gettext kwargs = {} +@@ -62,18 +64,19 @@ class portsPage(semanagePage): + + def __init__(self, xml): + semanagePage.__init__(self, xml, "ports", _("Network Port")) +- xml.signal_connect("on_group_clicked", self.on_group_clicked) ++ group_listview = xml.get_object("listViewButton") ++ group_listview.connect("clicked", self.on_group_clicked) + self.group = False +- self.ports_filter = xml.get_widget("portsFilterEntry") ++ self.ports_filter = xml.get_object("portsFilterEntry") + self.ports_filter.connect("focus_out_event", self.filter_changed) + self.ports_filter.connect("activate", self.filter_changed) +- self.ports_name_entry = xml.get_widget("portsNameEntry") +- self.ports_protocol_combo = xml.get_widget("portsProtocolCombo") +- self.ports_number_entry = xml.get_widget("portsNumberEntry") +- self.ports_mls_entry = xml.get_widget("portsMLSEntry") +- self.ports_add_button = xml.get_widget("portsAddButton") +- self.ports_properties_button = xml.get_widget("portsPropertiesButton") +- self.ports_delete_button = xml.get_widget("portsDeleteButton") ++ self.ports_name_entry = xml.get_object("portsNameEntry") ++ self.ports_protocol_combo = xml.get_object("portsProtocolCombo") ++ self.ports_number_entry = xml.get_object("portsNumberEntry") ++ self.ports_mls_entry = xml.get_object("portsMLSEntry") ++ self.ports_add_button = xml.get_object("portsAddButton") ++ self.ports_properties_button = xml.get_object("portsPropertiesButton") ++ self.ports_delete_button = xml.get_object("portsDeleteButton") + liststore = self.ports_protocol_combo.get_model() + iter = liststore.get_iter_first() + self.ports_protocol_combo.set_active_iter(iter) +@@ -90,28 +93,28 @@ class portsPage(semanagePage): + self.group_load(filter) + + def init_store(self): +- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) ++ self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING) + self.view.set_model(self.store) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) + + self.view.set_search_equal_func(self.search) +- col = gtk.TreeViewColumn(_("SELinux Port\nType"), gtk.CellRendererText(), text=TYPE_COL) ++ col = Gtk.TreeViewColumn(_("SELinux Port\nType"), Gtk.CellRendererText(), text=TYPE_COL) + col.set_sort_column_id(TYPE_COL) + col.set_resizable(True) + self.view.append_column(col) +- self.store.set_sort_column_id(TYPE_COL, gtk.SORT_ASCENDING) ++ self.store.set_sort_column_id(TYPE_COL, Gtk.SortType.ASCENDING) + +- col = gtk.TreeViewColumn(_("Protocol"), gtk.CellRendererText(), text=PROTOCOL_COL) ++ col = Gtk.TreeViewColumn(_("Protocol"), Gtk.CellRendererText(), text=PROTOCOL_COL) + col.set_sort_column_id(PROTOCOL_COL) + col.set_resizable(True) + self.view.append_column(col) + +- self.mls_col = gtk.TreeViewColumn(_("MLS/MCS\nLevel"), gtk.CellRendererText(), text=MLS_COL) ++ self.mls_col = Gtk.TreeViewColumn(_("MLS/MCS\nLevel"), Gtk.CellRendererText(), text=MLS_COL) + self.mls_col.set_resizable(True) + self.mls_col.set_sort_column_id(MLS_COL) + self.view.append_column(self.mls_col) + +- col = gtk.TreeViewColumn(_("Port"), gtk.CellRendererText(), text=PORT_COL) ++ col = Gtk.TreeViewColumn(_("Port"), Gtk.CellRendererText(), text=PORT_COL) + col.set_sort_column_id(PORT_COL) + col.set_resizable(True) + self.view.append_column(col) +@@ -139,7 +142,7 @@ class portsPage(semanagePage): + continue + iter = self.store.append() + if k[0] == k[1]: +- self.store.set_value(iter, PORT_COL, k[0]) ++ self.store.set_value(iter, PORT_COL, str(k[0])) + else: + rec = "%s-%s" % k[:2] + self.store.set_value(iter, PORT_COL, rec) +diff --git selinux-gui-2.7/semanagePage.py selinux-gui-2.7/semanagePage.py +index 27367f3..560ec07 100644 +--- selinux-gui-2.7/semanagePage.py ++++ selinux-gui-2.7/semanagePage.py +@@ -16,13 +16,8 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade +-import os +-import gobject + import sys +-import seobject ++from gi.repository import Gdk, Gtk + + ## + ## I18N +@@ -47,24 +42,25 @@ except: + + + def idle_func(): +- while gtk.events_pending(): +- gtk.main_iteration() ++ while Gtk.events_pending(): ++ Gtk.main_iteration() + + + class semanagePage: + + def __init__(self, xml, name, description): + self.xml = xml +- self.window = self.xml.get_widget("mainWindow").get_root_window() +- self.busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH) +- self.ready_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR) ++ self.window = self.xml.get_object("mainWindow").get_root_window() ++ self.busy_cursor = Gdk.Cursor.new(Gdk.CursorType.WATCH) ++ self.ready_cursor = Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR) + + self.local = False +- self.view = xml.get_widget("%sView" % name) +- self.dialog = xml.get_widget("%sDialog" % name) +- self.filter_entry = xml.get_widget("%sFilterEntry" % name) ++ self.view = xml.get_object("%sView" % name) ++ self.dialog = xml.get_object("%sDialog" % name) ++ self.filter_entry = xml.get_object("%sFilterEntry" % name) + self.filter_entry.connect("focus_out_event", self.filter_changed) + self.filter_entry.connect("activate", self.filter_changed) ++ self.filter_entry.connect("changed", self.filter_changed) + + self.view.connect("row_activated", self.rowActivated) + self.view.get_selection().connect("changed", self.itemSelected) +@@ -81,7 +77,7 @@ class semanagePage: + def get_description(self): + return self.description + +- def itemSelected(self, args): ++ def itemSelected(self, selection): + return + + def filter_changed(self, *arg): +@@ -110,28 +106,28 @@ class semanagePage: + self.propertiesDialog() + + def verify(self, message, title=""): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, +- gtk.BUTTONS_YES_NO, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO, ++ Gtk.ButtonsType.YES_NO, + message) + dlg.set_title(title) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + rc = dlg.run() + dlg.destroy() + return rc + + def error(self, message): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, +- gtk.BUTTONS_CLOSE, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR, ++ Gtk.ButtonsType.CLOSE, + message) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + dlg.run() + dlg.destroy() + + def deleteDialog(self): + store, it = self.view.get_selection().get_selected() +- if (it is not None) and (self.verify(_("Are you sure you want to delete %s '%s'?" % (self.description, store.get_value(it, 0))), _("Delete %s" % self.description)) == gtk.RESPONSE_YES): ++ if (it is not None) and (self.verify(_("Are you sure you want to delete %s '%s'?" % (self.description, store.get_value(it, 0))), _("Delete %s" % self.description)) == Gtk.ResponseType.YES): + self.delete() + + def use_menus(self): +@@ -140,11 +136,11 @@ class semanagePage: + def addDialog(self): + self.dialogClear() + self.dialog.set_title(_("Add %s" % self.description)) +- self.dialog.set_position(gtk.WIN_POS_MOUSE) ++ self.dialog.set_position(Gtk.WindowPosition.MOUSE) + +- while self.dialog.run() == gtk.RESPONSE_OK: ++ while self.dialog.run() == Gtk.ResponseType.OK: + try: +- if self.add() == False: ++ if not self.add(): + continue + break + except ValueError as e: +@@ -154,10 +150,10 @@ class semanagePage: + def propertiesDialog(self): + self.dialogInit() + self.dialog.set_title(_("Modify %s" % self.description)) +- self.dialog.set_position(gtk.WIN_POS_MOUSE) +- while self.dialog.run() == gtk.RESPONSE_OK: ++ self.dialog.set_position(Gtk.WindowPosition.MOUSE) ++ while self.dialog.run() == Gtk.ResponseType.OK: + try: +- if self.modify() == False: ++ if not self.modify(): + continue + break + except ValueError as e: +diff --git selinux-gui-2.7/statusPage.py selinux-gui-2.7/statusPage.py +index 23d0d0f..766854b 100644 +--- selinux-gui-2.7/statusPage.py ++++ selinux-gui-2.7/statusPage.py +@@ -16,23 +16,14 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade + import os +-import gobject + import sys +-import tempfile ++from gi.repository import Gtk + import selinux + + INSTALLPATH = '/usr/share/system-config-selinux' + sys.path.append(INSTALLPATH) + +-try: +- from subprocess import getstatusoutput +-except ImportError: +- from commands import getstatusoutput +- + ENFORCING = 1 + PERMISSIVE = 0 + DISABLED = -1 +@@ -71,12 +62,11 @@ class statusPage: + + self.type = selinux.selinux_getpolicytype() + # Bring in widgets from glade file. +- self.typeHBox = xml.get_widget("typeHBox") +- self.selinuxTypeOptionMenu = xml.get_widget("selinuxTypeOptionMenu") +- self.typeLabel = xml.get_widget("typeLabel") +- self.enabledOptionMenu = xml.get_widget("enabledOptionMenu") +- self.currentOptionMenu = xml.get_widget("currentOptionMenu") +- self.relabel_checkbutton = xml.get_widget("relabelCheckbutton") ++ self.selinuxTypeOptionMenu = xml.get_object("selinuxTypeOptionMenu") ++ self.typeLabel = xml.get_object("typeLabel") ++ self.enabledOptionMenu = xml.get_object("enabledOptionMenu") ++ self.currentOptionMenu = xml.get_object("currentOptionMenu") ++ self.relabel_checkbutton = xml.get_object("relabelCheckbutton") + self.relabel_checkbutton.set_active(self.is_relabel()) + self.relabel_checkbutton.connect("toggled", self.on_relabel_toggle) + if self.get_current_mode() == ENFORCING or self.get_current_mode() == PERMISSIVE: +@@ -90,7 +80,7 @@ class statusPage: + self.currentOptionMenu.set_active(0) + self.currentOptionMenu.set_sensitive(False) + +- if self.read_selinux_config() == None: ++ if self.read_selinux_config() is None: + self.selinuxsupport = False + else: + self.enabledOptionMenu.connect("changed", self.enabled_changed) +@@ -131,10 +121,10 @@ class statusPage: + os.unlink(RELABELFILE) + + def verify(self, message): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, +- gtk.BUTTONS_YES_NO, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO, ++ Gtk.ButtonsType.YES_NO, + message) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + rc = dlg.run() + dlg.destroy() +@@ -144,7 +134,7 @@ class statusPage: + type = self.get_type() + enabled = self.enabledOptionMenu.get_active() + if self.initialtype != type: +- if self.verify(_("Changing the policy type will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == gtk.RESPONSE_NO: ++ if self.verify(_("Changing the policy type will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == Gtk.ResponseType.NO: + menu.set_active(self.typeHistory) + return None + +@@ -158,12 +148,12 @@ class statusPage: + type = self.get_type() + + if self.initEnabled != DISABLED and enabled == DISABLED: +- if self.verify(_("Changing to SELinux disabled requires a reboot. It is not recommended. If you later decide to turn SELinux back on, the system will be required to relabel. If you just want to see if SELinux is causing a problem on your system, you can go to permissive mode which will only log errors and not enforce SELinux policy. Permissive mode does not require a reboot Do you wish to continue?")) == gtk.RESPONSE_NO: ++ if self.verify(_("Changing to SELinux disabled requires a reboot. It is not recommended. If you later decide to turn SELinux back on, the system will be required to relabel. If you just want to see if SELinux is causing a problem on your system, you can go to permissive mode which will only log errors and not enforce SELinux policy. Permissive mode does not require a reboot Do you wish to continue?")) == Gtk.ResponseType.NO: + combo.set_active(self.enabled) + return None + + if self.initEnabled == DISABLED and enabled < 2: +- if self.verify(_("Changing to SELinux enabled will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == gtk.RESPONSE_NO: ++ if self.verify(_("Changing to SELinux enabled will cause a relabel of the entire file system on the next boot. Relabeling takes a long time depending on the size of the file system. Do you wish to continue?")) == Gtk.ResponseType.NO: + combo.set_active(self.enabled) + return None + self.relabel_checkbutton.set_active(True) +diff --git selinux-gui-2.7/system-config-selinux.py selinux-gui-2.7/system-config-selinux.py +index ed41e98..ce7c74b 100644 +--- selinux-gui-2.7/system-config-selinux.py ++++ selinux-gui-2.7/system-config-selinux.py +@@ -20,20 +20,19 @@ + # along with this program; if not, write to the Free Software + # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + # ++import os + import signal +-import string + import sys ++import gi ++gi.require_version('Gtk', '3.0') + try: +- import gtk ++ from gi.repository import Gtk + except RuntimeError as e: + print("system-config-selinux:", e) + print("This is a graphical application and requires DISPLAY to be set.") + sys.exit(1) + +-import gtk.glade +-import os +-import gobject +-import gnome ++from gi.repository import GObject + import statusPage + import booleansPage + import loginsPage +@@ -64,8 +63,6 @@ except: + import __builtin__ + __builtin__.__dict__['_'] = unicode + +-gnome.program_init("SELinux Management Tool", "5") +- + version = "1.0" + + sys.path.append('/usr/share/system-config-selinux') +@@ -74,10 +71,12 @@ sys.path.append('/usr/share/system-config-selinux') + ## + ## Pull in the Glade file + ## +-if os.access("system-config-selinux.glade", os.F_OK): +- xml = gtk.glade.XML("system-config-selinux.glade", domain=PROGNAME) ++xml = Gtk.Builder() ++xml.set_translation_domain(PROGNAME) ++if os.access("system-config-selinux.ui", os.F_OK): ++ xml.add_from_file("system-config-selinux.ui") + else: +- xml = gtk.glade.XML("/usr/share/system-config-selinux/system-config-selinux.glade", domain=PROGNAME) ++ xml.add_from_file("/usr/share/system-config-selinux/system-config-selinux.ui") + + + class childWindow: +@@ -85,11 +84,16 @@ class childWindow: + def __init__(self): + self.tabs = [] + self.xml = xml +- xml.signal_connect("on_quit_activate", self.destroy) +- xml.signal_connect("on_delete_clicked", self.delete) +- xml.signal_connect("on_add_clicked", self.add) +- xml.signal_connect("on_properties_clicked", self.properties) +- xml.signal_connect("on_local_clicked", self.on_local_clicked) ++ xml.connect_signals({ ++ "on_quit_activate": self.destroy, ++ "on_delete_clicked": self.delete, ++ "on_add_clicked": self.add, ++ "on_properties_clicked": self.properties, ++ "on_local_clicked": self.on_local_clicked, ++ "on_policy_activate": self.policy, ++ "on_logging_activate": self.logging, ++ "on_about_activate": self.on_about_activate, ++ }) + self.add_page(statusPage.statusPage(xml)) + if selinux.is_selinux_enabled() > 0: + try: +@@ -103,20 +107,15 @@ class childWindow: + except ValueError as e: + self.error(e.message) + +- xml.signal_connect("on_quit_activate", self.destroy) +- xml.signal_connect("on_policy_activate", self.policy) +- xml.signal_connect("on_logging_activate", self.logging) +- xml.signal_connect("on_about_activate", self.on_about_activate) +- +- self.add_menu = xml.get_widget("add_menu_item") +- self.properties_menu = xml.get_widget("properties_menu_item") +- self.delete_menu = xml.get_widget("delete_menu_item") ++ self.add_menu = xml.get_object("add_menu_item") ++ self.properties_menu = xml.get_object("properties_menu_item") ++ self.delete_menu = xml.get_object("delete_menu_item") + + def error(self, message): +- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, +- gtk.BUTTONS_CLOSE, ++ dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR, ++ Gtk.ButtonsType.CLOSE, + message) +- dlg.set_position(gtk.WIN_POS_MOUSE) ++ dlg.set_position(Gtk.WindowPosition.MOUSE) + dlg.show_all() + dlg.run() + dlg.destroy() +@@ -143,12 +142,12 @@ class childWindow: + self.tabs[self.notebook.get_current_page()].on_local_clicked(button) + + def on_about_activate(self, args): +- dlg = xml.get_widget("aboutWindow") ++ dlg = xml.get_object("aboutWindow") + dlg.run() + dlg.hide() + + def destroy(self, args): +- gtk.main_quit() ++ Gtk.main_quit() + + def use_menus(self, use_menus): + self.add_menu.set_sensitive(use_menus) +@@ -166,13 +165,13 @@ class childWindow: + + def setupScreen(self): + # Bring in widgets from glade file. +- self.mainWindow = self.xml.get_widget("mainWindow") +- self.notebook = self.xml.get_widget("notebook") +- self.view = self.xml.get_widget("selectView") ++ self.mainWindow = self.xml.get_object("mainWindow") ++ self.notebook = self.xml.get_object("notebook") ++ self.view = self.xml.get_object("selectView") + self.view.get_selection().connect("changed", self.itemSelected) +- self.store = gtk.ListStore(gobject.TYPE_STRING) ++ self.store = Gtk.ListStore(GObject.TYPE_STRING) + self.view.set_model(self.store) +- col = gtk.TreeViewColumn("", gtk.CellRendererText(), text=0) ++ col = Gtk.TreeViewColumn("", Gtk.CellRendererText(), text=0) + col.set_resizable(True) + self.view.append_column(col) + +@@ -189,7 +188,7 @@ class childWindow: + self.mainWindow.connect("destroy", self.destroy) + + self.mainWindow.show_all() +- gtk.main() ++ Gtk.main() + + if __name__ == "__main__": + signal.signal(signal.SIGINT, signal.SIG_DFL) +diff --git selinux-gui-2.7/system-config-selinux.ui selinux-gui-2.7/system-config-selinux.ui +new file mode 100644 +index 0000000..7cc1cc5 +--- /dev/null ++++ selinux-gui-2.7/system-config-selinux.ui +@@ -0,0 +1,2024 @@ ++ ++ ++ ++ ++ ++ ++ system-config-selinux ++ False ++ 5 ++ normal ++ Copyright (c)2006 Red Hat, Inc. ++Copyright (c) 2006 Dan Walsh <dwalsh@redhat.com> ++ Daniel Walsh <dwalsh@redhat.com> ++ ++ translator-credits ++ system-config-selinux.png ++ ++ ++ False ++ ++ ++ False ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ False ++ gtk-add ++ ++ ++ True ++ False ++ gtk-properties ++ ++ ++ True ++ False ++ gtk-delete ++ ++ ++ False ++ Add SELinux Login Mapping ++ dialog ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ end ++ ++ ++ gtk-cancel ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 0 ++ ++ ++ ++ ++ gtk-ok ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ end ++ 0 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ 4 ++ 6 ++ ++ ++ True ++ False ++ Login Name ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ SELinux User ++ ++ ++ 0 ++ 1 ++ ++ ++ ++ ++ True ++ False ++ MLS/MCS Range ++ ++ ++ 0 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ 1 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ 5 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ ++ cancelbutton1 ++ okbutton1 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ tcp ++ ++ ++ udp ++ ++ ++ ++ ++ False ++ Add SELinux Network Ports ++ dialog ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ end ++ ++ ++ gtk-cancel ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 0 ++ ++ ++ ++ ++ gtk-ok ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ end ++ 0 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ 4 ++ 6 ++ ++ ++ True ++ False ++ Port Number ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ Protocol ++ ++ ++ 0 ++ 1 ++ ++ ++ ++ ++ True ++ False ++ SELinux Type ++ ++ ++ 0 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ model1 ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ 1 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ True ++ False ++ MLS/MCS ++Level ++ ++ ++ 0 ++ 3 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 3 ++ ++ ++ ++ ++ True ++ True ++ 5 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ ++ button1 ++ button2 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ all files ++ ++ ++ regular file ++ ++ ++ directory ++ ++ ++ character device ++ ++ ++ block device ++ ++ ++ socket file ++ ++ ++ symbolic link ++ ++ ++ named pipe ++ ++ ++ ++ ++ False ++ Add SELinux Login Mapping ++ dialog ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ end ++ ++ ++ gtk-cancel ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 0 ++ ++ ++ ++ ++ gtk-ok ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ end ++ 0 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ 4 ++ 6 ++ ++ ++ True ++ False ++ File Specification ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ File Type ++ ++ ++ 0 ++ 1 ++ ++ ++ ++ ++ True ++ False ++ SELinux Type ++ ++ ++ 0 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ model2 ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ 1 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ True ++ False ++ MLS ++ ++ ++ 0 ++ 3 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 3 ++ ++ ++ ++ ++ True ++ True ++ 5 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ ++ button5 ++ button6 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Disabled ++ ++ ++ Permissive ++ ++ ++ Enforcing ++ ++ ++ ++ ++ False ++ SELinux Administration ++ 800 ++ 500 ++ system-config-selinux.png ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ _File ++ True ++ ++ ++ True ++ False ++ ++ ++ _Add ++ True ++ False ++ True ++ image13 ++ False ++ ++ ++ ++ ++ ++ ++ _Properties ++ True ++ False ++ True ++ image14 ++ False ++ ++ ++ ++ ++ ++ ++ _Delete ++ True ++ False ++ True ++ image15 ++ False ++ ++ ++ ++ ++ ++ gtk-quit ++ True ++ False ++ True ++ True ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ False ++ _Help ++ True ++ ++ ++ True ++ False ++ ++ ++ gtk-about ++ True ++ False ++ True ++ True ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ False ++ True ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ True ++ False ++ 5 ++ 0 ++ none ++ ++ ++ True ++ False ++ 12 ++ ++ ++ True ++ True ++ Select Management Object ++ False ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ False ++ <b>Select:</b> ++ True ++ ++ ++ ++ ++ True ++ False ++ ++ ++ ++ ++ True ++ False ++ False ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ 5 ++ 5 ++ ++ ++ True ++ False ++ System Default Enforcing Mode ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ True ++ model3 ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ 1 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ Current Enforcing Mode ++ ++ ++ 0 ++ 1 ++ ++ ++ ++ ++ True ++ False ++ True ++ ++ ++ 1 ++ 1 ++ ++ ++ ++ ++ True ++ False ++ System Default Policy Type: ++ ++ ++ 0 ++ 2 ++ ++ ++ ++ ++ True ++ False ++ True ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ False ++ Select if you wish to relabel then entire file system on next reboot. Relabeling can take a very long time, depending on the size of the system. If you are changing policy types or going from disabled to enforcing, a relabel is required. ++ False ++ True ++ ++ ++ True ++ False ++ True ++ 0 ++ 0 ++ ++ ++ True ++ False ++ True ++ 2 ++ ++ ++ True ++ False ++ gtk-refresh ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ Relabel on next reboot. ++ True ++ ++ ++ False ++ False ++ 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ 0 ++ 3 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ end ++ 0 ++ ++ ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Revert boolean setting to system default ++ gtk-revert-to-saved ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Toggle between Customized and All Booleans ++ Customized ++ True ++ gtk-find ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ 10 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ Boolean ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 1 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Add File Context ++ gtk-add ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Modify File Context ++ gtk-properties ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Delete File Context ++ gtk-delete ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Toggle between all and customized file context ++ Customized ++ True ++ gtk-find ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ False ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ File Labeling ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 2 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Add SELinux User Mapping ++ gtk-add ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Modify SELinux User Mapping ++ gtk-properties ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Delete SELinux User Mapping ++ gtk-delete ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ 5 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ User Mapping ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 3 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Add User ++ gtk-add ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Modify User ++ gtk-properties ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Delete User ++ gtk-delete ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ 5 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ SELinux User ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 4 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Add Network Port ++ gtk-add ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Edit Network Port ++ gtk-properties ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Delete Network Port ++ gtk-delete ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ ++ ++ 32 ++ True ++ False ++ vertical ++ ++ ++ ++ ++ False ++ False ++ ++ ++ ++ ++ True ++ False ++ Toggle between Customized and All Ports ++ Group View ++ True ++ gtk-indent ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Toggle between Customized and All Ports ++ Customized ++ True ++ gtk-find ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ 5 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ Network Port ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 5 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Generate new policy module ++ gtk-new ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Load policy module ++ gtk-add ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Remove loadable policy module ++ gtk-remove ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ ++ ++ 10 ++ True ++ False ++ vertical ++ ++ ++ ++ ++ False ++ False ++ ++ ++ ++ ++ True ++ False ++ Enable/Disable additional audit rules, that are normally not reported in the log files. ++ Enable Audit ++ True ++ gtk-zoom-in ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ 5 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ Policy Module ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 6 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ both ++ ++ ++ True ++ False ++ Change process mode to permissive. ++ Permissive ++ True ++ gtk-dialog-warning ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ Change process mode to enforcing ++ Enforcing ++ True ++ gtk-dialog-error ++ ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ False ++ 0 ++ ++ ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ Filter ++ ++ ++ False ++ False ++ 10 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ 5 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ always ++ always ++ ++ ++ True ++ True ++ Process Domain ++ ++ ++ ++ ++ ++ ++ ++ True ++ True ++ 2 ++ ++ ++ ++ ++ 7 ++ ++ ++ ++ ++ True ++ True ++ ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ False ++ Add SELinux User ++ dialog ++ ++ ++ True ++ False ++ ++ ++ True ++ False ++ end ++ ++ ++ gtk-cancel ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 0 ++ ++ ++ ++ ++ gtk-ok ++ True ++ True ++ True ++ False ++ True ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ False ++ True ++ end ++ 0 ++ ++ ++ ++ ++ True ++ False ++ vertical ++ ++ ++ True ++ False ++ 4 ++ 6 ++ ++ ++ True ++ False ++ SELinux User ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ MLS/MCS Range ++ ++ ++ 0 ++ 1 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 1 ++ ++ ++ ++ ++ True ++ False ++ SELinux Roles ++ ++ ++ 0 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ True ++ True ++ * ++ ++ ++ 1 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ 5 ++ 0 ++ ++ ++ ++ ++ True ++ True ++ 1 ++ ++ ++ ++ ++ ++ button7 ++ button8 ++ ++ ++ ++ ++ ++ +diff --git selinux-gui-2.7/usersPage.py selinux-gui-2.7/usersPage.py +index 75b0547..26794ed 100644 +--- selinux-gui-2.7/usersPage.py ++++ selinux-gui-2.7/usersPage.py +@@ -16,17 +16,13 @@ + ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + ## Author: Dan Walsh +-import string +-import gtk +-import gtk.glade +-import os +-import gobject + import sys + try: + from subprocess import getstatusoutput + except ImportError: + from commands import getstatusoutput + ++from gi.repository import GObject, Gtk + import seobject + from semanagePage import * + +@@ -57,27 +53,27 @@ class usersPage(semanagePage): + def __init__(self, xml): + semanagePage.__init__(self, xml, "users", _("SELinux User")) + +- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) ++ self.store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_STRING) + self.view.set_model(self.store) +- self.store.set_sort_column_id(0, gtk.SORT_ASCENDING) ++ self.store.set_sort_column_id(0, Gtk.SortType.ASCENDING) + +- col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text=0) ++ col = Gtk.TreeViewColumn(_("SELinux\nUser"), Gtk.CellRendererText(), text=0) + col.set_sort_column_id(0) + col.set_resizable(True) + self.view.append_column(col) + +- col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text=1) ++ col = Gtk.TreeViewColumn(_("MLS/\nMCS Range"), Gtk.CellRendererText(), text=1) + col.set_resizable(True) + self.view.append_column(col) + +- col = gtk.TreeViewColumn(_("SELinux Roles"), gtk.CellRendererText(), text=2) ++ col = Gtk.TreeViewColumn(_("SELinux Roles"), Gtk.CellRendererText(), text=2) + col.set_resizable(True) + self.view.append_column(col) + + self.load() +- self.selinuxUserEntry = xml.get_widget("selinuxUserEntry") +- self.mlsRangeEntry = xml.get_widget("mlsRangeEntry") +- self.selinuxRolesEntry = xml.get_widget("selinuxRolesEntry") ++ self.selinuxUserEntry = xml.get_object("selinuxUserEntry") ++ self.mlsRangeEntry = xml.get_object("mlsRangeEntry") ++ self.selinuxRolesEntry = xml.get_object("selinuxRolesEntry") + + def load(self, filter=""): + self.filter = filter +@@ -95,10 +91,6 @@ class usersPage(semanagePage): + self.store.set_value(iter, 2, dict[k][3]) + self.view.get_selection().select_path((0,)) + +- def delete(self): +- if semanagePage.delete(self) == gtk.RESPONSE_NO: +- return None +- + def dialogInit(self): + store, iter = self.view.get_selection().get_selected() + self.selinuxUserEntry.set_text(store.get_value(iter, 0)) diff --git a/selinux-python-fedora.patch b/selinux-python-fedora.patch index f34a4f1..d450169 100644 --- a/selinux-python-fedora.patch +++ b/selinux-python-fedora.patch @@ -1,3 +1,270 @@ +diff --git selinux-python-2.7/semanage/semanage selinux-python-2.7/semanage/semanage +index 313537c..8d8a086 100644 +--- selinux-python-2.7/semanage/semanage ++++ selinux-python-2.7/semanage/semanage +@@ -89,16 +89,6 @@ class CheckRole(argparse.Action): + newval.append(v) + setattr(namespace, self.dest, newval) + +-store = '' +- +- +-class SetStore(argparse.Action): +- +- def __call__(self, parser, namespace, values, option_string=None): +- global store +- store = values +- setattr(namespace, self.dest, values) +- + + class seParser(argparse.ArgumentParser): + +@@ -134,67 +124,21 @@ class SetImportFile(argparse.Action): + sys.exit(1) + setattr(namespace, self.dest, values) + +-# functions for OBJECT initialization +- +- +-def login_ini(): +- OBJECT = seobject.loginRecords(store) +- return OBJECT +- +- +-def user_ini(): +- OBJECT = seobject.seluserRecords(store) +- return OBJECT +- +- +-def port_ini(): +- OBJECT = seobject.portRecords(store) +- return OBJECT +- +-def ibpkey_ini(): +- OBJECT = seobject.ibpkeyRecords(store) +- return OBJECT +- +-def ibendport_ini(): +- OBJECT = seobject.ibendportRecords(store) +- return OBJECT +- +-def module_ini(): +- OBJECT = seobject.moduleRecords(store) +- return OBJECT +- +- +-def interface_ini(): +- OBJECT = seobject.interfaceRecords(store) +- return OBJECT +- +- +-def node_ini(): +- OBJECT = seobject.nodeRecords(store) +- return OBJECT +- +- +-def fcontext_ini(): +- OBJECT = seobject.fcontextRecords(store) +- return OBJECT +- +- +-def boolean_ini(): +- OBJECT = seobject.booleanRecords(store) +- return OBJECT +- +- +-def permissive_ini(): +- OBJECT = seobject.permissiveRecords(store) +- return OBJECT +- +- +-def dontaudit_ini(): +- OBJECT = seobject.dontauditClass(store) +- return OBJECT +- + # define dictonary for seobject OBEJCTS +-object_dict = {'login': login_ini, 'user': user_ini, 'port': port_ini, 'module': module_ini, 'interface': interface_ini, 'node': node_ini, 'fcontext': fcontext_ini, 'boolean': boolean_ini, 'permissive': permissive_ini, 'dontaudit': dontaudit_ini, 'ibpkey': ibpkey_ini, 'ibendport': ibendport_ini} ++object_dict = { ++ 'login': seobject.loginRecords, ++ 'user': seobject.seluserRecords, ++ 'port': seobject.portRecords, ++ 'module': seobject.moduleRecords, ++ 'interface': seobject.interfaceRecords, ++ 'node': seobject.nodeRecords, ++ 'fcontext': seobject.fcontextRecords, ++ 'boolean': seobject.booleanRecords, ++ 'permissive': seobject.permissiveRecords, ++ 'dontaudit': seobject.dontauditClass, ++ 'ibpkey': seobject.ibpkeyRecords, ++ 'ibendport': seobject.ibendportRecords ++} + + def generate_custom_usage(usage_text, usage_dict): + # generate custom usage from given text and dictonary +@@ -238,8 +182,7 @@ def handleLogin(args): + + handle_opts(args, login_args, args.action) + +- OBJECT = object_dict['login']() +- OBJECT.set_reload(args.noreload) ++ OBJECT = object_dict['login'](args) + + if args.action is "add": + OBJECT.add(args.login, args.seuser, args.range) +@@ -257,7 +200,7 @@ def handleLogin(args): + + + def parser_add_store(parser, name): +- parser.add_argument('-S', '--store', action=SetStore, help=_("Select an alternate SELinux Policy Store to manage")) ++ parser.add_argument('-S', '--store', default='', help=_("Select an alternate SELinux Policy Store to manage")) + + + def parser_add_priority(parser, name): +@@ -269,7 +212,7 @@ def parser_add_noheading(parser, name): + + + def parser_add_noreload(parser, name): +- parser.add_argument('-N', '--noreload', action='store_false', default=True, help=_('Do not reload policy after commit')) ++ parser.add_argument('-N', '--noreload', action='store_true', default=False, help=_('Do not reload policy after commit')) + + + def parser_add_locallist(parser, name): +@@ -372,8 +315,7 @@ def handleFcontext(args): + else: + handle_opts(args, fcontext_args, args.action) + +- OBJECT = object_dict['fcontext']() +- OBJECT.set_reload(args.noreload) ++ OBJECT = object_dict['fcontext'](args) + + if args.action is "add": + if args.equal: +@@ -441,8 +383,7 @@ def handleUser(args): + + handle_opts(args, user_args, args.action) + +- OBJECT = object_dict['user']() +- OBJECT.set_reload(args.noreload) ++ OBJECT = object_dict['user'](args) + + if args.action is "add": + OBJECT.add(args.selinux_name, args.roles, args.level, args.range, args.prefix) +@@ -492,8 +433,7 @@ def handlePort(args): + + handle_opts(args, port_args, args.action) + +- OBJECT = object_dict['port']() +- OBJECT.set_reload(args.noreload) ++ OBJECT = object_dict['port'](args) + + if args.action is "add": + OBJECT.add(args.port, args.proto, args.range, args.type) +@@ -538,8 +478,7 @@ def handlePkey(args): + + handle_opts(args, ibpkey_args, args.action) + +- OBJECT = object_dict['ibpkey']() +- OBJECT.set_reload(args.noreload) ++ OBJECT = object_dict['ibpkey'](args) + + if args.action is "add": + OBJECT.add(args.ibpkey, args.subnet_prefix, args.range, args.type) +@@ -582,8 +521,7 @@ def handleIbendport(args): + + handle_opts(args, ibendport_args, args.action) + +- OBJECT = object_dict['ibendport']() +- OBJECT.set_reload(args.noreload) ++ OBJECT = object_dict['ibendport'](args) + + if args.action is "add": + OBJECT.add(args.ibendport, args.ibdev_name, args.range, args.type) +@@ -626,8 +564,7 @@ def handleInterface(args): + + handle_opts(args, interface_args, args.action) + +- OBJECT = object_dict['interface']() +- OBJECT.set_reload(args.noreload) ++ OBJECT = object_dict['interface'](args) + + if args.action is "add": + OBJECT.add(args.interface, args.range, args.type) +@@ -666,8 +603,7 @@ def setupInterfaceParser(subparsers): + + + def handleModule(args): +- OBJECT = seobject.moduleRecords(store) +- OBJECT.set_reload(args.noreload) ++ OBJECT = seobject.moduleRecords(args) + if args.action == "add": + OBJECT.add(args.module_name, args.priority) + if args.action == "enable": +@@ -709,8 +645,7 @@ def handleNode(args): + node_args = {'list': [('node', 'type', 'proto', 'netmask'), ('')], 'add': [('locallist'), ('type', 'node', 'proto', 'netmask')], 'modify': [('locallist'), ('node', 'netmask', 'proto')], 'delete': [('locallist'), ('node', 'netmask', 'prototype')], 'extract': [('locallist', 'node', 'type', 'proto', 'netmask'), ('')], 'deleteall': [('locallist'), ('')]} + handle_opts(args, node_args, args.action) + +- OBJECT = object_dict['node']() +- OBJECT.set_reload(args.noreload) ++ OBJECT = object_dict['node'](args) + + if args.action is "add": + OBJECT.add(args.node, args.netmask, args.proto, args.range, args.type) +@@ -756,8 +691,7 @@ def handleBoolean(args): + + handle_opts(args, boolean_args, args.action) + +- OBJECT = object_dict['boolean']() +- OBJECT.set_reload(args.noreload) ++ OBJECT = object_dict['boolean'](args) + + if args.action is "modify": + if args.boolean: +@@ -795,8 +729,7 @@ def setupBooleanParser(subparsers): + + + def handlePermissive(args): +- OBJECT = object_dict['permissive']() +- OBJECT.set_reload(args.noreload) ++ OBJECT = object_dict['permissive'](args) + + if args.action is "list": + OBJECT.list(args.noheading) +@@ -830,8 +763,7 @@ def setupPermissiveParser(subparsers): + + + def handleDontaudit(args): +- OBJECT = object_dict['dontaudit']() +- OBJECT.set_reload(args.noreload) ++ OBJECT = object_dict['dontaudit'](args) + OBJECT.toggle(args.action) + + +@@ -848,7 +780,7 @@ def handleExport(args): + for i in manageditems: + print("%s -D" % i) + for i in manageditems: +- OBJECT = object_dict[i]() ++ OBJECT = object_dict[i](args) + for c in OBJECT.customized(): + print("%s %s" % (i, str(c))) + +@@ -912,7 +844,7 @@ def mkargv(line): + + + def handleImport(args): +- trans = seobject.semanageRecords(store) ++ trans = seobject.semanageRecords(args) + trans.start() + + for l in sys.stdin.readlines(): +@@ -932,7 +864,6 @@ def handleImport(args): + except KeyboardInterrupt: + sys.exit(0) + +- trans.set_reload(args.noreload) + trans.finish() + + 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 @@ -15,10 +282,67 @@ index 0bdb90f..0cdcfcc 100644 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..af88126 100644 +index 70fd192..99e1cd8 100644 --- selinux-python-2.7/semanage/seobject.py +++ selinux-python-2.7/semanage/seobject.py -@@ -386,6 +386,8 @@ class moduleRecords(semanageRecords): +@@ -238,21 +238,28 @@ class semanageRecords: + transaction = False + handle = None + store = None ++ args = None + +- def __init__(self, store): ++ def __init__(self, args = None): + global handle +- self.load = True +- self.sh = self.get_handle(store) ++ if args: ++ # legacy code - args was store originally ++ if type(args) == str: ++ self.store = args ++ else: ++ self.args = args ++ self.noreload = getattr(args, "noreload", False) ++ if not self.store: ++ self.store = getattr(args, "store", "") ++ ++ self.sh = self.get_handle(self.store) + + rc, localstore = selinux.selinux_getpolicytype() +- if store == "" or store == localstore: ++ if self.store == "" or self.store == localstore: + self.mylog = logger() + else: + self.mylog = nulllogger() + +- def set_reload(self, load): +- self.load = load +- + def get_handle(self, store): + global is_mls_enabled + +@@ -312,7 +319,8 @@ class semanageRecords: + if semanageRecords.transaction: + return + +- semanage_set_reload(self.sh, self.load) ++ if self.noreload: ++ semanage_set_reload(self.sh, 0) + rc = semanage_commit(self.sh) + if rc < 0: + self.mylog.commit(0) +@@ -328,8 +336,8 @@ class semanageRecords: + + class moduleRecords(semanageRecords): + +- def __init__(self, store): +- semanageRecords.__init__(self, store) ++ def __init__(self, args = None): ++ semanageRecords.__init__(self, args) + + def get_all(self): + l = [] +@@ -386,6 +394,8 @@ class moduleRecords(semanageRecords): print("%-25s %-9s %-5s %s" % (t[0], t[2], t[3], disabled)) def add(self, file, priority): @@ -27,7 +351,7 @@ index 70fd192..af88126 100644 if not os.path.exists(file): raise ValueError(_("Module does not exist: %s ") % file) -@@ -398,6 +400,8 @@ class moduleRecords(semanageRecords): +@@ -398,6 +408,8 @@ class moduleRecords(semanageRecords): self.commit() def set_enabled(self, module, enable): @@ -36,7 +360,7 @@ index 70fd192..af88126 100644 for m in module.split(): rc, key = semanage_module_key_create(self.sh) if rc < 0: -@@ -416,11 +420,15 @@ class moduleRecords(semanageRecords): +@@ -416,11 +428,15 @@ class moduleRecords(semanageRecords): self.commit() def modify(self, file): @@ -52,11 +376,372 @@ index 70fd192..af88126 100644 rc = semanage_set_default_priority(self.sh, priority) if rc < 0: raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority) +@@ -440,8 +456,8 @@ class moduleRecords(semanageRecords): + + class dontauditClass(semanageRecords): + +- def __init__(self, store): +- semanageRecords.__init__(self, store) ++ def __init__(self, args = None): ++ semanageRecords.__init__(self, args) + + def toggle(self, dontaudit): + if dontaudit not in ["on", "off"]: +@@ -453,8 +469,8 @@ class dontauditClass(semanageRecords): + + class permissiveRecords(semanageRecords): + +- def __init__(self, store): +- semanageRecords.__init__(self, store) ++ def __init__(self, args = None): ++ semanageRecords.__init__(self, args) + + def get_all(self): + l = [] +@@ -522,8 +538,8 @@ class permissiveRecords(semanageRecords): + + class loginRecords(semanageRecords): + +- def __init__(self, store=""): +- semanageRecords.__init__(self, store) ++ def __init__(self, args = None): ++ semanageRecords.__init__(self, args) + self.oldsename = None + self.oldserange = None + self.sename = None +@@ -534,7 +550,7 @@ class loginRecords(semanageRecords): + if sename == "": + sename = "user_u" + +- userrec = seluserRecords() ++ userrec = seluserRecords(self.args) + range, (rc, oldserole) = userrec.get(self.oldsename) + range, (rc, serole) = userrec.get(sename) + +@@ -603,7 +619,7 @@ class loginRecords(semanageRecords): + if sename == "" and serange == "": + raise ValueError(_("Requires seuser or serange")) + +- userrec = seluserRecords() ++ userrec = seluserRecords(self.args) + range, (rc, oldserole) = userrec.get(self.oldsename) + + if sename != "": +@@ -660,7 +676,7 @@ class loginRecords(semanageRecords): + + def __delete(self, name): + rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) +- userrec = seluserRecords() ++ userrec = seluserRecords(self.args) + range, (rc, oldserole) = userrec.get(self.oldsename) + + (rc, k) = semanage_seuser_key_create(self.sh, name) +@@ -779,8 +795,8 @@ class loginRecords(semanageRecords): + + class seluserRecords(semanageRecords): + +- def __init__(self, store=""): +- semanageRecords.__init__(self, store) ++ def __init__(self, args = None): ++ semanageRecords.__init__(self, args) + + def get(self, name): + (rc, k) = semanage_user_key_create(self.sh, name) +@@ -1042,8 +1058,8 @@ class portRecords(semanageRecords): + except RuntimeError: + valid_types = [] + +- def __init__(self, store=""): +- semanageRecords.__init__(self, store) ++ def __init__(self, args = None): ++ semanageRecords.__init__(self, args) + + def __genkey(self, port, proto): + if proto == "tcp": +@@ -1317,8 +1333,8 @@ class ibpkeyRecords(semanageRecords): + except: + valid_types = [] + +- def __init__(self, store=""): +- semanageRecords.__init__(self, store) ++ def __init__(self, args = None): ++ semanageRecords.__init__(self, args) + + def __genkey(self, pkey, subnet_prefix): + if subnet_prefix == "": +@@ -1540,9 +1556,8 @@ class ibpkeyRecords(semanageRecords): + def customized(self): + l = [] + ddict = self.get_all(True) +- keys = ddict.keys() +- keys.sort() +- for k in keys: ++ ++ for k in sorted(ddict.keys()): + if k[0] == k[1]: + l.append("-a -t %s -x %s %s" % (ddict[k][0], k[2], k[0])) + else: +@@ -1554,11 +1569,10 @@ class ibpkeyRecords(semanageRecords): + keys = ddict.keys() + if len(keys) == 0: + return +- keys.sort() + + if heading: + print("%-30s %-18s %s\n" % (_("SELinux IB Pkey Type"), _("Subnet_Prefix"), _("Pkey Number"))) +- for i in keys: ++ for i in sorted(keys): + rec = "%-30s %-18s " % i + rec += "%s" % ddict[i][0] + for p in ddict[i][1:]: +@@ -1572,8 +1586,8 @@ class ibendportRecords(semanageRecords): + except: + valid_types = [] + +- def __init__(self, store=""): +- semanageRecords.__init__(self, store) ++ def __init__(self, args = None): ++ semanageRecords.__init__(self, args) + + def __genkey(self, ibendport, ibdev_name): + if ibdev_name == "": +@@ -1782,10 +1796,9 @@ class ibendportRecords(semanageRecords): + def customized(self): + l = [] + ddict = self.get_all(True) +- keys = ddict.keys() +- keys.sort() +- for k in keys: +- l.append("-a -t %s -x %s %s" % (ddict[k][0], k[2], k[0])) ++ ++ for k in sorted(ddict.keys()): ++ l.append("-a -t %s -r %s -z %s %s" % (ddict[k][0], ddict[k][1], k[1], k[0])) + return l + + def list(self, heading=1, locallist=0): +@@ -1793,11 +1806,10 @@ class ibendportRecords(semanageRecords): + keys = ddict.keys() + if len(keys) == 0: + return +- keys.sort() + + if heading: + print("%-30s %-18s %s\n" % (_("SELinux IB End Port Type"), _("IB Device Name"), _("Port Number"))) +- for i in keys: ++ for i in sorted(keys): + rec = "%-30s %-18s " % i + rec += "%s" % ddict[i][0] + for p in ddict[i][1:]: +@@ -1810,8 +1822,8 @@ class nodeRecords(semanageRecords): + except RuntimeError: + valid_types = [] + +- def __init__(self, store=""): +- semanageRecords.__init__(self, store) ++ def __init__(self, args = None): ++ semanageRecords.__init__(self, args) + self.protocol = ["ipv4", "ipv6"] + + def validate(self, addr, mask, protocol): +@@ -2046,8 +2058,8 @@ class nodeRecords(semanageRecords): + + class interfaceRecords(semanageRecords): + +- def __init__(self, store=""): +- semanageRecords.__init__(self, store) ++ def __init__(self, args = None): ++ semanageRecords.__init__(self, args) + + def __add(self, interface, serange, ctype): + if is_mls_enabled == 1: +@@ -2243,8 +2255,8 @@ class fcontextRecords(semanageRecords): + except RuntimeError: + valid_types = [] + +- def __init__(self, store=""): +- semanageRecords.__init__(self, store) ++ def __init__(self, args = None): ++ semanageRecords.__init__(self, args) + self.equiv = {} + self.equiv_dist = {} + self.equal_ind = False +@@ -2566,10 +2578,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 = {} +@@ -2627,8 +2644,8 @@ class fcontextRecords(semanageRecords): + + class booleanRecords(semanageRecords): + +- def __init__(self, store=""): +- semanageRecords.__init__(self, store) ++ def __init__(self, args = None): ++ semanageRecords.__init__(self, args) + self.dict = {} + self.dict["TRUE"] = 1 + self.dict["FALSE"] = 0 +diff --git selinux-python-2.7/sepolicy/sepolicy.8 selinux-python-2.7/sepolicy/sepolicy.8 +index 7900586..09d2b24 100644 +--- selinux-python-2.7/sepolicy/sepolicy.8 ++++ selinux-python-2.7/sepolicy/sepolicy.8 +@@ -22,14 +22,15 @@ Query SELinux policy to see if domains can communicate with each other + .br + + .B generate +-.br + .br + Generate SELinux Policy module template +-.B gui ++.B sepolicy-generate(8) + .br ++ ++.B gui + .br + Launch Graphical User Interface for SELinux Policy, requires policycoreutils-gui package. +-.B sepolicy-generate(8) ++.B sepolicy-gui(8) + .br + + .B interface diff --git selinux-python-2.7/sepolicy/sepolicy/__init__.py selinux-python-2.7/sepolicy/sepolicy/__init__.py -index 5cfc071..a10dbcd 100644 +index 5cfc071..24e3526 100644 --- selinux-python-2.7/sepolicy/sepolicy/__init__.py +++ selinux-python-2.7/sepolicy/sepolicy/__init__.py -@@ -1136,27 +1136,14 @@ def boolean_desc(boolean): +@@ -4,6 +4,7 @@ + # Author: Ryan Hallisey + # Author: Jason Zaman + ++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(): @@ -90,11 +775,124 @@ index 5cfc071..a10dbcd 100644 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..4772b50 100755 +index 4d84636..b463165 100755 --- selinux-python-2.7/sepolicy/sepolicy/manpage.py +++ selinux-python-2.7/sepolicy/sepolicy/manpage.py -@@ -125,8 +125,33 @@ def gen_domains(): +@@ -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 @@ -121,7 +919,10 @@ index 4d84636..4772b50 100755 +def _gen_mcs_constrained_types(): + global mcs_constrained_types + if mcs_constrained_types is None: -+ mcs_constrained_types = next(sepolicy.info(sepolicy.ATTRIBUTE, "mcs_constrained_type")) ++ try: ++ mcs_constrained_types = next(sepolicy.info(sepolicy.ATTRIBUTE, "mcs_constrained_type")) ++ except StopIteration: ++ mcs_constrained_types = [] + return mcs_constrained_types + + @@ -129,7 +930,7 @@ index 4d84636..4772b50 100755 def _gen_types(): global types -@@ -149,10 +174,6 @@ def prettyprint(f, trim): +@@ -149,10 +178,6 @@ def prettyprint(f, trim): manpage_domains = [] manpage_roles = [] @@ -140,7 +941,7 @@ index 4d84636..4772b50 100755 def get_alphabet_manpages(manpage_list): alphabet_manpages = dict.fromkeys(string.ascii_letters, []) for i in string.ascii_letters: -@@ -182,7 +203,7 @@ def convert_manpage_to_html(html_manpage, manpage): +@@ -182,7 +207,7 @@ def convert_manpage_to_html(html_manpage, manpage): class HTMLManPages: """ @@ -149,7 +950,7 @@ index 4d84636..4772b50 100755 """ def __init__(self, manpage_roles, manpage_domains, path, os_version): -@@ -190,9 +211,9 @@ class HTMLManPages: +@@ -190,9 +215,9 @@ class HTMLManPages: self.manpage_domains = get_alphabet_manpages(manpage_domains) self.os_version = os_version self.old_path = path + "/" @@ -161,7 +962,7 @@ index 4d84636..4772b50 100755 self.__gen_html_manpages() else: print("SELinux HTML man pages can not be generated for this %s" % os_version) -@@ -201,7 +222,6 @@ class HTMLManPages: +@@ -201,7 +226,6 @@ class HTMLManPages: def __gen_html_manpages(self): self._write_html_manpage() self._gen_index() @@ -169,7 +970,7 @@ index 4d84636..4772b50 100755 self._gen_css() def _write_html_manpage(self): -@@ -219,67 +239,21 @@ class HTMLManPages: +@@ -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): @@ -241,7 +1042,7 @@ index 4d84636..4772b50 100755 for letter in self.manpage_roles: if len(self.manpage_roles[letter]): fd.write(""" -@@ -423,6 +397,9 @@ class ManPage: +@@ -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() @@ -251,7 +1052,7 @@ index 4d84636..4772b50 100755 if self.source_files: self.fcpath = self.root + "file_contexts" -@@ -735,10 +712,13 @@ Default Defined Ports:""") +@@ -735,10 +716,13 @@ Default Defined Ports:""") def _file_context(self): flist = [] @@ -265,7 +1066,7 @@ index 4d84636..4772b50 100755 if f in self.fcdict: mpaths = mpaths + self.fcdict[f]["regex"] if len(mpaths) == 0: -@@ -790,19 +770,20 @@ SELinux %(domainname)s policy is very flexible allowing users to setup their %(d +@@ -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]}) @@ -289,7 +1090,17 @@ index 4d84636..4772b50 100755 self.fd.write(r""" .I The following file types are defined for %(domainname)s: -@@ -974,8 +955,7 @@ All executeables with the default executable label, usually stored in /usr/bin a +@@ -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):