[libsemanage] Move handling of role audit records into the library

Daniel J Walsh dwalsh at fedoraproject.org
Fri Jul 26 21:39:49 UTC 2013


commit 514a8aa4c004703bb7fbade819d898973471a827
Author: Dan Walsh <dwalsh at redhat.com>
Date:   Fri Jul 26 17:39:40 2013 -0400

    Move handling of role audit records into the library
    
    - Patch stops semanage from removing user record while in use

 libsemanage-rhat.patch |  374 ++++++++++++++++++++++++++++++++++++++++++++++++
 libsemanage.spec       |   32 +++--
 2 files changed, 392 insertions(+), 14 deletions(-)
---
diff --git a/libsemanage-rhat.patch b/libsemanage-rhat.patch
index 132fc4d..d3bcee6 100644
--- a/libsemanage-rhat.patch
+++ b/libsemanage-rhat.patch
@@ -1,3 +1,377 @@
+diff --git a/libsemanage/man/man3/semanage_bool_set_active.3 b/libsemanage/man/man3/semanage_bool_set_active.3
+index 026e29d..d868fe8 100644
+--- a/libsemanage/man/man3/semanage_bool_set_active.3
++++ b/libsemanage/man/man3/semanage_bool_set_active.3
+@@ -40,7 +40,7 @@ This function requires an semanage connection to be established (see
+ ).
+ 
+ .SH "RETURN VALUE"
+-In case of failure, -1 is returned, and the semanage error callback is invoked, describing the error.
++In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error.
+ Otherwise 0 is returned.
+ 
+ .SH "SEE ALSO"
+diff --git a/libsemanage/man/man3/semanage_count.3 b/libsemanage/man/man3/semanage_count.3
+index b131cbe..b865a21 100644
+--- a/libsemanage/man/man3/semanage_count.3
++++ b/libsemanage/man/man3/semanage_count.3
+@@ -33,7 +33,7 @@ This function requires an semanage connection to be established (see
+ )
+ 
+ .SH "RETURN VALUE"
+-In case of failure, -1 is returned, and the semanage error callback is invoked, describing the error.
++In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error.
+ Otherwise a non-negative integer is returned (a commit number). The same number will be returned by all other semanage object read calls until the next commit.
+ 
+ .SH "SEE ALSO"
+diff --git a/libsemanage/man/man3/semanage_del.3 b/libsemanage/man/man3/semanage_del.3
+index 5b11ce3..4dd0a77 100644
+--- a/libsemanage/man/man3/semanage_del.3
++++ b/libsemanage/man/man3/semanage_del.3
+@@ -40,7 +40,7 @@ This function requires an semanage connection to be established (see
+ ).
+ 
+ .SH "RETURN VALUE"
+-In case of failure, -1 is returned, and the semanage error callback is invoked, describing the error.
++In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error.
+ Otherwise 0 is returned.
+ 
+ .SH "SEE ALSO"
+diff --git a/libsemanage/man/man3/semanage_exists.3 b/libsemanage/man/man3/semanage_exists.3
+index da401c2..6d68c76 100644
+--- a/libsemanage/man/man3/semanage_exists.3
++++ b/libsemanage/man/man3/semanage_exists.3
+@@ -38,7 +38,7 @@ This function requires an semanage connection to be established (see
+ )
+ 
+ .SH "RETURN VALUE"
+-In case of failure, -1 is returned, and the semanage error callback is invoked, describing the error.
++In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error.
+ Otherwise a non-negative integer is returned (a commit number). The same number will be returned by all other read calls to the semanage database until the next commit.
+ 
+ .SH "SEE ALSO"
+diff --git a/libsemanage/man/man3/semanage_iterate.3 b/libsemanage/man/man3/semanage_iterate.3
+index 8773800..1528164 100644
+--- a/libsemanage/man/man3/semanage_iterate.3
++++ b/libsemanage/man/man3/semanage_iterate.3
+@@ -31,7 +31,7 @@ if that is necessary.
+ 
+ The handler code may not invoke any semanage write requests for the same object type (i.e. modifying the underlying store is not allowed). The iterate function is reentrant only while inside a transaction (see
+ .B semanage_begin_transaction
+-). It is not safe to execute other semanage read or write requests within iterate if not inside a transaction. The handler may return -1 to signal error exit, 0 to signal continue, and 1 to signal successful exit early (the iterate function will stop accordingly). 
++). It is not safe to execute other semanage read or write requests within iterate if not inside a transaction. The handler may return \-1 to signal error exit, 0 to signal continue, and 1 to signal successful exit early (the iterate function will stop accordingly).
+ 
+ .TP
+ .B Parameters:
+@@ -50,7 +50,7 @@ This function requires an semanage connection to be established (see
+ )
+ 
+ .SH "RETURN VALUE"
+-In case of failure, -1 is returned, and the semanage error callback is invoked, describing the error.
++In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error.
+ Otherwise a non-negative integer is returned (a commit number). The same number will be returned by all other semanage object read calls until the next commit.
+ 
+ .SH "SEE ALSO"
+diff --git a/libsemanage/man/man3/semanage_list.3 b/libsemanage/man/man3/semanage_list.3
+index 9376702..acc161f 100644
+--- a/libsemanage/man/man3/semanage_list.3
++++ b/libsemanage/man/man3/semanage_list.3
+@@ -39,7 +39,7 @@ This function requires an semanage connection to be established (see
+ )
+ 
+ .SH "RETURN VALUE"
+-In case of failure, -1 is returned, and the semanage error callback is invoked, describing the error.
++In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error.
+ Otherwise a non-negative integer is returned (a commit number). The same number will be returned by all other semanage object read calls until the next commit.
+ 
+ .SH "SEE ALSO"
+diff --git a/libsemanage/man/man3/semanage_modify.3 b/libsemanage/man/man3/semanage_modify.3
+index 04bd801..ee23900 100644
+--- a/libsemanage/man/man3/semanage_modify.3
++++ b/libsemanage/man/man3/semanage_modify.3
+@@ -42,7 +42,7 @@ This function requires an semanage connection to be established (see
+ ).
+ 
+ .SH "RETURN VALUE"
+-In case of failure, -1 is returned, and the semanage error callback is invoked, describing the error.
++In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error.
+ Otherwise 0 is returned.
+ 
+ .SH "SEE ALSO"
+diff --git a/libsemanage/man/man3/semanage_query.3 b/libsemanage/man/man3/semanage_query.3
+index 1a6cdb2..e61c8b8 100644
+--- a/libsemanage/man/man3/semanage_query.3
++++ b/libsemanage/man/man3/semanage_query.3
+@@ -39,7 +39,7 @@ This function requires an semanage connection to be established (see
+ )
+ 
+ .SH "RETURN VALUE"
+-In case of failure, -1 is returned, and the semanage error callback is invoked, describing the error.
++In case of failure, \-1 is returned, and the semanage error callback is invoked, describing the error.
+ Otherwise a non-negative integer is returned (a commit number). The same number will be returned by all other semanage object read calls until the next commit.
+ 
+ .SH "SEE ALSO"
+diff --git a/libsemanage/man/man3/semanage_set_root.3 b/libsemanage/man/man3/semanage_set_root.3
+index 2ae0f17..664822e 100644
+--- a/libsemanage/man/man3/semanage_set_root.3
++++ b/libsemanage/man/man3/semanage_set_root.3
+@@ -15,7 +15,7 @@ Set the alternate root directory for SELinux configuration directory.
+ This function sets an alternate root directory to for SELinux configuration paths to be used by the semanage library.
+ 
+ .SH "RETURN VALUE"
+-In case of failure, -1 is returned.
++In case of failure, \-1 is returned.
+ Otherwise 0 is returned.
+ 
+ .SH "SEE ALSO"
+diff --git a/libsemanage/src/Makefile b/libsemanage/src/Makefile
+index c63bb22..edb84cc 100644
+--- a/libsemanage/src/Makefile
++++ b/libsemanage/src/Makefile
+@@ -92,7 +92,7 @@ $(LIBA): $(OBJS)
+ 	$(RANLIB) $@
+ 
+ $(LIBSO): $(LOBJS)
+-	$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -lsepol -lselinux -lbz2 -lustr -L$(LIBDIR) -Wl,-soname,$(LIBSO),--version-script=libsemanage.map,-z,defs
++	$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -lsepol -laudit -lselinux -lbz2 -lustr -L$(LIBDIR) -Wl,-soname,$(LIBSO),--version-script=libsemanage.map,-z,defs
+ 	ln -sf $@ $(TARGET)
+ 
+ $(LIBPC): $(LIBPC).in ../VERSION
+diff --git a/libsemanage/src/genhomedircon.c b/libsemanage/src/genhomedircon.c
+index 3c81d7a..f3b9b5c 100644
+--- a/libsemanage/src/genhomedircon.c
++++ b/libsemanage/src/genhomedircon.c
+@@ -283,7 +283,7 @@ static semanage_list_t *get_home_dirs(genhomedircon_settings_t * s)
+ 	char *rbuf = NULL;
+ 	char *path = NULL;
+ 	long rbuflen;
+-	uid_t temp, minuid = 500;
++	uid_t temp, minuid = 500, maxuid = 60000;
+ 	int minuid_set = 0;
+ 	struct passwd pwstorage, *pwbuf;
+ 	struct stat buf;
+@@ -333,6 +333,14 @@ static semanage_list_t *get_home_dirs(genhomedircon_settings_t * s)
+ 	free(path);
+ 	path = NULL;
+ 
++	path = semanage_findval(PATH_ETC_LOGIN_DEFS, "UID_MAX", NULL);
++	if (path && *path) {
++		temp = atoi(path);
++		maxuid = temp;
++	}
++	free(path);
++	path = NULL;
++
+ 	path = semanage_findval(PATH_ETC_LIBUSER, "LU_UIDNUMBER", "=");
+ 	if (path && *path) {
+ 		temp = atoi(path);
+@@ -352,7 +360,7 @@ static semanage_list_t *get_home_dirs(genhomedircon_settings_t * s)
+ 		goto fail;
+ 	setpwent();
+ 	while ((retval = getpwent_r(&pwstorage, rbuf, rbuflen, &pwbuf)) == 0) {
+-		if (pwbuf->pw_uid < minuid)
++		if (pwbuf->pw_uid < minuid || pwbuf->pw_uid > maxuid)
+ 			continue;
+ 		if (!semanage_list_find(shells, pwbuf->pw_shell))
+ 			continue;
+@@ -385,7 +393,7 @@ static semanage_list_t *get_home_dirs(genhomedircon_settings_t * s)
+ 
+ 			/* NOTE: old genhomedircon printed a warning on match */
+ 			if (hand.matched) {
+-				WARN(s->h_semanage, "%s homedir %s or its parent directory conflicts with a file context already specified in the policy.  This usually indicates an incorrectly defined system account.  If it is a system account please make sure its uid is less than %u or its login shell is /sbin/nologin.", pwbuf->pw_name, pwbuf->pw_dir, minuid);
++				WARN(s->h_semanage, "%s homedir %s or its parent directory conflicts with a file context already specified in the policy.  This usually indicates an incorrectly defined system account.  If it is a system account please make sure its uid is less than %u or greater than %u or its login shell is /sbin/nologin.", pwbuf->pw_name, pwbuf->pw_dir, minuid, maxuid);
+ 			} else {
+ 				if (semanage_list_push(&homedir_list, path))
+ 					goto fail;
+diff --git a/libsemanage/src/seusers_local.c b/libsemanage/src/seusers_local.c
+index e7cf12c..ed0af21 100644
+--- a/libsemanage/src/seusers_local.c
++++ b/libsemanage/src/seusers_local.c
+@@ -8,27 +8,117 @@ typedef struct semanage_seuser record_t;
+ 
+ #include <sepol/policydb.h>
+ #include <sepol/context.h>
++#include <libaudit.h>
++#include <errno.h>
+ #include "user_internal.h"
+ #include "seuser_internal.h"
+ #include "handle.h"
+ #include "database.h"
+ #include "debug.h"
++#include "string.h"
++#include <stdlib.h>
++
++static char *semanage_user_roles(semanage_handle_t * handle, const char *sename) {
++	char *roles = NULL;
++	unsigned int num_roles;
++	size_t i;
++	size_t size = 0;
++	const char **roles_arr;
++	semanage_user_key_t *key = NULL;
++	semanage_user_t * user;
++	if (semanage_user_key_create(handle, sename, &key) >= 0) {
++		if (semanage_user_query(handle, key, &user) >= 0) {
++			if (semanage_user_get_roles(handle, 
++						    user, 
++						    &roles_arr, 
++						    &num_roles) >= 0) {
++				for (i = 0; i<num_roles; i++) {
++					size += (strlen(roles_arr[i]) + 1);
++				}
++				roles = malloc(size);
++				if (roles) {
++					strcpy(roles,roles_arr[0]);
++					for (i = 1; i<num_roles; i++) {
++						strcat(roles,",");
++						strcat(roles,roles_arr[0]);
++					}
++				}
++			}
++			semanage_user_free(user);
++		}
++		semanage_user_key_free(key);
++	}
++	return roles;
++}
++
++static int semanage_seuser_audit(semanage_handle_t * handle,
++			  const semanage_seuser_t * seuser, 
++			  const semanage_seuser_t * previous,
++			  int audit_type, 
++			  int success) {
++	const char *name = NULL;
++	const char *sename = NULL;
++	char *roles = NULL;
++	const char *mls = NULL;
++	const char *psename = NULL;
++	const char *pmls = NULL;
++	char *proles = NULL;
++	if (seuser) {
++		name = semanage_seuser_get_name(seuser);
++		sename = semanage_seuser_get_sename(seuser);
++		mls = semanage_seuser_get_mlsrange(seuser);
++		roles = semanage_user_roles(handle, sename);
++	}
++	if (previous) {
++		psename = semanage_seuser_get_sename(previous);
++		pmls = semanage_seuser_get_mlsrange(previous);
++		proles = semanage_user_roles(handle, psename);
++	}
++
++	int fd = audit_open();
++	if (fd < 0)
++	{
++		/* If kernel doesn't support audit, bail out */
++		if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT)
++			return 0;
++		return fd;
++	}
++	audit_log_semanage_message(fd, audit_type, NULL, NULL, name, 0, sename, roles, mls, psename, proles, pmls, NULL, NULL,NULL, success);
++	audit_close(fd);
++	free(roles);
++	free(proles);
++	return 0;
++}
+ 
+ int semanage_seuser_modify_local(semanage_handle_t * handle,
+ 				 const semanage_seuser_key_t * key,
+ 				 const semanage_seuser_t * data)
+ {
+-
++	int rc;
+ 	dbase_config_t *dconfig = semanage_seuser_dbase_local(handle);
+-	return dbase_modify(handle, dconfig, key, data);
++	semanage_seuser_t *previous = NULL;
++	semanage_seuser_query(handle, key, &previous);
++	rc = dbase_modify(handle, dconfig, key, data);
++	if (semanage_seuser_audit(handle, data, previous, AUDIT_ROLE_ASSIGN, rc == 0) < 0) 
++		rc = -1;
++	if (previous)
++		semanage_seuser_free(previous);
++	return rc;
+ }
+ 
+ int semanage_seuser_del_local(semanage_handle_t * handle,
+ 			      const semanage_seuser_key_t * key)
+ {
+-
++	int rc;
++	semanage_seuser_t *seuser = NULL;
+ 	dbase_config_t *dconfig = semanage_seuser_dbase_local(handle);
+-	return dbase_del(handle, dconfig, key);
++	rc = dbase_del(handle, dconfig, key);
++	semanage_seuser_query(handle, key, &seuser);
++	if (semanage_seuser_audit(handle, NULL, seuser, AUDIT_ROLE_REMOVE, rc == 0) < 0) 
++		rc = -1;
++	if (seuser)
++		semanage_seuser_free(seuser);
++	return rc;
+ }
+ 
+ int semanage_seuser_query_local(semanage_handle_t * handle,
+diff --git a/libsemanage/src/users_local.c b/libsemanage/src/users_local.c
+index 8742ca1..b78ad0e 100644
+--- a/libsemanage/src/users_local.c
++++ b/libsemanage/src/users_local.c
+@@ -6,9 +6,14 @@ typedef struct semanage_user_key record_key_t;
+ typedef struct semanage_user record_t;
+ #define DBASE_RECORD_DEFINED
+ 
++#include <string.h>
++#include <stdlib.h>
+ #include "user_internal.h"
++#include "seuser_internal.h"
+ #include "handle.h"
+ #include "database.h"
++#include "errno.h"
++#include "debug.h"
+ 
+ int semanage_user_modify_local(semanage_handle_t * handle,
+ 			       const semanage_user_key_t * key,
+@@ -19,9 +24,43 @@ int semanage_user_modify_local(semanage_handle_t * handle,
+ 	return dbase_modify(handle, dconfig, key, data);
+ }
+ 
++static int lookup_seuser(semanage_handle_t * handle, const semanage_user_key_t *k) {
++	semanage_user_t *user;
++	semanage_seuser_t **records;
++	const char *name;
++	const char *sename;
++	unsigned int count;
++	size_t i;
++	int rc = 0;
++	if (semanage_user_query(handle, k, &user) < 0)
++		return 0;
++	name = semanage_user_get_name(user);
++	semanage_seuser_list_local(handle,
++				   &records,
++				   &count);
++	for(i=0; i<count; i++) {
++		sename = semanage_seuser_get_sename(records[i]);
++		if (strcmp(name, sename) == 0) {
++			errno = EINVAL;
++			ERR(handle, "%s is being used by %s login record", 
++			    sename, semanage_seuser_get_name(records[i]));
++			rc = -1;
++		}
++	}
++	for(i=0; i<count; i++)
++		semanage_seuser_free(records[i]);
++	free(records);
++	semanage_user_free(user);
++	if (rc)
++		errno = EINVAL;
++	return rc;
++}
++
+ int semanage_user_del_local(semanage_handle_t * handle,
+ 			    const semanage_user_key_t * key)
+ {
++	if (lookup_seuser(handle, key))
++		return -1;
+ 
+ 	dbase_config_t *dconfig = semanage_user_dbase_local(handle);
+ 	return dbase_del(handle, dconfig, key);
 diff --git a/libsemanage/src/utilities.c b/libsemanage/src/utilities.c
 index 349a4be..a340fc8 100644
 --- a/libsemanage/src/utilities.c
diff --git a/libsemanage.spec b/libsemanage.spec
index 93c6a65..4ccc6ca 100644
--- a/libsemanage.spec
+++ b/libsemanage.spec
@@ -7,7 +7,7 @@
 Summary: SELinux binary policy manipulation library 
 Name: libsemanage
 Version: 2.1.10
-Release: 6%{?dist}
+Release: 7%{?dist}
 License: LGPLv2+
 Group: System Environment/Libraries
 Source: libsemanage-%{version}.tgz
@@ -178,6 +178,10 @@ rm -rf ${RPM_BUILD_ROOT}
 %endif # if with_python3
 
 %changelog
+* Fri Jul 26 2013 Dan Walsh <dwalsh at redhat.com> - 2.1.10-7
+- Move handling of role audit records into the library
+- Patch stops semanage from removing user record while in use
+
 * Tue Jul 9 2013 Dan Walsh <dwalsh at redhat.com> - 2.1.10-6
 - Remove dependance on selinux-policy, /etc/selinux should be owned by libsemanage, and selinux-policy can require it.
 
@@ -445,11 +449,11 @@ invoking the appropriate config tool (or by hardcoding the old value for
 - Make sure /root is not used in genhomedircon
 
 * Wed Aug 5 2009 Dan Walsh <dwalsh at redhat.com> - 2.0.35-1
-  * Revert hard linking of files between tmp/active/previous.
-  * Enable configuration of bzip behavior from Stephen Smalley.
-    bzip-blocksize=0 to disable compression and decompression support.
-    bzip-blocksize=1..9 to set the blocksize for compression.
-    bzip-small=true to reduce memory usage for decompression.
+- Revert hard linking of files between tmp/active/previous.
+- Enable configuration of bzip behavior from Stephen Smalley.
+-   bzip-blocksize=0 to disable compression and decompression support.
+-   bzip-blocksize=1..9 to set the blocksize for compression.
+-   bzip-small=true to reduce memory usage for decompression.
 
 * Sat Jul 25 2009 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.0.33-3
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
@@ -488,7 +492,7 @@ invoking the appropriate config tool (or by hardcoding the old value for
 - Rebuild for Python 2.6
 
 * Thu Dec 4 2008 Dan Walsh <dwalsh at redhat.com> - 2.0.30-1
-  * Add semanage_mls_enabled() interface from Stephen Smalley.
+- Add semanage_mls_enabled() interface from Stephen Smalley.
 
 * Sat Nov 29 2008 Ignacio Vazquez-Abrams <ivazqueznet+rpm at gmail.com> - 2.0.29-2
 - Rebuild for Python 2.6
@@ -648,18 +652,18 @@ invoking the appropriate config tool (or by hardcoding the old value for
 
 * Wed Apr 25 2007 Dan Walsh <dwalsh at redhat.com> - 2.0.2-1
 - Upgrade to latest from NSA
-  * Merged optimizations from Stephen Smalley.
-    - do not set all booleans upon commit, only those whose values have changed
-    - only install the sandbox upon commit if something was rebuilt
+- Merged optimizations from Stephen Smalley.
+-    do not set all booleans upon commit, only those whose values have changed
+-    only install the sandbox upon commit if something was rebuilt
 
 * Sat Mar 17 2007 Dan Walsh <dwalsh at redhat.com> - 2.0.1-2
 - Add SELinux to Man page Names so man -k will work
 
 * Mon Mar 12 2007 Dan Walsh <dwalsh at redhat.com> - 2.0.1-1
-  * Merged dbase_file_flush patch from Dan Walsh.
-    This removes any mention of specific tools (e.g. semanage)
-    from the comment header of the auto-generated files,
-    since there are multiple front-end tools.
+- Merged dbase_file_flush patch from Dan Walsh.
+- This removes any mention of specific tools (e.g. semanage)
+- from the comment header of the auto-generated files,
+- since there are multiple front-end tools.
 
 * Tue Feb 20 2007 Dan Walsh <dwalsh at redhat.com> - 2.0.0-1
 - Upgrade to latest from NSA


More information about the scm-commits mailing list