>From 8c9768287a1fade2e8b9cb27f550a3b00ccecc10 Mon Sep 17 00:00:00 2001 From: Dan Walsh <dwalsh@xxxxxxxxxx> Date: Fri, 26 Jul 2013 16:53:40 -0400 Subject: [PATCH 45/45] Patch stops semanage from removing user record while in use Currently you can remove user records with semnage user -d even if a login record is using it. This is very bad because you can not re-add the record, and the database becomes corrupt. This patch will search the login records for the seuser record and report an error. --- libsemanage/src/users_local.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) 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); -- 1.8.3.1