summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2012-10-23 14:09:50 +0200
committerJakub Hrozek <jhrozek@redhat.com>2012-10-24 17:28:03 +0200
commitfb67530ec34740a18f56ff56614898d2bdaee36f (patch)
treea78c4280cc601a171bda5898051b28da6953c7d1
parent672f430c2e5d55226261a281bc3fa77311ace5a4 (diff)
downloadsssd-fb67530ec34740a18f56ff56614898d2bdaee36f.tar.gz
sssd-fb67530ec34740a18f56ff56614898d2bdaee36f.tar.bz2
sssd-fb67530ec34740a18f56ff56614898d2bdaee36f.zip
sudo: do not fail if usn value is zero but full refresh is completed
https://fedorahosted.org/sssd/ticket/1596 In case that LDAP server contains zero sudo rules, the full refresh completes succussfully and stores current USN value (= 0). But then smart refresh will fail because it takes USN=0 as invalid value.
-rw-r--r--src/providers/ldap/sdap_sudo.c24
-rw-r--r--src/providers/ldap/sdap_sudo.h2
2 files changed, 19 insertions, 7 deletions
diff --git a/src/providers/ldap/sdap_sudo.c b/src/providers/ldap/sdap_sudo.c
index 5db0c613..f81fa673 100644
--- a/src/providers/ldap/sdap_sudo.c
+++ b/src/providers/ldap/sdap_sudo.c
@@ -31,6 +31,7 @@
#include "db/sysdb_sudo.h"
struct sdap_sudo_full_refresh_state {
+ struct sdap_sudo_ctx *sudo_ctx;
struct sdap_id_ctx *id_ctx;
struct sysdb_ctx *sysdb;
int dp_error;
@@ -128,6 +129,10 @@ int sdap_sudo_init(struct be_ctx *be_ctx,
*ops = &sdap_sudo_ops;
*pvt_data = sudo_ctx;
+ /* we didn't do any full refresh now,
+ * so we don't have current usn values available */
+ sudo_ctx->full_refresh_done = false;
+
ret = ldap_get_sudo_options(id_ctx, be_ctx->cdb,
be_ctx->conf_path, id_ctx->opts,
&sudo_ctx->use_host_filter,
@@ -532,6 +537,7 @@ static struct tevent_req *sdap_sudo_full_refresh_send(TALLOC_CTX *mem_ctx,
return NULL;
}
+ state->sudo_ctx = sudo_ctx;
state->id_ctx = id_ctx;
state->sysdb = id_ctx->be->sysdb;
@@ -606,6 +612,8 @@ static void sdap_sudo_full_refresh_done(struct tevent_req *subreq)
return;
}
+ state->sudo_ctx->full_refresh_done = true;
+
/* save the time in the sysdb */
ret = sysdb_sudo_set_last_full_refresh(state->sysdb, time(NULL));
if (ret != EOK) {
@@ -810,6 +818,7 @@ static struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
struct sdap_sudo_smart_refresh_state *state = NULL;
char *ldap_filter = NULL;
char *ldap_full_filter = NULL;
+ const char *usn;
int ret;
req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_smart_refresh_state);
@@ -818,9 +827,11 @@ static struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- if (srv_opts == NULL || srv_opts->max_sudo_value == 0) {
- /* Perform full refresh */
- DEBUG(SSSDBG_TRACE_FUNC, ("USN value is unknown!\n"));
+ if (!sudo_ctx->full_refresh_done
+ && (srv_opts == NULL || srv_opts->max_sudo_value == 0)) {
+ /* Perform full refresh first */
+ DEBUG(SSSDBG_TRACE_FUNC, ("USN value is unknown, "
+ "waiting for full refresh!\n"));
ret = EINVAL;
goto immediately;
}
@@ -829,12 +840,11 @@ static struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
state->sysdb = id_ctx->be->sysdb;
/* Download all rules from LDAP that are newer than usn */
+ usn = srv_opts->max_sudo_value == NULL ? "0" : srv_opts->max_sudo_value;
ldap_filter = talloc_asprintf(state, "(&(objectclass=%s)(%s>=%s)(!(%s=%s)))",
map[SDAP_OC_SUDORULE].name,
- map[SDAP_AT_SUDO_USN].name,
- srv_opts->max_sudo_value,
- map[SDAP_AT_SUDO_USN].name,
- srv_opts->max_sudo_value);
+ map[SDAP_AT_SUDO_USN].name, usn,
+ map[SDAP_AT_SUDO_USN].name, usn);
if (ldap_filter == NULL) {
ret = ENOMEM;
goto immediately;
diff --git a/src/providers/ldap/sdap_sudo.h b/src/providers/ldap/sdap_sudo.h
index d2c5e80f..f9988d61 100644
--- a/src/providers/ldap/sdap_sudo.h
+++ b/src/providers/ldap/sdap_sudo.h
@@ -29,6 +29,8 @@ struct sdap_sudo_ctx {
bool include_netgroups;
bool include_regexp;
bool use_host_filter;
+
+ bool full_refresh_done;
};
/* Common functions from ldap_sudo.c */