From f143937efc6cbb1eb84042979c83dd5b3f23a40c Mon Sep 17 00:00:00 2001 From: Pavel Březina Date: Mon, 7 May 2012 17:08:20 +0200 Subject: sudo ldap provider: find highest USN --- src/providers/ldap/sdap_sudo_cache.c | 84 +++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 6 deletions(-) (limited to 'src/providers/ldap/sdap_sudo_cache.c') diff --git a/src/providers/ldap/sdap_sudo_cache.c b/src/providers/ldap/sdap_sudo_cache.c index 39b028d66..499db02f6 100644 --- a/src/providers/ldap/sdap_sudo_cache.c +++ b/src/providers/ldap/sdap_sudo_cache.c @@ -18,17 +18,50 @@ along with this program. If not, see . */ +#include + #include "db/sysdb.h" #include "db/sysdb_sudo.h" #include "providers/ldap/sdap_sudo_cache.h" /* ========== Functions specific for the native sudo LDAP schema ========== */ +static errno_t sdap_sudo_get_usn(TALLOC_CTX *mem_ctx, + struct sysdb_attrs *attrs, + struct sdap_attr_map *map, + const char *name, + char **_usn) +{ + const char *usn; + errno_t ret; + + if (_usn == NULL) { + return EINVAL; + } + + ret = sysdb_attrs_get_string(attrs, map[SDAP_AT_SUDO_USN].sys_name, &usn); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Failed to retrieve USN value: [%s]\n", strerror(ret))); + + return ret; + } + + *_usn = talloc_strdup(mem_ctx, usn); + if (*_usn == NULL) { + return ENOMEM; + } + + return EOK; +} + static errno_t -sdap_save_native_sudorule(struct sysdb_ctx *sysdb_ctx, +sdap_save_native_sudorule(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb_ctx, struct sdap_attr_map *map, struct sysdb_attrs *attrs, int cache_timeout, - time_t now) + time_t now, + char **_usn) { errno_t ret; const char *rule_name; @@ -49,6 +82,12 @@ sdap_save_native_sudorule(struct sysdb_ctx *sysdb_ctx, return ret; } + ret = sdap_sudo_get_usn(mem_ctx, attrs, map, rule_name, _usn); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not read USN from %s\n", rule_name)); + return ret; + } + ret = sysdb_save_sudorule(sysdb_ctx, rule_name, attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Could not save sudorule %s\n", rule_name)); @@ -59,17 +98,28 @@ sdap_save_native_sudorule(struct sysdb_ctx *sysdb_ctx, } errno_t -sdap_save_native_sudorule_list(struct sysdb_ctx *sysdb_ctx, +sdap_save_native_sudorule_list(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb_ctx, struct sdap_attr_map *map, struct sysdb_attrs **replies, size_t replies_count, int cache_timeout, - time_t now) + time_t now, + char **_usn) { + TALLOC_CTX *tmp_ctx = NULL; + char *higher_usn = NULL; + char *usn_value = NULL; errno_t ret, tret; bool in_transaction = false; size_t i; + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, ("talloc_new() failed\n")); + return ENOMEM; + } + ret = sysdb_transaction_start(sysdb_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("Could not start transaction\n")); @@ -78,11 +128,27 @@ sdap_save_native_sudorule_list(struct sysdb_ctx *sysdb_ctx, in_transaction = true; for (i=0; i strlen(higher_usn)) || + (strcmp(usn_value, higher_usn) > 0)) { + talloc_zfree(higher_usn); + higher_usn = usn_value; + } else { + talloc_zfree(usn_value); + } + } else { + higher_usn = usn_value; + } + } } ret = sysdb_transaction_commit(sysdb_ctx); @@ -92,6 +158,10 @@ sdap_save_native_sudorule_list(struct sysdb_ctx *sysdb_ctx, } in_transaction = false; + if (higher_usn != NULL) { + *_usn = talloc_steal(mem_ctx, higher_usn); + } + ret = EOK; fail: if (in_transaction) { @@ -101,5 +171,7 @@ fail: } } + talloc_free(tmp_ctx); + return ret; } -- cgit