summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2010-11-26 13:59:32 -0500
committerStephen Gallagher <sgallagh@redhat.com>2010-12-07 17:09:19 -0500
commit85abff7f43e8006de2c2fa35612884d377b9a036 (patch)
tree84e36f7e4d1eb807c4bc2d77b74cd755275d7973
parent1d9eec9e868fbc2d996f1030a43675be9a840133 (diff)
downloadsssd-85abff7f43e8006de2c2fa35612884d377b9a036.tar.gz
sssd-85abff7f43e8006de2c2fa35612884d377b9a036.tar.xz
sssd-85abff7f43e8006de2c2fa35612884d377b9a036.zip
ldap: Use USN entries if available.
Otherwise fallback to the default modifyTimestamp indicator
-rw-r--r--src/config/etc/sssd.api.d/sssd-ipa.conf2
-rw-r--r--src/config/etc/sssd.api.d/sssd-ldap.conf2
-rw-r--r--src/providers/ipa/ipa_common.c4
-rw-r--r--src/providers/ldap/ldap_common.c8
-rw-r--r--src/providers/ldap/ldap_common.h3
-rw-r--r--src/providers/ldap/ldap_id_enum.c51
-rw-r--r--src/providers/ldap/sdap.c58
-rw-r--r--src/providers/ldap/sdap.h7
-rw-r--r--src/providers/ldap/sdap_async_accounts.c144
-rw-r--r--src/providers/ldap/sdap_id_op.c3
10 files changed, 193 insertions, 89 deletions
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 04b6632d5..7c1c35a2a 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -52,6 +52,7 @@ ldap_user_principal = str, None, false
ldap_user_fullname = str, None, false
ldap_user_member_of = str, None, false
ldap_user_modify_timestamp = str, None, false
+ldap_user_entry_usn = str, None, false
ldap_user_shadow_last_change = str, None, false
ldap_user_shadow_min = str, None, false
ldap_user_shadow_max = str, None, false
@@ -71,6 +72,7 @@ ldap_group_gid_number = str, None, false
ldap_group_member = str, None, false
ldap_group_uuid = str, None, false
ldap_group_modify_timestamp = str, None, false
+ldap_group_entry_usn = str, None, false
ldap_force_upper_case_realm = bool, None, false
ldap_group_nesting_level = int, None, false
ldap_netgroup_search_base = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
index 2d44fb4ba..66f55275a 100644
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
@@ -45,6 +45,7 @@ ldap_user_principal = str, None, false
ldap_user_fullname = str, None, false
ldap_user_member_of = str, None, false
ldap_user_modify_timestamp = str, None, false
+ldap_user_entry_usn = str, None, false
ldap_user_shadow_last_change = str, None, false
ldap_user_shadow_min = str, None, false
ldap_user_shadow_max = str, None, false
@@ -64,6 +65,7 @@ ldap_group_gid_number = str, None, false
ldap_group_member = str, None, false
ldap_group_uuid = str, None, false
ldap_group_modify_timestamp = str, None, false
+ldap_group_entry_usn = str, None, false
ldap_group_nesting_level = int, None, false
ldap_force_upper_case_realm = bool, None, false
ldap_netgroup_search_base = str, None, false
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index 35583af21..346fcb384 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -103,6 +103,7 @@ struct sdap_attr_map ipa_user_map[] = {
{ "ldap_user_member_of", "memberOf", SYSDB_MEMBEROF, NULL },
{ "ldap_user_uuid", "nsUniqueId", SYSDB_UUID, NULL },
{ "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
+ { "ldap_user_entry_usn", NULL, SYSDB_USN, NULL },
{ "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL },
{ "ldap_user_shadow_min", "shadowMin", SYSDB_SHADOWPW_MIN, NULL },
{ "ldap_user_shadow_max", "shadowMax", SYSDB_SHADOWPW_MAX, NULL },
@@ -122,7 +123,8 @@ struct sdap_attr_map ipa_group_map[] = {
{ "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
{ "ldap_group_member", "member", SYSDB_MEMBER, NULL },
{ "ldap_group_uuid", "nsUniqueId", SYSDB_UUID, NULL },
- { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }
+ { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
+ { "ldap_group_entry_usn", NULL, SYSDB_USN, NULL }
};
struct sdap_attr_map ipa_netgroup_map[] = {
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index 5e2572b87..4d9fabc4e 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -108,6 +108,7 @@ struct sdap_attr_map rfc2307_user_map[] = {
{ "ldap_user_member_of", NULL, SYSDB_MEMBEROF, NULL },
{ "ldap_user_uuid", NULL, SYSDB_UUID, NULL },
{ "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
+ { "ldap_user_entry_usn", NULL, SYSDB_USN, NULL },
{ "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL },
{ "ldap_user_shadow_min", "shadowMin", SYSDB_SHADOWPW_MIN, NULL },
{ "ldap_user_shadow_max", "shadowMax", SYSDB_SHADOWPW_MAX, NULL },
@@ -127,7 +128,8 @@ struct sdap_attr_map rfc2307_group_map[] = {
{ "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
{ "ldap_group_member", "memberuid", SYSDB_MEMBER, NULL },
{ "ldap_group_uuid", NULL, SYSDB_UUID, NULL },
- { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }
+ { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
+ { "ldap_group_entry_usn", NULL, SYSDB_USN, NULL }
};
struct sdap_attr_map rfc2307bis_user_map[] = {
@@ -145,6 +147,7 @@ struct sdap_attr_map rfc2307bis_user_map[] = {
/* FIXME: this is 389ds specific */
{ "ldap_user_uuid", "nsUniqueId", SYSDB_UUID, NULL },
{ "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
+ { "ldap_user_entry_usn", NULL, SYSDB_USN, NULL },
{ "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL },
{ "ldap_user_shadow_min", "shadowMin", SYSDB_SHADOWPW_MIN, NULL },
{ "ldap_user_shadow_max", "shadowMax", SYSDB_SHADOWPW_MAX, NULL },
@@ -165,7 +168,8 @@ struct sdap_attr_map rfc2307bis_group_map[] = {
{ "ldap_group_member", "member", SYSDB_MEMBER, NULL },
/* FIXME: this is 389ds specific */
{ "ldap_group_uuid", "nsUniqueId", SYSDB_UUID, NULL },
- { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }
+ { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
+ { "ldap_group_entry_usn", NULL, SYSDB_USN, NULL }
};
struct sdap_attr_map netgroup_map[] = {
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index f6b5c1182..8f25e4232 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -54,8 +54,7 @@ struct sdap_id_ctx {
/* cleanup loop timer */
struct timeval last_purge;
- char *max_user_timestamp;
- char *max_group_timestamp;
+ struct sdap_server_opts *srv_opts;
};
struct sdap_auth_ctx {
diff --git a/src/providers/ldap/ldap_id_enum.c b/src/providers/ldap/ldap_id_enum.c
index d60519213..f2ac8c6a9 100644
--- a/src/providers/ldap/ldap_id_enum.c
+++ b/src/providers/ldap/ldap_id_enum.c
@@ -426,16 +426,15 @@ static struct tevent_req *enum_users_send(TALLOC_CTX *memctx,
state->ctx = ctx;
state->op = op;
- if (ctx->max_user_timestamp && !purge) {
-
+ if (ctx->srv_opts && ctx->srv_opts->max_user_value && !purge) {
state->filter = talloc_asprintf(state,
"(&(%s=*)(objectclass=%s)(%s>=%s)(!(%s=%s)))",
ctx->opts->user_map[SDAP_AT_USER_NAME].name,
ctx->opts->user_map[SDAP_OC_USER].name,
- ctx->opts->user_map[SDAP_AT_USER_MODSTAMP].name,
- ctx->max_user_timestamp,
- ctx->opts->user_map[SDAP_AT_USER_MODSTAMP].name,
- ctx->max_user_timestamp);
+ ctx->opts->user_map[SDAP_AT_USER_USN].name,
+ ctx->srv_opts->max_user_value,
+ ctx->opts->user_map[SDAP_AT_USER_USN].name,
+ ctx->srv_opts->max_user_value);
} else {
state->filter = talloc_asprintf(state,
"(&(%s=*)(objectclass=%s))",
@@ -479,23 +478,23 @@ static void enum_users_op_done(struct tevent_req *subreq)
struct tevent_req);
struct enum_users_state *state = tevent_req_data(req,
struct enum_users_state);
- char *timestamp;
+ char *usn_value;
int ret;
- ret = sdap_get_users_recv(subreq, state, &timestamp);
+ ret = sdap_get_users_recv(subreq, state, &usn_value);
talloc_zfree(subreq);
if (ret) {
tevent_req_error(req, ret);
return;
}
- if (timestamp) {
- talloc_zfree(state->ctx->max_user_timestamp);
- state->ctx->max_user_timestamp = talloc_steal(state->ctx, timestamp);
+ if (usn_value) {
+ talloc_zfree(state->ctx->srv_opts->max_user_value);
+ state->ctx->srv_opts->max_user_value = talloc_steal(state->ctx, usn_value);
}
- DEBUG(4, ("Users higher timestamp: [%s]\n",
- state->ctx->max_user_timestamp));
+ DEBUG(4, ("Users higher USN value: [%s]\n",
+ state->ctx->srv_opts->max_user_value));
tevent_req_done(req);
}
@@ -530,16 +529,15 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
state->ctx = ctx;
state->op = op;
- if (ctx->max_group_timestamp && !purge) {
-
+ if (ctx->srv_opts && ctx->srv_opts->max_group_value && !purge) {
state->filter = talloc_asprintf(state,
"(&(%s=*)(objectclass=%s)(%s>=%s)(!(%s=%s)))",
ctx->opts->group_map[SDAP_AT_GROUP_NAME].name,
ctx->opts->group_map[SDAP_OC_GROUP].name,
- ctx->opts->group_map[SDAP_AT_GROUP_MODSTAMP].name,
- ctx->max_group_timestamp,
- ctx->opts->group_map[SDAP_AT_GROUP_MODSTAMP].name,
- ctx->max_group_timestamp);
+ ctx->opts->group_map[SDAP_AT_GROUP_USN].name,
+ ctx->srv_opts->max_group_value,
+ ctx->opts->group_map[SDAP_AT_GROUP_USN].name,
+ ctx->srv_opts->max_group_value);
} else {
state->filter = talloc_asprintf(state,
"(&(%s=*)(objectclass=%s))",
@@ -582,23 +580,24 @@ static void enum_groups_op_done(struct tevent_req *subreq)
struct tevent_req);
struct enum_groups_state *state = tevent_req_data(req,
struct enum_groups_state);
- char *timestamp;
+ char *usn_value;
int ret;
- ret = sdap_get_groups_recv(subreq, state, &timestamp);
+ ret = sdap_get_groups_recv(subreq, state, &usn_value);
talloc_zfree(subreq);
if (ret) {
tevent_req_error(req, ret);
return;
}
- if (timestamp) {
- talloc_zfree(state->ctx->max_group_timestamp);
- state->ctx->max_group_timestamp = talloc_steal(state->ctx, timestamp);
+ if (usn_value) {
+ talloc_zfree(state->ctx->srv_opts->max_group_value);
+ state->ctx->srv_opts->max_group_value =
+ talloc_steal(state->ctx, usn_value);
}
- DEBUG(4, ("Groups higher timestamp: [%s]\n",
- state->ctx->max_group_timestamp));
+ DEBUG(4, ("Groups higher USN value: [%s]\n",
+ state->ctx->srv_opts->max_group_value));
tevent_req_done(req);
}
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index ffe625b3b..1735ac520 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -22,6 +22,7 @@
#define LDAP_DEPRECATED 1
#include "util/util.h"
#include "confdb/confdb.h"
+#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap.h"
/* =Retrieve-Options====================================================== */
@@ -540,6 +541,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
{ NULL, NULL } };
const char *last_usn_name;
const char *last_usn_value;
+ const char *entry_usn_name;
int ret;
int i;
@@ -554,6 +556,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
}
last_usn_name = opts->gen_map[SDAP_AT_LAST_USN].name;
+ entry_usn_name = opts->gen_map[SDAP_AT_ENTRY_USN].name;
if (last_usn_name) {
ret = sysdb_attrs_get_string(rootdse,
last_usn_name, &last_usn_value);
@@ -571,8 +574,6 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
DEBUG(1, ("Unkown error (%d) checking rootdse!\n", ret));
}
} else {
- const char *entry_usn_name;
- entry_usn_name = opts->gen_map[SDAP_AT_ENTRY_USN].name;
if (!entry_usn_name) {
DEBUG(1, ("%s found in rootdse but %s is not set!\n",
last_usn_name,
@@ -601,13 +602,53 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
}
if (!last_usn_name) {
- DEBUG(5, ("No known USN scheme is supported by this server\n!"));
+ DEBUG(5, ("No known USN scheme is supported by this server!\n"));
+ if (!entry_usn_name) {
+ DEBUG(5, ("Will use modification timestamp as usn!\n"));
+ opts->gen_map[SDAP_AT_ENTRY_USN].name =
+ talloc_strdup(opts->gen_map, "modifyTimestamp");
+ }
+ }
+
+ if (!opts->user_map[SDAP_AT_USER_USN].name) {
+ opts->user_map[SDAP_AT_USER_USN].name =
+ talloc_strdup(opts->user_map,
+ opts->gen_map[SDAP_AT_ENTRY_USN].name);
+ }
+ if (!opts->group_map[SDAP_AT_GROUP_USN].name) {
+ opts->group_map[SDAP_AT_GROUP_USN].name =
+ talloc_strdup(opts->group_map,
+ opts->gen_map[SDAP_AT_ENTRY_USN].name);
}
*srv_opts = so;
return EOK;
}
+void sdap_steal_server_opts(struct sdap_id_ctx *id_ctx,
+ struct sdap_server_opts **srv_opts)
+{
+ if (!id_ctx || !srv_opts || !*srv_opts) {
+ return;
+ }
+
+ if (!id_ctx->srv_opts) {
+ id_ctx->srv_opts = talloc_move(id_ctx, srv_opts);
+ return;
+ }
+
+ /* discard if same as previous so we do not reset max usn values
+ * unnecessarily */
+ if (strcmp(id_ctx->srv_opts->server_id, (*srv_opts)->server_id) == 0) {
+ talloc_zfree(*srv_opts);
+ return;
+ }
+
+ talloc_zfree(id_ctx->srv_opts);
+ id_ctx->srv_opts = talloc_move(id_ctx, srv_opts);
+}
+
+
int build_attrs_from_map(TALLOC_CTX *memctx,
struct sdap_attr_map *map,
size_t size, const char ***_attrs)
@@ -636,6 +677,17 @@ int build_attrs_from_map(TALLOC_CTX *memctx,
return EOK;
}
+int append_attrs_to_array(const char **attrs, size_t size, const char *attr)
+{
+ attrs = talloc_realloc(NULL, attrs, const char *, size + 2);
+ if (!attrs) return ENOMEM;
+
+ attrs[size] = attr;
+ attrs[size + 1] = NULL;
+
+ return EOK;
+}
+
int sdap_control_create(struct sdap_handle *sh, const char *oid, int iscritical,
struct berval *value, int dupval, LDAPControl **ctrlp)
{
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 68242f1a6..83bfd21b4 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -218,6 +218,7 @@ enum sdap_user_attrs {
SDAP_AT_USER_MEMBEROF,
SDAP_AT_USER_UUID,
SDAP_AT_USER_MODSTAMP,
+ SDAP_AT_USER_USN,
SDAP_AT_SP_LSTCHG,
SDAP_AT_SP_MIN,
SDAP_AT_SP_MAX,
@@ -244,6 +245,7 @@ enum sdap_group_attrs {
SDAP_AT_GROUP_MEMBER,
SDAP_AT_GROUP_UUID,
SDAP_AT_GROUP_MODSTAMP,
+ SDAP_AT_GROUP_USN,
SDAP_OPTS_GROUP /* attrs counter */
};
@@ -292,6 +294,8 @@ struct sdap_server_opts {
char *max_group_value;
};
+struct sdap_id_ctx;
+
int sdap_get_map(TALLOC_CTX *memctx,
struct confdb_ctx *cdb,
const char *conf_path,
@@ -333,6 +337,7 @@ bool sdap_check_sup_list(struct sup_list *l, const char *val);
int build_attrs_from_map(TALLOC_CTX *memctx,
struct sdap_attr_map *map,
size_t size, const char ***_attrs);
+int append_attrs_to_array(const char **attrs, size_t size, const char *attr);
int sdap_control_create(struct sdap_handle *sh, const char *oid, int iscritical,
struct berval *value, int dupval, LDAPControl **ctrlp);
@@ -345,4 +350,6 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
struct sysdb_attrs *rootdse,
struct sdap_options *opts,
struct sdap_server_opts **srv_opts);
+void sdap_steal_server_opts(struct sdap_id_ctx *id_ctx,
+ struct sdap_server_opts **srv_opts);
#endif /* _SDAP_H_ */
diff --git a/src/providers/ldap/sdap_async_accounts.c b/src/providers/ldap/sdap_async_accounts.c
index 9856e7548..004c69aff 100644
--- a/src/providers/ldap/sdap_async_accounts.c
+++ b/src/providers/ldap/sdap_async_accounts.c
@@ -34,7 +34,7 @@ static int sdap_save_user(TALLOC_CTX *memctx,
struct sss_domain_info *dom,
struct sysdb_attrs *attrs,
bool is_initgr,
- char **_timestamp)
+ char **_usn_value)
{
struct ldb_message_element *el;
int ret;
@@ -50,7 +50,7 @@ static int sdap_save_user(TALLOC_CTX *memctx,
int i;
char *val = NULL;
int cache_timeout;
- char *timestamp = NULL;
+ char *usn_value = NULL;
DEBUG(9, ("Save user\n"));
@@ -181,8 +181,25 @@ static int sdap_save_user(TALLOC_CTX *memctx,
if (ret) {
goto fail;
}
- timestamp = talloc_strdup(memctx, (const char*)el->values[0].data);
- if (!timestamp) {
+ }
+
+ ret = sysdb_attrs_get_el(attrs,
+ opts->user_map[SDAP_AT_USER_USN].sys_name, &el);
+ if (ret) {
+ goto fail;
+ }
+ if (el->num_values == 0) {
+ DEBUG(7, ("Original USN value is not available for [%s].\n",
+ name));
+ } else {
+ ret = sysdb_attrs_add_string(user_attrs,
+ opts->user_map[SDAP_AT_USER_USN].sys_name,
+ (const char*)el->values[0].data);
+ if (ret) {
+ goto fail;
+ }
+ usn_value = talloc_strdup(memctx, (const char*)el->values[0].data);
+ if (!usn_value) {
ret = ENOMEM;
goto fail;
}
@@ -252,8 +269,8 @@ static int sdap_save_user(TALLOC_CTX *memctx,
user_attrs, cache_timeout);
if (ret) goto fail;
- if (_timestamp) {
- *_timestamp = timestamp;
+ if (_usn_value) {
+ *_usn_value = usn_value;
}
return EOK;
@@ -272,11 +289,11 @@ static int sdap_save_users(TALLOC_CTX *memctx,
struct sdap_options *opts,
struct sysdb_attrs **users,
int num_users,
- char **_timestamp)
+ char **_usn_value)
{
TALLOC_CTX *tmpctx;
- char *higher_timestamp = NULL;
- char *timestamp;
+ char *higher_usn = NULL;
+ char *usn_value;
int ret;
int i;
@@ -296,10 +313,10 @@ static int sdap_save_users(TALLOC_CTX *memctx,
}
for (i = 0; i < num_users; i++) {
- timestamp = NULL;
+ usn_value = NULL;
ret = sdap_save_user(tmpctx, sysdb, opts, dom,
- users[i], false, &timestamp);
+ users[i], false, &usn_value);
/* Do not fail completely on errors.
* Just report the failure to save and go on */
@@ -309,16 +326,17 @@ static int sdap_save_users(TALLOC_CTX *memctx,
DEBUG(9, ("User %d processed!\n", i));
}
- if (timestamp) {
- if (higher_timestamp) {
- if (strcmp(timestamp, higher_timestamp) > 0) {
- talloc_zfree(higher_timestamp);
- higher_timestamp = timestamp;
+ 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(timestamp);
+ talloc_zfree(usn_value);
}
} else {
- higher_timestamp = timestamp;
+ higher_usn = usn_value;
}
}
}
@@ -329,8 +347,8 @@ static int sdap_save_users(TALLOC_CTX *memctx,
goto done;
}
- if (_timestamp) {
- *_timestamp = talloc_steal(memctx, higher_timestamp);
+ if (_usn_value) {
+ *_usn_value = talloc_steal(memctx, higher_usn);
}
done:
@@ -350,7 +368,7 @@ struct sdap_get_users_state {
const char **attrs;
const char *filter;
- char *higher_timestamp;
+ char *higher_usn;
struct sysdb_attrs **users;
size_t count;
};
@@ -379,7 +397,7 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx,
state->sysdb = sysdb;
state->filter = filter;
state->attrs = attrs;
- state->higher_timestamp = NULL;
+ state->higher_usn = NULL;
state->users = NULL;
state->count = 0;
@@ -424,7 +442,7 @@ static void sdap_get_users_process(struct tevent_req *subreq)
ret = sdap_save_users(state, state->sysdb,
state->dom, state->opts,
state->users, state->count,
- &state->higher_timestamp);
+ &state->higher_usn);
if (ret) {
DEBUG(2, ("Failed to store users.\n"));
tevent_req_error(req, ret);
@@ -437,15 +455,15 @@ static void sdap_get_users_process(struct tevent_req *subreq)
}
int sdap_get_users_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx, char **timestamp)
+ TALLOC_CTX *mem_ctx, char **usn_value)
{
struct sdap_get_users_state *state = tevent_req_data(req,
struct sdap_get_users_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
- if (timestamp) {
- *timestamp = talloc_steal(mem_ctx, state->higher_timestamp);
+ if (usn_value) {
+ *usn_value = talloc_steal(mem_ctx, state->higher_usn);
}
return EOK;
@@ -601,14 +619,14 @@ static int sdap_save_group(TALLOC_CTX *memctx,
struct sysdb_attrs *attrs,
bool store_members,
bool populate_members,
- char **_timestamp)
+ char **_usn_value)
{
struct ldb_message_element *el;
struct sysdb_attrs *group_attrs;
const char *name = NULL;
gid_t gid;
int ret;
- char *timestamp = NULL;
+ char *usn_value = NULL;
ret = sysdb_attrs_get_el(attrs,
opts->group_map[SDAP_AT_GROUP_NAME].sys_name, &el);
@@ -674,8 +692,25 @@ static int sdap_save_group(TALLOC_CTX *memctx,
if (ret) {
goto fail;
}
- timestamp = talloc_strdup(memctx, (const char*)el->values[0].data);
- if (!timestamp) {
+ }
+
+ ret = sysdb_attrs_get_el(attrs,
+ opts->group_map[SDAP_AT_GROUP_USN].sys_name, &el);
+ if (ret) {
+ goto fail;
+ }
+ if (el->num_values == 0) {
+ DEBUG(7, ("Original USN value is not available for [%s].\n",
+ name));
+ } else {
+ ret = sysdb_attrs_add_string(group_attrs,
+ opts->group_map[SDAP_AT_GROUP_USN].sys_name,
+ (const char*)el->values[0].data);
+ if (ret) {
+ goto fail;
+ }
+ usn_value = talloc_strdup(memctx, (const char*)el->values[0].data);
+ if (!usn_value) {
ret = ENOMEM;
goto fail;
}
@@ -721,8 +756,8 @@ static int sdap_save_group(TALLOC_CTX *memctx,
SDAP_ENTRY_CACHE_TIMEOUT));
if (ret) goto fail;
- if (_timestamp) {
- *_timestamp = timestamp;
+ if (_usn_value) {
+ *_usn_value = usn_value;
}
return EOK;
@@ -805,11 +840,11 @@ static int sdap_save_groups(TALLOC_CTX *memctx,
struct sysdb_attrs **groups,
int num_groups,
bool populate_members,
- char **_timestamp)
+ char **_usn_value)
{
TALLOC_CTX *tmpctx;
- char *higher_timestamp = NULL;
- char *timestamp;
+ char *higher_usn = NULL;
+ char *usn_value;
bool twopass;
int ret;
int i;
@@ -840,12 +875,12 @@ static int sdap_save_groups(TALLOC_CTX *memctx,
}
for (i = 0; i < num_groups; i++) {
- timestamp = NULL;
+ usn_value = NULL;
/* if 2 pass savemembers = false */
ret = sdap_save_group(tmpctx, sysdb,
opts, dom, groups[i],
- (!twopass), populate_members, &timestamp);
+ (!twopass), populate_members, &usn_value);
/* Do not fail completely on errors.
* Just report the failure to save and go on */
@@ -855,16 +890,17 @@ static int sdap_save_groups(TALLOC_CTX *memctx,
DEBUG(9, ("Group %d processed!\n", i));
}
- if (timestamp) {
- if (higher_timestamp) {
- if (strcmp(timestamp, higher_timestamp) > 0) {
- talloc_zfree(higher_timestamp);
- higher_timestamp = timestamp;
+ 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(timestamp);
+ talloc_zfree(usn_value);
}
} else {
- higher_timestamp = timestamp;
+ higher_usn = usn_value;
}
}
}
@@ -890,8 +926,8 @@ static int sdap_save_groups(TALLOC_CTX *memctx,
goto done;
}
- if (_timestamp) {
- *_timestamp = talloc_steal(memctx, higher_timestamp);
+ if (_usn_value) {
+ *_usn_value = talloc_steal(memctx, higher_usn);
}
done:
@@ -1431,7 +1467,7 @@ struct sdap_get_groups_state {
const char **attrs;
const char *filter;
- char *higher_timestamp;
+ char *higher_usn;
struct sysdb_attrs **groups;
size_t count;
size_t check_count;
@@ -1465,7 +1501,7 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
state->sysdb = sysdb;
state->filter = filter;
state->attrs = attrs;
- state->higher_timestamp = NULL;
+ state->higher_usn = NULL;
state->groups = NULL;
state->count = 0;
@@ -1604,7 +1640,7 @@ static void sdap_get_groups_done(struct tevent_req *subreq)
ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts,
state->groups, state->count, true,
- &state->higher_timestamp);
+ &state->higher_usn);
if (ret) {
DEBUG(2, ("Failed to store groups.\n"));
tevent_req_error(req, ret);
@@ -1616,15 +1652,15 @@ static void sdap_get_groups_done(struct tevent_req *subreq)
}
int sdap_get_groups_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx, char **timestamp)
+ TALLOC_CTX *mem_ctx, char **usn_value)
{
struct sdap_get_groups_state *state = tevent_req_data(req,
struct sdap_get_groups_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
- if (timestamp) {
- *timestamp = talloc_steal(mem_ctx, state->higher_timestamp);
+ if (usn_value) {
+ *usn_value = talloc_steal(mem_ctx, state->higher_usn);
}
return EOK;
@@ -1676,7 +1712,7 @@ static void sdap_nested_done(struct tevent_req *subreq)
* place for the groups to add them.
*/
ret = sdap_save_users(state, state->sysdb, state->dom, state->opts,
- users, count, &state->higher_timestamp);
+ users, count, &state->higher_usn);
if (ret != EOK) {
tevent_req_error(req, ret);
return;
@@ -1702,7 +1738,7 @@ static void sdap_nested_done(struct tevent_req *subreq)
talloc_zfree(values);
ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts,
- groups, count, false, &state->higher_timestamp);
+ groups, count, false, &state->higher_usn);
if (ret != EOK) {
tevent_req_error(req, ret);
return;
diff --git a/src/providers/ldap/sdap_id_op.c b/src/providers/ldap/sdap_id_op.c
index c4194efbc..c38a803ff 100644
--- a/src/providers/ldap/sdap_id_op.c
+++ b/src/providers/ldap/sdap_id_op.c
@@ -497,7 +497,7 @@ static void sdap_id_op_connect_done(struct tevent_req *subreq)
struct sdap_id_conn_data *conn_data =
tevent_req_callback_data(subreq, struct sdap_id_conn_data);
struct sdap_id_conn_cache *conn_cache = conn_data->conn_cache;
- struct sdap_server_opts *srv_opts;
+ struct sdap_server_opts *srv_opts = NULL;
bool can_retry = false;
bool is_offline = false;
int ret;
@@ -528,6 +528,7 @@ static void sdap_id_op_connect_done(struct tevent_req *subreq)
if (ret == EOK) {
ret = sdap_id_conn_data_set_expire_timer(conn_data);
+ sdap_steal_server_opts(conn_cache->id_ctx, &srv_opts);
}
if (can_retry) {