s3:winbindd: Improve performance of lookup_groupmem() in idmap_ad
authorPavel Filipenský <pfilipensky@samba.org>
Tue, 12 Mar 2024 12:20:24 +0000 (13:20 +0100)
committerJule Anger <janger@samba.org>
Wed, 17 Apr 2024 13:37:12 +0000 (13:37 +0000)
The LDAP query of lookup_groupmem() returns all group members from AD
even those with missing uidNumber.  Such group members are useless in
UNIX environment for idmap_ad backend since there is no uid mapping.

'test_user' is member of group "Domanin Users" with 200K members,
only 20K members have set uidNumber.

Without this fix:

$ time id test_user

real    1m5.946s
user    0m0.019s
sys     0m0.012s

With this fix:

$ time id test_user

real    0m3.544s
user    0m0.004s
sys     0m0.007s

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15605

Signed-off-by: Pavel Filipenský <pfilipensky@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 5d475d26a3d545f04791a04e85a06b8b192e3fcf)

source3/winbindd/winbindd_ads.c

index 7e572e5d41f48168925f8783947d253d76d2bc37..7d6324033ea2f0b8980cea7cb8fd58206dbce952 100644 (file)
@@ -1039,7 +1039,7 @@ static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
 }
 
 static NTSTATUS add_primary_group_members(
-       ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, uint32_t rid,
+       ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, uint32_t rid, const char *domname,
        char ***all_members, size_t *num_all_members)
 {
        char *filter;
@@ -1051,10 +1051,13 @@ static NTSTATUS add_primary_group_members(
        char **members;
        size_t num_members;
        ads_control args;
+       bool all_groupmem = idmap_config_bool(domname, "all_groupmem", false);
 
        filter = talloc_asprintf(
-               mem_ctx, "(&(objectCategory=user)(primaryGroupID=%u))",
-               (unsigned)rid);
+               mem_ctx,
+               "(&(objectCategory=user)(primaryGroupID=%u)%s)",
+               (unsigned)rid,
+               all_groupmem ? "" : "(uidNumber=*)(!(uidNumber=0))");
        if (filter == NULL) {
                goto done;
        }
@@ -1206,7 +1209,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 
        DEBUG(10, ("ads lookup_groupmem: got %d sids via extended dn call\n", (int)num_members));
 
-       status = add_primary_group_members(ads, mem_ctx, rid,
+       status = add_primary_group_members(ads, mem_ctx, rid, domain->name,
                                           &members, &num_members);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(10, ("%s: add_primary_group_members failed: %s\n",