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_async_sudo.c | 34 ++++++++++----- src/providers/ldap/sdap_sudo.c | 5 ++- src/providers/ldap/sdap_sudo.h | 6 ++- src/providers/ldap/sdap_sudo_cache.c | 84 +++++++++++++++++++++++++++++++++--- src/providers/ldap/sdap_sudo_cache.h | 6 ++- 5 files changed, 113 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c index 081ed20c4..8ed216b15 100644 --- a/src/providers/ldap/sdap_async_sudo.c +++ b/src/providers/ldap/sdap_async_sudo.c @@ -47,6 +47,7 @@ struct sdap_sudo_refresh_state { int dp_error; int error; + char *highest_usn; }; struct sdap_sudo_load_sudoers_state { @@ -84,12 +85,14 @@ static int sdap_sudo_load_sudoers_recv(struct tevent_req *req, static void sdap_sudo_load_sudoers_done(struct tevent_req *subreq); -static int sdap_sudo_store_sudoers(struct sysdb_ctx *sysdb_ctx, +static int sdap_sudo_store_sudoers(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb_ctx, struct sdap_options *opts, size_t rules_count, struct sysdb_attrs **rules, int cache_timeout, - time_t now); + time_t now, + char **_usn); struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, @@ -123,6 +126,7 @@ struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx, state->sysdb_filter = talloc_strdup(state, sysdb_filter); state->dp_error = DP_ERR_OK; state->error = EOK; + state->highest_usn = NULL; if (state->ldap_filter == NULL) { ret = ENOMEM; @@ -151,9 +155,11 @@ immediately: return req; } -int sdap_sudo_refresh_recv(struct tevent_req *req, +int sdap_sudo_refresh_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, int *dp_error, - int *error) + int *error, + char **usn) { struct sdap_sudo_refresh_state *state = NULL; @@ -164,6 +170,10 @@ int sdap_sudo_refresh_recv(struct tevent_req *req, *dp_error = state->dp_error; *error = state->error; + if (usn != NULL && state->highest_usn != NULL) { + *usn = talloc_steal(mem_ctx, state->highest_usn); + } + return EOK; } @@ -472,8 +482,9 @@ static void sdap_sudo_load_sudoers_done(struct tevent_req *subreq) /* store rules */ now = time(NULL); - ret = sdap_sudo_store_sudoers(state->sysdb, state->opts, rules_count, rules, - state->domain->sudo_timeout, now); + ret = sdap_sudo_store_sudoers(state, state->sysdb, state->opts, rules_count, + rules, state->domain->sudo_timeout, now, + &state->highest_usn); if (ret != EOK) { goto done; } @@ -506,12 +517,14 @@ done: } } -static int sdap_sudo_store_sudoers(struct sysdb_ctx *sysdb_ctx, +static int sdap_sudo_store_sudoers(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb_ctx, struct sdap_options *opts, size_t rules_count, struct sysdb_attrs **rules, int cache_timeout, - time_t now) + time_t now, + char **_usn) { errno_t ret; @@ -520,8 +533,9 @@ static int sdap_sudo_store_sudoers(struct sysdb_ctx *sysdb_ctx, return EOK; } - ret = sdap_save_native_sudorule_list(sysdb_ctx, opts->sudorule_map, - rules, rules_count, cache_timeout, now); + ret = sdap_save_native_sudorule_list(mem_ctx, sysdb_ctx, opts->sudorule_map, + rules, rules_count, cache_timeout, now, + _usn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("failed to save sudo rules [%d]: %s\n", ret, strerror(ret))); diff --git a/src/providers/ldap/sdap_sudo.c b/src/providers/ldap/sdap_sudo.c index 06d359b78..8ce33a088 100644 --- a/src/providers/ldap/sdap_sudo.c +++ b/src/providers/ldap/sdap_sudo.c @@ -328,7 +328,8 @@ static void sdap_sudo_full_refresh_done(struct tevent_req *subreq) req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_sudo_full_refresh_state); - ret = sdap_sudo_refresh_recv(subreq, &state->dp_error, &state->error); + ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error, + &state->error, NULL); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); @@ -430,7 +431,7 @@ static int sdap_sudo_rules_refresh_recv(struct tevent_req *req, int *dp_error, int *error) { - return sdap_sudo_refresh_recv(req, dp_error, error); + return sdap_sudo_refresh_recv(req, req, dp_error, error, NULL); } static void sdap_sudo_periodical_full_refresh_done(struct tevent_req *req) diff --git a/src/providers/ldap/sdap_sudo.h b/src/providers/ldap/sdap_sudo.h index 0c3001842..7c5fccc35 100644 --- a/src/providers/ldap/sdap_sudo.h +++ b/src/providers/ldap/sdap_sudo.h @@ -36,9 +36,11 @@ struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx, const char *ldap_filter, const char *sysdb_filter); -int sdap_sudo_refresh_recv(struct tevent_req *req, +int sdap_sudo_refresh_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, int *dp_error, - int *error); + int *error, + char **usn); /* timer */ 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; } diff --git a/src/providers/ldap/sdap_sudo_cache.h b/src/providers/ldap/sdap_sudo_cache.h index 146d38f2a..6413d2361 100644 --- a/src/providers/ldap/sdap_sudo_cache.h +++ b/src/providers/ldap/sdap_sudo_cache.h @@ -25,11 +25,13 @@ /* Cache functions specific for the native sudo LDAP schema */ 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); #endif /* _SDAP_SUDO_CACHE_H_ */ -- cgit