• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python
2
3import dbus
4import dbus.service
5import dbus.mainloop.glib
6import gobject
7import slip.dbus.service
8from slip.dbus import polkit
9import os
10import selinux
11from subprocess import Popen, PIPE, STDOUT
12
13class selinux_server(slip.dbus.service.Object):
14    default_polkit_auth_required = "org.selinux.semanage"
15    def __init__ (self, *p, **k):
16        super(selinux_server, self).__init__(*p, **k)
17
18    #
19    # The semanage method runs a transaction on a series of semanage commands,
20    # these commnds can take the output of customized
21    #
22    @slip.dbus.polkit.require_auth("org.selinux.semanage")
23    @dbus.service.method("org.selinux", in_signature='s')
24    def semanage(self, buf):
25        p = Popen(["/usr/sbin/semanage", "import"],stdout=PIPE, stderr=PIPE, stdin=PIPE)
26        p.stdin.write(buf)
27        output = p.communicate()
28        if p.returncode and p.returncode != 0:
29            raise dbus.exceptions.DBusException(output[1])
30
31    #
32    # The customized method will return all of the custommizations for policy
33    # on the server.  This output can be used with the semanage method on
34    # another server to make the two systems have duplicate policy.
35    #
36    @slip.dbus.polkit.require_auth("org.selinux.customized")
37    @dbus.service.method("org.selinux", in_signature='', out_signature='s')
38    def customized(self):
39        p = Popen(["/usr/sbin/semanage", "export"],stdout=PIPE, stderr=PIPE)
40        buf = p.stdout.read()
41        output = p.communicate()
42        if p.returncode and p.returncode != 0:
43            raise OSError("Failed to read SELinux configuration: %s", output)
44        return buf
45
46    #
47    # The semodule_list method will return the output of semodule -l, using the customized polkit,
48    # since this is a readonly behaviour
49    #
50    @slip.dbus.polkit.require_auth("org.selinux.semodule_list")
51    @dbus.service.method("org.selinux", in_signature='', out_signature='s')
52    def semodule_list(self):
53        p = Popen(["/usr/sbin/semodule", "-l"],stdout=PIPE, stderr=PIPE)
54        buf = p.stdout.read()
55        output = p.communicate()
56        if p.returncode and p.returncode != 0:
57            raise OSError("Failed to list SELinux modules: %s", output)
58        return buf
59
60    #
61    # The restorecon method modifies any file path to the default system label
62    #
63    @slip.dbus.polkit.require_auth("org.selinux.restorecon")
64    @dbus.service.method("org.selinux", in_signature='s')
65    def restorecon(self, path):
66        selinux.restorecon(str(path), recursive=1)
67
68    #
69    # The setenforce method turns off the current enforcement of SELinux
70    #
71    @slip.dbus.polkit.require_auth("org.selinux.setenforce")
72    @dbus.service.method("org.selinux", in_signature='i')
73    def setenforce(self, value):
74        selinux.security_setenforce(value)
75
76    #
77    # The setenforce method turns off the current enforcement of SELinux
78    #
79    @slip.dbus.polkit.require_auth("org.selinux.relabel_on_boot")
80    @dbus.service.method("org.selinux", in_signature='i')
81    def relabel_on_boot(self, value):
82        if value == 1:
83            fd = open("/.autorelabel","w")
84            fd.close()
85        else:
86            os.unlink("/.autorelabel")
87
88    def write_selinux_config(self, enforcing=None, policy=None):
89        path = selinux.selinux_path() + "config"
90        backup_path = path + ".bck"
91        fd = open(path)
92        lines = fd.readlines()
93        fd.close()
94        fd = open(backup_path, "w")
95        for l in lines:
96            if enforcing and l.startswith("SELINUX="):
97                fd.write("SELINUX=%s\n" % enforcing)
98                continue
99            if policy and l.startswith("SELINUXTYPE="):
100                fd.write("SELINUXTYPE=%s\n" % policy)
101                continue
102            fd.write(l)
103        fd.close()
104        os.rename(backup_path, path)
105
106    #
107    # The change_default_enforcement modifies the current enforcement mode
108    #
109    @slip.dbus.polkit.require_auth("org.selinux.change_default_mode")
110    @dbus.service.method("org.selinux", in_signature='s')
111    def change_default_mode(self, value):
112        values = [ "enforcing", "permissive", "disabled" ]
113        if value not in values:
114            raise ValueError("Enforcement mode must be %s" % ", ".join(values))
115        self.write_selinux_config(enforcing=value)
116
117
118    #
119    # The change_default_policy method modifies the policy type
120    #
121    @slip.dbus.polkit.require_auth("org.selinux.change_default_policy")
122    @dbus.service.method("org.selinux", in_signature='s')
123    def change_default_policy(self, value):
124        path = selinux.selinux_path() + value
125        if os.path.isdir(path):
126            return self.write_selinux_config(policy=value)
127        raise ValueError("%s does not exist" % path)
128
129if __name__ == "__main__":
130        mainloop = gobject.MainLoop()
131        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
132        system_bus = dbus.SystemBus()
133        name = dbus.service.BusName("org.selinux", system_bus)
134        object = selinux_server(system_bus, "/org/selinux/object")
135        slip.dbus.service.set_mainloop(mainloop)
136        mainloop.run()
137