From 4d6be3c36169c954c4d61399607fde229902cb07 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Wed, 26 Aug 2020 15:40:53 +0200 Subject: [PATCH] ldap: use member DN to create ghost user hash table --- src/db/sysdb.h | 1 + src/providers/ldap/sdap.c | 10 ++++++++++ src/providers/ldap/sdap_async_groups.c | 17 +++++++++++++++- src/providers/ldap/sdap_async_nested_groups.c | 20 +++++++++++++++++-- 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index a2bc8ed3b..679763bad 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -129,6 +129,7 @@ #define SYSDB_UPN "userPrincipalName" #define SYSDB_CANONICAL_UPN "canonicalUserPrincipalName" #define SYSDB_CCACHE_FILE "ccacheFile" +#define SYSDB_DN_FOR_MEMBER_HASH_TABLE "dnForMemberHashTable" #define SYSDB_ORIG_DN "originalDN" #define SYSDB_ORIG_MODSTAMP "originalModifyTimestamp" diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c index a9c8b92b8..a1a00df56 100644 --- a/src/providers/ldap/sdap.c +++ b/src/providers/ldap/sdap.c @@ -771,6 +771,16 @@ errno_t sdap_parse_deref(TALLOC_CTX *mem_ctx, goto done; } + /* The dereference control seems to return the DN from the dereference + * attribute (e.g. member) so we can use it as key for the hash table + * later. */ + ret = sysdb_attrs_add_string(res[mi]->attrs, + SYSDB_DN_FOR_MEMBER_HASH_TABLE, orig_dn); + if (ret) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); + goto done; + } + for (dval = dref->attrVals; dval != NULL; dval = dval->next) { DEBUG(SSSDBG_TRACE_INTERNAL, "Dereferenced attribute: %s\n", dval->type); diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c index abe2ed275..4e3c524a4 100644 --- a/src/providers/ldap/sdap_async_groups.c +++ b/src/providers/ldap/sdap_async_groups.c @@ -2509,6 +2509,7 @@ static errno_t sdap_nested_group_populate_users(TALLOC_CTX *mem_ctx, struct ldb_message_element *el; const char *username; const char *original_dn; + const char *hash_key_dn; struct sss_domain_info *user_dom; struct sdap_domain *sdap_dom; @@ -2607,8 +2608,22 @@ static errno_t sdap_nested_group_populate_users(TALLOC_CTX *mem_ctx, SYSDB_MOD_REP); if (ret != EOK) goto done; } else { + /* The DN of the user object and the DN in the member attribute + * might differ, e.g. in case. Since we later search the hash with + * DNs from the member attribute we should try to use DN from the + * member attribute here as well. This should be added earlier in + * the SYSDB_DN_FOR_MEMBER_HASH_TABLE attribute. If this does not + * exists we fall-back to original_dn which should work in the + * most cases as well. */ + ret = sysdb_attrs_get_string(users[i], + SYSDB_DN_FOR_MEMBER_HASH_TABLE, + &hash_key_dn); + if (ret != EOK) { + hash_key_dn = original_dn; + } + key.type = HASH_KEY_STRING; - key.str = talloc_steal(ghosts, discard_const(original_dn)); + key.str = talloc_steal(ghosts, discard_const(hash_key_dn)); value.type = HASH_VALUE_PTR; /* Already qualified from sdap_get_user_primary_name() */ value.ptr = talloc_steal(ghosts, discard_const(username)); diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c index 055de29ca..635b46403 100644 --- a/src/providers/ldap/sdap_async_nested_groups.c +++ b/src/providers/ldap/sdap_async_nested_groups.c @@ -241,9 +241,12 @@ static errno_t sdap_nested_group_hash_entry(hash_table_t *table, const char *name = NULL; errno_t ret; - ret = sysdb_attrs_get_string(entry, SYSDB_ORIG_DN, &name); + ret = sysdb_attrs_get_string(entry, SYSDB_DN_FOR_MEMBER_HASH_TABLE, &name); if (ret != EOK) { - return ret; + ret = sysdb_attrs_get_string(entry, SYSDB_ORIG_DN, &name); + if (ret != EOK) { + return ret; + } } return sdap_nested_group_hash_insert(table, name, entry, false, table_name); @@ -1495,6 +1498,19 @@ sdap_nested_group_single_step_process(struct tevent_req *subreq) } } + /* The original DN of the user object itself might differ from the one + * used inthe member attribute, e.g. different case. To make sure if + * can be found in a hash table when iterating over group members the + * DN from the member attribute used for the search as saved as well. + */ + ret = sysdb_attrs_add_string(entry, + SYSDB_DN_FOR_MEMBER_HASH_TABLE, + state->current_member->dn); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); + goto done; + } + /* save user in hash table */ ret = sdap_nested_group_hash_user(state->group_ctx, entry); if (ret == EEXIST) { -- 2.21.3