From 132b0f633bc0972472c92ce6b0ce219924e2e3ec Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Fri, 27 Jan 2012 13:24:08 -0500 Subject: [PATCH] Add ability to send proper audit messages to semanage --- policycoreutils-rhat.patch | 573 ++++++++++++++++++++++++++++++++++++- policycoreutils.spec | 5 +- 2 files changed, 571 insertions(+), 7 deletions(-) diff --git a/policycoreutils-rhat.patch b/policycoreutils-rhat.patch index 592cedf..0b1dfcc 100644 --- a/policycoreutils-rhat.patch +++ b/policycoreutils-rhat.patch @@ -435,9 +435,15 @@ index 0c7c186..aaba8b1 100644 except IOError: import __builtin__ diff --git a/policycoreutils/semanage/seobject.py b/policycoreutils/semanage/seobject.py -index 17afe23..e5b6303 100644 +index 17afe23..12cd0fe 100644 --- a/policycoreutils/semanage/seobject.py +++ b/policycoreutils/semanage/seobject.py +@@ -1,4 +1,4 @@ +-#! /usr/bin/python -E ++#! /usr/bin/python -Es + # Copyright (C) 2005-2011 Red Hat + # see file 'COPYING' for use and warranty information + # @@ -30,11 +30,10 @@ from IPy import IP import gettext gettext.bindtextdomain(PROGNAME, "/usr/share/locale") @@ -454,7 +460,222 @@ index 17afe23..e5b6303 100644 import syslog -@@ -431,7 +430,9 @@ class loginRecords(semanageRecords): +@@ -61,32 +60,67 @@ try: + class logger: + def __init__(self): + self.audit_fd = audit.audit_open() +- +- def log(self, success, msg, name = "", sename = "", serole = "", serange = "", old_sename = "", old_serole = "", old_serange = ""): +- audit.audit_log_semanage_message(self.audit_fd, audit.AUDIT_USER_ROLE_CHANGE, sys.argv[0], str(msg), name, 0, sename, serole, serange, old_sename, old_serole, old_serange, "", "", "", success); ++ self.log_list = [] ++ def log(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""): ++ ++ sep = "-" ++ if sename != oldsename: ++ msg += sep + "sename"; sep = "," ++ if serole != oldserole: ++ msg += sep + "role"; sep = "," ++ if serange != oldserange: ++ msg += sep + "range"; sep = "," ++ ++ 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 commit(self,success): ++ for l in self.log_list: ++ audit.audit_log_semanage_message(*(l + [success])) ++ self.log_list = [] + except: + class logger: +- def log(self, success, msg, name = "", sename = "", serole = "", serange = "", old_sename = "", old_serole = "", old_serange = ""): +- if success == 1: +- message = "Successful: " +- else: +- message = "Failed: " ++ def __init__(self): ++ self.log_list=[] ++ ++ def log(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""): + message += " %s name=%s" % (msg, name) + if sename != "": + message += " sename=" + sename +- if old_sename != "": +- message += " old_sename=" + old_sename ++ if oldsename != "": ++ message += " oldsename=" + oldsename + if serole != "": + message += " role=" + serole +- if old_serole != "": +- message += " old_role=" + old_serole ++ if oldserole != "": ++ message += " old_role=" + oldserole + if serange != "" and serange != None: + message += " MLSRange=" + serange +- if old_serange != "" and old_serange != None: +- message += " old_MLSRange=" + old_serange +- syslog.syslog(message); +- +-mylog = logger() ++ if oldserange != "" and oldserange != 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 commit(self,success): ++ if success == 1: ++ message = "Successful: " ++ else: ++ message = "Failed: " ++ for l in self.log_list: ++ syslog.syslog(syslog.LOG_INFO, message + l) ++ ++class nulllogger: ++ def log(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""): ++ pass ++ ++ def log_remove(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""): ++ pass ++ ++ def commit(self,success): ++ pass + + import xml.etree.ElementTree + +@@ -168,44 +202,50 @@ class semanageRecords: + store = None + def __init__(self, store): + global handle +- ++ + self.sh = self.get_handle(store) + ++ rc, localstore = selinux.selinux_getpolicytype() ++ if store == "" or store == localstore: ++ self.mylog = logger() ++ else: ++ self.mylog = nulllogger() ++ + def get_handle(self, store): +- global is_mls_enabled ++ global is_mls_enabled + +- if semanageRecords.handle: +- return semanageRecords.handle ++ if semanageRecords.handle: ++ return semanageRecords.handle + +- handle = semanage_handle_create() +- if not handle: +- raise ValueError(_("Could not create semanage handle")) ++ handle = semanage_handle_create() ++ if not handle: ++ 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 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.")) ++ 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_access_check(handle) ++ if rc < SEMANAGE_CAN_READ: ++ semanage_handle_destroy(handle) ++ raise ValueError(_("Cannot read policy store.")) + +- rc = semanage_connect(handle) +- if rc < 0: +- semanage_handle_destroy(handle) +- raise ValueError(_("Could not establish semanage connection")) ++ rc = semanage_connect(handle) ++ if rc < 0: ++ semanage_handle_destroy(handle) ++ raise ValueError(_("Could not establish semanage connection")) + +- is_mls_enabled = semanage_mls_enabled(handle) +- if is_mls_enabled < 0: +- semanage_handle_destroy(handle) +- raise ValueError(_("Could not test MLS enabled status")) ++ is_mls_enabled = semanage_mls_enabled(handle) ++ if is_mls_enabled < 0: ++ semanage_handle_destroy(handle) ++ raise ValueError(_("Could not test MLS enabled status")) + +- semanageRecords.handle = handle +- return semanageRecords.handle ++ semanageRecords.handle = handle ++ return semanageRecords.handle + + def deleteall(self): + raise ValueError(_("Not yet implemented")) +@@ -226,11 +266,13 @@ class semanageRecords: + raise ValueError(_("Not yet implemented")) + + def commit(self): +- if semanageRecords.transaction: +- return +- rc = semanage_commit(self.sh) +- if rc < 0: +- raise ValueError(_("Could not commit semanage transaction")) ++ if semanageRecords.transaction: ++ return ++ rc = semanage_commit(self.sh) ++ if rc < 0: ++ self.mylog.commit(0) ++ raise ValueError(_("Could not commit semanage transaction")) ++ self.mylog.commit(1) + + def finish(self): + if not semanageRecords.transaction: +@@ -412,17 +454,26 @@ permissive %s; + class loginRecords(semanageRecords): + def __init__(self, store = ""): + semanageRecords.__init__(self, store) ++ self.oldsename = None ++ self.oldserange = None ++ self.sename = None ++ self.serange = None + + def __add(self, name, sename, serange): +- if is_mls_enabled == 1: +- if serange == "": +- serange = "s0" +- else: +- serange = untranslate(serange) +- ++ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) + if sename == "": + sename = "user_u" + ++ userrec = seluserRecords() ++ range, (rc, oldserole) = userrec.get(self.oldsename) ++ range, (rc, serole) = userrec.get(sename) ++ ++ if is_mls_enabled == 1: ++ if serange != "": ++ serange = untranslate(serange) ++ else: ++ serange = range ++ + (rc, k) = semanage_seuser_key_create(self.sh, name) + if rc < 0: + raise ValueError(_("Could not create a key for %s") % name) +@@ -431,7 +482,9 @@ class loginRecords(semanageRecords): if rc < 0: raise ValueError(_("Could not check if login mapping for %s is defined") % name) if exists: @@ -465,7 +686,230 @@ index 17afe23..e5b6303 100644 if name[0] == '%': try: grp.getgrnam(name[1:]) -@@ -641,7 +642,8 @@ class seluserRecords(semanageRecords): +@@ -466,113 +519,132 @@ class loginRecords(semanageRecords): + + semanage_seuser_key_free(k) + semanage_seuser_free(u) ++ self.mylog.log("login", name, sename=sename, serange=serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange); + + def add(self, name, sename, serange): + try: +- self.begin() +- self.__add(name, sename, serange) +- self.commit() +- ++ self.begin() ++ self.__add(name, sename, serange) ++ self.commit() + except ValueError, error: +- mylog.log(0, _("add SELinux user mapping"), name, sename, "", serange); ++ self.mylog.commit(0) + raise error +- +- mylog.log(1, _("add SELinux user mapping"), name, sename, "", serange); + + def __modify(self, name, sename = "", serange = ""): +- if sename == "" and serange == "": ++ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) ++ if sename == "" and serange == "": + raise ValueError(_("Requires seuser or serange")) + +- (rc, k) = semanage_seuser_key_create(self.sh, name) +- if rc < 0: +- raise ValueError(_("Could not create a key for %s") % name) +- +- (rc, exists) = semanage_seuser_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if login mapping for %s is defined") % name) +- if not exists: +- raise ValueError(_("Login mapping for %s is not defined") % name) ++ userrec = seluserRecords() ++ range, (rc, oldserole) = userrec.get(self.oldsename) + +- (rc, u) = semanage_seuser_query(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not query seuser for %s") % name) ++ if sename != "": ++ range, (rc, serole) = userrec.get(sename) ++ else: ++ serole=oldserole + +- oldserange = semanage_seuser_get_mlsrange(u) +- oldsename = semanage_seuser_get_sename(u) +- if serange != "": +- semanage_seuser_set_mlsrange(self.sh, u, untranslate(serange)) +- else: +- serange = oldserange ++ if serange != "": ++ self.serange=serange ++ else: ++ self.serange=range + +- if sename != "": +- semanage_seuser_set_sename(self.sh, u, sename) +- else: +- sename = oldsename ++ (rc, k) = semanage_seuser_key_create(self.sh, name) ++ if rc < 0: ++ raise ValueError(_("Could not create a key for %s") % name) + +- rc = semanage_seuser_modify_local(self.sh, k, u) +- if rc < 0: +- raise ValueError(_("Could not modify login mapping for %s") % name) ++ (rc, exists) = semanage_seuser_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if login mapping for %s is defined") % name) ++ if not exists: ++ raise ValueError(_("Login mapping for %s is not defined") % name) ++ ++ (rc, u) = semanage_seuser_query(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not query seuser for %s") % name) ++ ++ self.oldserange = semanage_seuser_get_mlsrange(u) ++ self.oldsename = semanage_seuser_get_sename(u) ++ if serange != "": ++ semanage_seuser_set_mlsrange(self.sh, u, untranslate(serange)) + +- semanage_seuser_key_free(k) +- semanage_seuser_free(u) ++ if sename != "": ++ semanage_seuser_set_sename(self.sh, u, sename) ++ else: ++ self.sename = self.oldsename ++ ++ rc = semanage_seuser_modify_local(self.sh, k, u) ++ if rc < 0: ++ raise ValueError(_("Could not modify login mapping for %s") % name) + +- mylog.log(1, "modify selinux user mapping", name, sename, "", serange, oldsename, "", oldserange); ++ semanage_seuser_key_free(k) ++ semanage_seuser_free(u) ++ self.mylog.log("login", name,sename=self.sename,serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange); + + def modify(self, name, sename = "", serange = ""): + try: + self.begin() + self.__modify(name, sename, serange) + self.commit() +- + except ValueError, error: +- mylog.log(0, "modify selinux user mapping", name, sename, "", serange, "", "", ""); ++ self.mylog.commit(0) + raise error +- ++ + def __delete(self, name): +- (rc, k) = semanage_seuser_key_create(self.sh, name) +- if rc < 0: +- raise ValueError(_("Could not create a key for %s") % name) ++ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) ++ userrec = seluserRecords() ++ range, (rc, oldserole) = userrec.get(self.oldsename) + +- (rc, exists) = semanage_seuser_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if login mapping for %s is defined") % name) +- if not exists: +- raise ValueError(_("Login mapping for %s is not defined") % name) ++ (rc, k) = semanage_seuser_key_create(self.sh, name) ++ if rc < 0: ++ raise ValueError(_("Could not create a key for %s") % name) + +- (rc, exists) = semanage_seuser_exists_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if login mapping for %s is defined") % name) +- if not exists: +- raise ValueError(_("Login mapping for %s is defined in policy, cannot be deleted") % name) ++ (rc, exists) = semanage_seuser_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if login mapping for %s is defined") % name) ++ if not exists: ++ raise ValueError(_("Login mapping for %s is not defined") % name) ++ ++ (rc, exists) = semanage_seuser_exists_local(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if login mapping for %s is defined") % name) ++ if not exists: ++ raise ValueError(_("Login mapping for %s is defined in policy, cannot be deleted") % name) ++ ++ rc = semanage_seuser_del_local(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not delete login mapping for %s") % name) ++ ++ semanage_seuser_key_free(k) + +- rc = semanage_seuser_del_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not delete login mapping for %s") % name) ++ rec, self.sename, self.serange = selinux.getseuserbyname("__default__") ++ range, (rc, serole) = userrec.get(self.sename) + +- semanage_seuser_key_free(k) ++ self.mylog.log_remove("login", name, sename=self.sename, serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange); + + def delete(self, name): + try: +- self.begin() +- self.__delete(name) +- self.commit() ++ self.begin() ++ self.__delete(name) ++ self.commit() + + except ValueError, error: +- mylog.log(0, "delete SELinux user mapping", name); ++ self.mylog.commit(0) + raise error + +- mylog.log(1, "delete SELinux user mapping", name); +- + def deleteall(self): + (rc, ulist) = semanage_seuser_list_local(self.sh) + if rc < 0: + raise ValueError(_("Could not list login mappings")) + +- self.begin() +- for u in ulist: +- self.__delete(semanage_seuser_get_name(u)) +- self.commit() +- ++ try: ++ self.begin() ++ for u in ulist: ++ self.__delete(semanage_seuser_get_name(u)) ++ self.commit() ++ except ValueError, error: ++ self.mylog.commit(0) ++ raise error ++ + def get_all(self, locallist = 0): + ddict = {} + if locallist: +@@ -618,6 +690,22 @@ class seluserRecords(semanageRecords): + def __init__(self, store = ""): + semanageRecords.__init__(self, store) + ++ def get(self, name): ++ (rc, k) = semanage_user_key_create(self.sh, name) ++ if rc < 0: ++ raise ValueError(_("Could not create a key for %s") % name) ++ (rc, exists) = semanage_user_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if SELinux user %s is defined") % name) ++ (rc, u) = semanage_user_query(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not query user for %s") % name) ++ serange = semanage_user_get_mlsrange(u) ++ serole = semanage_user_get_roles(self.sh,u) ++ semanage_user_key_free(k) ++ semanage_user_free(u) ++ return serange, serole ++ + def __add(self, name, roles, selevel, serange, prefix): + if is_mls_enabled == 1: + if serange == "": +@@ -641,7 +729,8 @@ class seluserRecords(semanageRecords): if rc < 0: raise ValueError(_("Could not check if SELinux user %s is defined") % name) if exists: @@ -475,7 +919,124 @@ index 17afe23..e5b6303 100644 (rc, u) = semanage_user_create(self.sh) if rc < 0: -@@ -1155,7 +1157,8 @@ class nodeRecords(semanageRecords): +@@ -677,21 +766,20 @@ class seluserRecords(semanageRecords): + + semanage_user_key_free(k) + semanage_user_free(u) ++ self.mylog.log("seuser", sename=name, serole=",".join(roles), serange=serange) + + def add(self, name, roles, selevel, serange, prefix): +- seroles = " ".join(roles) +- try: +- self.begin() +- self.__add( name, roles, selevel, serange, prefix) +- self.commit() ++ serole = " ".join(roles) ++ try: ++ self.begin() ++ self.__add( name, roles, selevel, serange, prefix) ++ self.commit() + except ValueError, error: +- mylog.log(0,"add SELinux user record", name, name, seroles, serange) ++ self.mylog.commit(0) + raise error +- +- mylog.log(1,"add SELinux user record", name, name, seroles, serange) + + def __modify(self, name, roles = [], selevel = "", serange = "", prefix = ""): +- oldroles = "" ++ oldserole = "" + oldserange = "" + newroles = string.join(roles, ' '); + if prefix == "" and len(roles) == 0 and serange == "" and selevel == "": +@@ -717,9 +805,7 @@ class seluserRecords(semanageRecords): + oldserange = semanage_user_get_mlsrange(u) + (rc, rlist) = semanage_user_get_roles(self.sh, u) + if rc >= 0: +- oldroles = string.join(rlist, ' '); +- newroles = newroles + ' ' + oldroles; +- ++ oldserole = string.join(rlist, ' '); + + if serange != "": + semanage_user_set_mlsrange(self.sh, u, untranslate(serange)) +@@ -743,8 +829,10 @@ class seluserRecords(semanageRecords): + + semanage_user_key_free(k) + semanage_user_free(u) +- +- mylog.log(1,"modify SELinux user record", name, "", newroles, serange, "", oldroles, oldserange) ++ ++ role=",".join(newroles.split()) ++ oldserole=",".join(oldserole.split()) ++ self.mylog.log("seuser", sename=name, oldsename=name, serole=role, serange=serange, oldserole=oldserole, oldserange=oldserange) + + + def modify(self, name, roles = [], selevel = "", serange = "", prefix = ""): +@@ -752,9 +840,8 @@ class seluserRecords(semanageRecords): + self.begin() + self.__modify(name, roles, selevel, serange, prefix) + self.commit() +- + except ValueError, error: +- mylog.log(0,"modify SELinux user record", name, "", " ".join(roles), serange, "", "", "") ++ self.mylog.commit(0) + raise error + + def __delete(self, name): +@@ -774,11 +861,21 @@ class seluserRecords(semanageRecords): + if not exists: + raise ValueError(_("SELinux user %s is defined in policy, cannot be deleted") % name) + ++ (rc, u) = semanage_user_query(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not query user for %s") % name) ++ oldserange = semanage_user_get_mlsrange(u) ++ (rc, rlist) = semanage_user_get_roles(self.sh, u) ++ oldserole = ",".join(rlist) ++ + rc = semanage_user_del_local(self.sh, k) + if rc < 0: + raise ValueError(_("Could not delete SELinux user %s") % name) + + semanage_user_key_free(k) ++ semanage_user_free(u) ++ ++ self.mylog.log_remove("seuser", oldsename=name, oldserange=oldserange, oldserole=oldserole) + + def delete(self, name): + try: +@@ -787,20 +884,22 @@ class seluserRecords(semanageRecords): + self.commit() + + except ValueError, error: +- mylog.log(0,"delete SELinux user record", name) ++ self.mylog.commit(0) + raise error + +- mylog.log(1,"delete SELinux user record", name) +- + def deleteall(self): + (rc, ulist) = semanage_user_list_local(self.sh) + if rc < 0: + raise ValueError(_("Could not list login mappings")) + +- self.begin() +- for u in ulist: +- self.__delete(semanage_user_get_name(u)) +- self.commit() ++ try: ++ self.begin() ++ for u in ulist: ++ self.__delete(semanage_user_get_name(u)) ++ self.commit() ++ except ValueError, error: ++ self.mylog.commit(0) ++ raise error + + def get_all(self, locallist = 0): + ddict = {} +@@ -1155,7 +1254,8 @@ class nodeRecords(semanageRecords): (rc, exists) = semanage_node_exists(self.sh, k) if exists: @@ -485,7 +1046,7 @@ index 17afe23..e5b6303 100644 (rc, node) = semanage_node_create(self.sh) if rc < 0: -@@ -1353,7 +1356,8 @@ class interfaceRecords(semanageRecords): +@@ -1353,7 +1453,8 @@ class interfaceRecords(semanageRecords): if rc < 0: raise ValueError(_("Could not check if interface %s is defined") % interface) if exists: @@ -495,7 +1056,7 @@ index 17afe23..e5b6303 100644 (rc, iface) = semanage_iface_create(self.sh) if rc < 0: -@@ -1636,7 +1640,8 @@ class fcontextRecords(semanageRecords): +@@ -1636,7 +1737,8 @@ class fcontextRecords(semanageRecords): raise ValueError(_("Could not check if file context for %s is defined") % target) if exists: diff --git a/policycoreutils.spec b/policycoreutils.spec index 7b6e451..9120313 100644 --- a/policycoreutils.spec +++ b/policycoreutils.spec @@ -7,7 +7,7 @@ Summary: SELinux policy core utilities Name: policycoreutils Version: 2.1.10 -Release: 16%{?dist} +Release: 17%{?dist} License: GPLv2 Group: System Environment/Base # Based on git repository with tag 20101221 @@ -361,6 +361,9 @@ fi /bin/systemctl try-restart restorecond.service >/dev/null 2>&1 || : %changelog +* Fri Jan 26 2012 Dan Walsh - 2.1.10-17 +- Change semanage to produce proper audit records for Common Criteria + * Thu Jan 26 2012 Harald Hoyer 2.1.10-16 - fixed load_policy location