summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2012-05-07 17:08:20 +0200
committerStephen Gallagher <sgallagh@redhat.com>2012-06-29 11:37:17 -0400
commitf143937efc6cbb1eb84042979c83dd5b3f23a40c (patch)
tree85f43baea7ceb4396457717c1b95e05ec278095e
parentc8704f06db6dbbe39f50dfb35f20cdf27cf1f087 (diff)
downloadsssd-f143937efc6cbb1eb84042979c83dd5b3f23a40c.tar.gz
sssd-f143937efc6cbb1eb84042979c83dd5b3f23a40c.tar.bz2
sssd-f143937efc6cbb1eb84042979c83dd5b3f23a40c.zip
sudo ldap provider: find highest USN
-rw-r--r--src/providers/ldap/sdap_async_sudo.c34
-rw-r--r--src/providers/ldap/sdap_sudo.c5
-rw-r--r--src/providers/ldap/sdap_sudo.h6
-rw-r--r--src/providers/ldap/sdap_sudo_cache.c84
-rw-r--r--src/providers/ldap/sdap_sudo_cache.h6
5 files changed, 113 insertions, 22 deletions
diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c
index 081ed20c..8ed216b1 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 06d359b7..8ce33a08 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 0c300184..7c5fccc3 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 39b028d6..499db02f 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 <http://www.gnu.org/licenses/>.
*/
+#include <talloc.h>
+
#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<replies_count; i++) {
- ret = sdap_save_native_sudorule(sysdb_ctx, map, replies[i],
- cache_timeout, now);
+ usn_value = NULL;
+ ret = sdap_save_native_sudorule(tmp_ctx, sysdb_ctx, map, replies[i],
+ cache_timeout, now, &usn_value);
if (ret != EOK) {
goto fail;
}
+
+ /* find highest usn */
+ if (usn_value) {
+ if (higher_usn) {
+ if ((strlen(usn_value) > 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 146d38f2..6413d236 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_ */