• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#
2# booleansPage.py - GUI for Booleans page in system-config-securitylevel
3#
4# Dan Walsh <dwalsh@redhat.com>
5#
6# Copyright 2006, 2007 Red Hat, Inc.
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20#
21import string
22import gtk
23import gtk.glade
24import os
25import gobject
26import sys
27import tempfile
28import seobject
29import semanagePage
30
31INSTALLPATH = '/usr/share/system-config-selinux'
32sys.path.append(INSTALLPATH)
33
34import commands
35ENFORCING = 0
36PERMISSIVE = 1
37DISABLED = 2
38
39##
40## I18N
41##
42PROGNAME = "policycoreutils"
43
44import gettext
45gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
46gettext.textdomain(PROGNAME)
47try:
48    gettext.install(PROGNAME,
49                    localedir="/usr/share/locale",
50                    unicode=False,
51                    codeset='utf-8')
52except IOError:
53    import __builtin__
54    __builtin__.__dict__['_'] = unicode
55
56from glob import fnmatch
57
58
59class Modifier:
60
61    def __init__(self, name, on, save):
62        self.on = on
63        self.name = name
64        self.save = save
65
66    def set(self, value):
67        self.on = value
68        self.save = True
69
70    def isOn(self):
71        return self.on
72
73
74class Boolean(Modifier):
75
76    def __init__(self, name, val, save=False):
77        Modifier.__init__(self, name, val, save)
78
79ACTIVE = 0
80MODULE = 1
81DESC = 2
82BOOLEAN = 3
83
84
85class booleansPage:
86
87    def __init__(self, xml, doDebug=None):
88        self.xml = xml
89        self.window = self.xml.get_widget("mainWindow").get_root_window()
90        self.local = False
91        self.types = []
92        self.selinuxsupport = True
93        self.typechanged = False
94        self.doDebug = doDebug
95        self.busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
96        self.ready_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)
97
98        # Bring in widgets from glade file.
99        self.typeHBox = xml.get_widget("typeHBox")
100        self.booleanSW = xml.get_widget("booleanSW")
101        self.booleansFilter = xml.get_widget("booleansFilter")
102        self.booleansFilter.connect("focus_out_event", self.filter_changed)
103        self.booleansFilter.connect("activate", self.filter_changed)
104
105        self.booleansView = xml.get_widget("booleansView")
106        self.typeLabel = xml.get_widget("typeLabel")
107        self.modifySeparator = xml.get_widget("modifySeparator")
108
109        self.revertButton = xml.get_widget("booleanRevertButton")
110        self.revertButton.set_sensitive(self.local)
111        self.revertButton.connect("clicked", self.on_revert_clicked)
112        listStore = gtk.ListStore(gobject.TYPE_STRING)
113        cell = gtk.CellRendererText()
114
115        self.store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
116        self.store.set_sort_column_id(1, gtk.SORT_ASCENDING)
117        self.booleansView.set_model(self.store)
118
119        checkbox = gtk.CellRendererToggle()
120        checkbox.connect("toggled", self.boolean_toggled)
121        col = gtk.TreeViewColumn('Active', checkbox, active=ACTIVE)
122        col.set_clickable(True)
123        col.set_sort_column_id(ACTIVE)
124        self.booleansView.append_column(col)
125
126        col = gtk.TreeViewColumn("Module", gtk.CellRendererText(), text=MODULE)
127        col.set_sort_column_id(MODULE)
128        col.set_resizable(True)
129        self.booleansView.append_column(col)
130
131        col = gtk.TreeViewColumn("Description", gtk.CellRendererText(), text=DESC)
132        col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
133        col.set_fixed_width(400)
134        col.set_sort_column_id(DESC)
135        col.set_resizable(True)
136        self.booleansView.append_column(col)
137
138        col = gtk.TreeViewColumn("Name", gtk.CellRendererText(), text=BOOLEAN)
139        col.set_sort_column_id(BOOLEAN)
140        col.set_resizable(True)
141        self.booleansView.set_search_equal_func(self.__search)
142        self.booleansView.append_column(col)
143        self.filter = ""
144        self.load(self.filter)
145
146    def error(self, message):
147        dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR,
148                                gtk.BUTTONS_CLOSE,
149                                message)
150        dlg.set_position(gtk.WIN_POS_MOUSE)
151        dlg.show_all()
152        dlg.run()
153        dlg.destroy()
154
155    def __search(self, model, col, key, i):
156        sort_col = self.store.get_sort_column_id()[0]
157        if sort_col > 0:
158            val = model.get_value(i, sort_col)
159            if val.lower().startswith(key.lower()):
160                return False
161        return True
162
163    def wait(self):
164        self.window.set_cursor(self.busy_cursor)
165        semanagePage.idle_func()
166
167    def ready(self):
168        self.window.set_cursor(self.ready_cursor)
169        semanagePage.idle_func()
170
171    def deleteDialog(self):
172        store, iter = self.booleansView.get_selection().get_selected()
173        if iter == None:
174            return
175        boolean = store.get_value(iter, BOOLEAN)
176        # change cursor
177        if boolean == None:
178            return
179        try:
180            self.wait()
181            (rc, out) = commands.getstatusoutput("semanage boolean -d %s" % boolean)
182
183            self.ready()
184            if rc != 0:
185                return self.error(out)
186            self.load(self.filter)
187        except ValueError, e:
188            self.error(e.args[0])
189
190    def filter_changed(self, *arg):
191        filter = arg[0].get_text()
192        if filter != self.filter:
193            self.load(filter)
194            self.filter = filter
195
196    def use_menus(self):
197        return False
198
199    def get_description(self):
200        return _("Boolean")
201
202    def match(self, key, filter=""):
203        try:
204            f = filter.lower()
205            cat = self.booleans.get_category(key).lower()
206            val = self.booleans.get_desc(key).lower()
207            k = key.lower()
208            return val.find(f) >= 0 or k.find(f) >= 0 or cat.find(f) >= 0
209        except:
210            return False
211
212    def load(self, filter=None):
213        self.store.clear()
214        self.booleans = seobject.booleanRecords()
215        booleansList = self.booleans.get_all(self.local)
216        for name in booleansList:
217            rec = booleansList[name]
218            if self.match(name, filter):
219                iter = self.store.append()
220                self.store.set_value(iter, ACTIVE, rec[2] == 1)
221                self.store.set_value(iter, MODULE, self.booleans.get_category(name))
222                self.store.set_value(iter, DESC, self.booleans.get_desc(name))
223                self.store.set_value(iter, BOOLEAN, name)
224
225    def boolean_toggled(self, widget, row):
226        iter = self.store.get_iter(row)
227        val = self.store.get_value(iter, ACTIVE)
228        key = self.store.get_value(iter, BOOLEAN)
229        self.store.set_value(iter, ACTIVE, not val)
230        self.wait()
231        setsebool = "/usr/sbin/setsebool -P %s %d" % (key, not val)
232        rc, out = commands.getstatusoutput(setsebool)
233        if rc != 0:
234            self.error(out)
235        self.load(self.filter)
236        self.ready()
237
238    def on_revert_clicked(self, button):
239        self.wait()
240        setsebool = "semanage boolean --deleteall"
241        commands.getstatusoutput(setsebool)
242        self.load(self.filter)
243        self.ready()
244
245    def on_local_clicked(self, button):
246        self.local = not self.local
247        self.revertButton.set_sensitive(self.local)
248
249        if self.local:
250            button.set_label(_("all"))
251        else:
252            button.set_label(_("Customized"))
253
254        self.load(self.filter)
255        return True
256