From 85abff7f43e8006de2c2fa35612884d377b9a036 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 26 Nov 2010 13:59:32 -0500 Subject: ldap: Use USN entries if available. Otherwise fallback to the default modifyTimestamp indicator --- src/config/etc/sssd.api.d/sssd-ipa.conf | 2 + src/config/etc/sssd.api.d/sssd-ldap.conf | 2 + src/providers/ipa/ipa_common.c | 4 +- src/providers/ldap/ldap_common.c | 8 +- src/providers/ldap/ldap_common.h | 3 +- src/providers/ldap/ldap_id_enum.c | 51 ++++++----- src/providers/ldap/sdap.c | 58 ++++++++++++- src/providers/ldap/sdap.h | 7 ++ src/providers/ldap/sdap_async_accounts.c | 144 +++++++++++++++++++------------ src/providers/ldap/sdap_id_op.c | 3 +- 10 files changed, 193 insertions(+), 89 deletions(-) (limited to 'src') 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, ×tamp); + 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, ×tamp); + 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, ×tamp); + 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, ×tamp); + (!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) { -- cgit