LDAP Sync Nested Groups vs Separate Containers
I have an Active Directory domain that looks something like this:
ADUC
|-example.com
||-OU1
|||-Group3
|||-Group4
|||-User12
||-Users
|||-Group1
|||-Group2
|||-User01 (through User11)
|||-SyncAcct
Potentially relevant bits of multiOTP the config follow:
ldap_base_dn=DC=example,DC=com
ldap_bind_dn=CN=SyncAcct,CN=Users,DC=example,DC=com
ldap_in_group=Group1
Other ldap settings follow https://github.com/multiOTP/multiotp/wiki/#how-to-configure-multiotp-to-synchronized-the-users-from-an-active-directory-
Because the wiki doesn't mention it or show a confifg option for it, the config also includes this:
ldap_recursive_groups=1
Group2, Group3, and Group4 are members of Group1
User01 through User11 are members of Group2
User12 is a member of Group3
Group4 is empty
Whenever I run an LDAP sync, User01 through User11 match up, but User12 does not. When I use ldapsearch with the SyncAcct to check User01, I see the Group2 membership and Group1 is not shown. When I do the same to check Group2, I see the Group1 membership. When I do the same with User12, I see the Group3 membership, and when I do the same with Group3, I see the Group1 membership. This tells me that the account is able to see what it needs to see. I believe this behavior may be considered buggy, so I wanted to post this even though I will be attempting to work around it with configuration changes.
While I don't see any potential value here (short of potential changes to improve future debug output), the LDAP sync debug looks like this:
2026-06-10 18:57:01 debug LDAP Debug: *AD/LDAP synchronization started at 18:57:01 / Memory used: 0.4MB / Peak: 0.4MB 0 d168e776792d 127.0.0.1
2026-06-10 18:57:01 info LDAP Info: AD/LDAP synchronization started 0 d168e776792d 127.0.0.1
2026-06-10 18:57:01 debug System Debug: *LDAP cache folder value: /tmp/.ldap_cache/ 0 d168e776792d 127.0.0.1
2026-06-10 18:57:02 info LDAP Info: No update for the 11 LDAP synced users, based on 11 LDAP entries (processed in 00:00:01) 0 d168e776792d 127.0.0.1
2026-06-10 18:57:02 debug Debug Debug: *19 INFO: Requested operation successfully done 0 d168e776792d 127.0.0.1
ADUC
|-example.com
||-OU1
|||-Group3
|||-Group4
|||-User12
||-Users
|||-Group1
|||-Group2
|||-User01 (through User11)
|||-SyncAcct
Potentially relevant bits of multiOTP the config follow:
ldap_base_dn=DC=example,DC=com
ldap_bind_dn=CN=SyncAcct,CN=Users,DC=example,DC=com
ldap_in_group=Group1
Other ldap settings follow https://github.com/multiOTP/multiotp/wiki/#how-to-configure-multiotp-to-synchronized-the-users-from-an-active-directory-
Because the wiki doesn't mention it or show a confifg option for it, the config also includes this:
ldap_recursive_groups=1
Group2, Group3, and Group4 are members of Group1
User01 through User11 are members of Group2
User12 is a member of Group3
Group4 is empty
Whenever I run an LDAP sync, User01 through User11 match up, but User12 does not. When I use ldapsearch with the SyncAcct to check User01, I see the Group2 membership and Group1 is not shown. When I do the same to check Group2, I see the Group1 membership. When I do the same with User12, I see the Group3 membership, and when I do the same with Group3, I see the Group1 membership. This tells me that the account is able to see what it needs to see. I believe this behavior may be considered buggy, so I wanted to post this even though I will be attempting to work around it with configuration changes.
While I don't see any potential value here (short of potential changes to improve future debug output), the LDAP sync debug looks like this:
2026-06-10 18:57:01 debug LDAP Debug: *AD/LDAP synchronization started at 18:57:01 / Memory used: 0.4MB / Peak: 0.4MB 0 d168e776792d 127.0.0.1
2026-06-10 18:57:01 info LDAP Info: AD/LDAP synchronization started 0 d168e776792d 127.0.0.1
2026-06-10 18:57:01 debug System Debug: *LDAP cache folder value: /tmp/.ldap_cache/ 0 d168e776792d 127.0.0.1
2026-06-10 18:57:02 info LDAP Info: No update for the 11 LDAP synced users, based on 11 LDAP entries (processed in 00:00:01) 0 d168e776792d 127.0.0.1
2026-06-10 18:57:02 debug Debug Debug: *19 INFO: Requested operation successfully done 0 d168e776792d 127.0.0.1
Comments
info LDAP Info: 11 users updated, based on 12 LDAP entries (processed in 00:00:00)
The user was not created and further configuration modification did not affect this behavior.
Further investigation lead to the realization that memberOf does not return the user's primary group, and the design for OU1 had all users belonging only to Group3 or Group4, meaning that those groups would be primary groups. To confirm this was the issue, I reverted my configuration changes and added a new group (call it Group5) in OU1, meaning my group memberships now look like this:
Group2 and Group5 are members of Group1
User01 through User11 are members of Group2
User12 is a member of Group5
(Group3 and Group4 are no longer relevant to multiOTP)
After this change, the final log entry in LDAP sync was like this:
info LDAP Info: 1 user created, based on 12 LDAP entries (processed in 00:00:00)
The user was added to multiOTP, so the only potentially outstanding items for this thread are as follows:
1) Is there a ldap-recursive-groups option for multiotp -config (or should there be) and should the wiki be updated to mention it?
2) Can multiOTP be enhanced to determine primary group membership where memberOf will otherwise miss that group, and if so, is such an enhancement desirable?