# Copyright (C) 2005-2013 Red Hat
# see file 'COPYING' for use and warranty information
# semanage is a tool for managing SELinux configuration files
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
PROGNAME = "selinux-python"
if sys.version_info < (3,):
gettext.install(PROGNAME,
localedir="/usr/share/locale",
builtins.__dict__['_'] = str
__builtin__.__dict__['_'] = unicode
file_types[""] = SEMANAGE_FCONTEXT_ALL
file_types["all files"] = SEMANAGE_FCONTEXT_ALL
file_types["a"] = SEMANAGE_FCONTEXT_ALL
file_types["regular file"] = SEMANAGE_FCONTEXT_REG
file_types["--"] = SEMANAGE_FCONTEXT_REG
file_types["f"] = SEMANAGE_FCONTEXT_REG
file_types["-d"] = SEMANAGE_FCONTEXT_DIR
file_types["directory"] = SEMANAGE_FCONTEXT_DIR
file_types["d"] = SEMANAGE_FCONTEXT_DIR
file_types["-c"] = SEMANAGE_FCONTEXT_CHAR
file_types["character device"] = SEMANAGE_FCONTEXT_CHAR
file_types["c"] = SEMANAGE_FCONTEXT_CHAR
file_types["-b"] = SEMANAGE_FCONTEXT_BLOCK
file_types["block device"] = SEMANAGE_FCONTEXT_BLOCK
file_types["b"] = SEMANAGE_FCONTEXT_BLOCK
file_types["-s"] = SEMANAGE_FCONTEXT_SOCK
file_types["socket"] = SEMANAGE_FCONTEXT_SOCK
file_types["s"] = SEMANAGE_FCONTEXT_SOCK
file_types["-l"] = SEMANAGE_FCONTEXT_LINK
file_types["l"] = SEMANAGE_FCONTEXT_LINK
file_types["symbolic link"] = SEMANAGE_FCONTEXT_LINK
file_types["p"] = SEMANAGE_FCONTEXT_PIPE
file_types["-p"] = SEMANAGE_FCONTEXT_PIPE
file_types["named pipe"] = SEMANAGE_FCONTEXT_PIPE
file_type_str_to_option = {"all files": "a",
ftype_to_audit = {"": "any",
#test if audit module is enabled
audit.audit_close(audit.audit_open())
self.audit_fd = audit.audit_open()
self.log_change_list = []
def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
if serange != oldserange:
self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_ASSIGN, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_REMOVE, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
def log_change(self, msg):
self.log_change_list.append([self.audit_fd, audit.AUDIT_USER_MAC_CONFIG_CHANGE, str(msg), "semanage", "", "", ""])
def commit(self, success):
audit.audit_log_semanage_message(*(l + [success]))
for l in self.log_change_list:
audit.audit_log_user_comm_message(*(l + [success]))
self.log_change_list = []
except (OSError, ImportError):
def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
message = " %s name=%s" % (msg, name)
message += " sename=" + sename
message += " oldsename=" + oldsename
message += " role=" + serole
message += " old_role=" + oldserole
if serange != "" and serange is not None:
message += " MLSRange=" + serange
if oldserange != "" and oldserange is not None:
message += " old_MLSRange=" + oldserange
self.log_list.append(message)
def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
self.log(msg, name, sename, serole, serange, oldsename, oldserole, oldserange)
def log_change(self, msg):
self.log_list.append(" %s" % msg)
def commit(self, success):
syslog.syslog(syslog.LOG_INFO, message + l)
def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
def log_change(self, msg):
def commit(self, success):
cat_range = category + r"(\." + category + ")?"
categories = cat_range + r"(\," + cat_range + ")*"
reg = sensitivity + "(-" + sensitivity + ")?" + "(:" + categories + ")?"
return re.search("^" + reg + "$", raw)
def translate(raw, prepend=1):
context = "%s%s" % (filler, raw)
(rc, trans) = selinux.selinux_raw_to_trans_context(context)
trans = trans[len(filler):]
def untranslate(trans, prepend=1):
context = "%s%s" % (filler, trans)
(rc, raw) = selinux.selinux_trans_to_raw_context(context)
def __init__(self, args = None):
# legacy code - args was store originally
self.noreload = getattr(args, "noreload", False)
self.store = getattr(args, "store", "")
self.sh = self.get_handle(self.store)
rc, localstore = selinux.selinux_getpolicytype()
if self.store == "" or self.store == localstore:
sepolicy.load_store_policy(self.store)
selinux.selinux_set_policy_root("%s%s" % (selinux.selinux_path(), self.store))
self.mylog = nulllogger()
def set_reload(self, load):
def get_handle(self, store):
if semanageRecords.handle:
return semanageRecords.handle
handle = semanage_handle_create()
raise ValueError(_("Could not create semanage handle"))
if not semanageRecords.transaction and store != "":
semanage_select_store(handle, store, SEMANAGE_CON_DIRECT)
semanageRecords.store = store
if not semanage_is_managed(handle):
semanage_handle_destroy(handle)
raise ValueError(_("SELinux policy is not managed or store cannot be accessed."))
rc = semanage_access_check(handle)
if rc < SEMANAGE_CAN_READ:
semanage_handle_destroy(handle)
raise ValueError(_("Cannot read policy store."))
rc = semanage_connect(handle)
semanage_handle_destroy(handle)
raise ValueError(_("Could not establish semanage connection"))
is_mls_enabled = semanage_mls_enabled(handle)
semanage_handle_destroy(handle)
raise ValueError(_("Could not test MLS enabled status"))
semanageRecords.handle = handle
return semanageRecords.handle
raise ValueError(_("Not yet implemented"))
if semanageRecords.transaction:
raise ValueError(_("Semanage transaction already in progress"))
semanageRecords.transaction = True
if semanageRecords.transaction:
rc = semanage_begin_transaction(self.sh)
raise ValueError(_("Could not start semanage transaction"))
raise ValueError(_("Not yet implemented"))
if semanageRecords.transaction:
semanage_set_reload(self.sh, 0)
rc = semanage_commit(self.sh)
raise ValueError(_("Could not commit semanage transaction"))
if not semanageRecords.transaction:
raise ValueError(_("Semanage transaction not in progress"))
semanageRecords.transaction = False
class moduleRecords(semanageRecords):
def __init__(self, args = None):
semanageRecords.__init__(self, args)
(rc, mlist, number) = semanage_module_list_all(self.sh)
raise ValueError(_("Could not list SELinux modules"))
mod = semanage_module_list_nth(mlist, i)
rc, name = semanage_module_info_get_name(self.sh, mod)
raise ValueError(_("Could not get module name"))
rc, enabled = semanage_module_info_get_enabled(self.sh, mod)
raise ValueError(_("Could not get module enabled"))
rc, priority = semanage_module_info_get_priority(self.sh, mod)
raise ValueError(_("Could not get module priority"))
rc, lang_ext = semanage_module_info_get_lang_ext(self.sh, mod)
raise ValueError(_("Could not get module lang_ext"))
l.append((name, enabled, priority, lang_ext))
# sort the list so they are in name order, but with higher priorities coming first
l.sort(key=lambda t: t[3], reverse=True)
l.sort(key=lambda t: t[0])
return ["-d %s" % x[0] for x in [t for t in all if t[1] == 0]]
def list(self, heading=1, locallist=0):
print("\n%-25s %-9s %s\n" % (_("Module Name"), _("Priority"), _("Language")))
print("%-25s %-9s %-5s %s" % (t[0], t[2], t[3], disabled))
def add(self, file, priority):
if not os.path.exists(file):
raise ValueError(_("Module does not exist: %s ") % file)
rc = semanage_set_default_priority(self.sh, priority)
raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
rc = semanage_module_install_file(self.sh, file)
def set_enabled(self, module, enable):
rc, key = semanage_module_key_create(self.sh)
raise ValueError(_("Could not create module key"))
rc = semanage_module_key_set_name(self.sh, key, m)
raise ValueError(_("Could not set module key name"))
rc = semanage_module_set_enabled(self.sh, key, enable)
raise ValueError(_("Could not enable module %s") % m)
raise ValueError(_("Could not disable module %s") % m)
def delete(self, module, priority):
rc = semanage_set_default_priority(self.sh, priority)
raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
rc = semanage_module_remove(self.sh, m)
raise ValueError(_("Could not remove module %s (remove failed)") % m)
l = [x[0] for x in [t for t in self.get_all() if t[1] == 0]]
self.set_enabled(m, True)
class dontauditClass(semanageRecords):
def __init__(self, args = None):
semanageRecords.__init__(self, args)
def toggle(self, dontaudit):
if dontaudit not in ["on", "off"]:
raise ValueError(_("dontaudit requires either 'on' or 'off'"))
semanage_set_disable_dontaudit(self.sh, dontaudit == "off")
class permissiveRecords(semanageRecords):
def __init__(self, args = None):
semanageRecords.__init__(self, args)
(rc, mlist, number) = semanage_module_list(self.sh)
raise ValueError(_("Could not list SELinux modules"))
mod = semanage_module_list_nth(mlist, i)
name = semanage_module_get_name(mod)
if name and name.startswith("permissive_"):
l.append(name.split("permissive_")[1])
return ["-a %s" % x for x in sorted(self.get_all())]
def list(self, heading=1, locallist=0):
all = [y["name"] for y in [x for x in sepolicy.info(sepolicy.TYPE) if x["permissive"]]]
print("\n%-25s\n" % (_("Builtin Permissive Types")))
customized = self.get_all()
print("\n%-25s\n" % (_("Customized Permissive Types")))