Bug 15515 - Regression in LDAP_MATCHING_RULE_IN_CHAIN after CVE-2023-0614 fix
Summary: Regression in LDAP_MATCHING_RULE_IN_CHAIN after CVE-2023-0614 fix
Status: NEW
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: AD: LDB/DSDB/SAMDB (show other bugs)
Version: 4.18.5
Hardware: All All
: P5 regression (vote)
Target Milestone: ---
Assignee: Samba QA Contact
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-11-10 15:49 UTC by Jonathan Hunter
Modified: 2024-12-19 04:20 UTC (History)
2 users (show)

See Also:


Attachments
patch for testing (1.13 KB, patch)
2023-12-28 00:03 UTC, Douglas Bagnall
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Hunter 2023-11-10 15:49:19 UTC
After commit 0776ce5caedf18aa8cc1d1dddb1a425f3d0c926c (bug 15270), one of my production LDAP queries using LDAP_MATCHING_RULE_IN_CHAIN has stopped working.

The same query using ldbsearch against sam.ldb works OK, but when the search is carried out using LDAP (either with ldbsearch or ldapsearch) it returns no results.

Example search that now returns nothing after my DC upgrades; this
exact search used to work just fine:
(&
    (objectCategory=Person)
    (sAMAccountName=*)
    (memberOf:1.2.840.113556.1.4.1941:=CN=somegroup,OU=someou,DC=mydomain,DC=org)
)

But if I remove the matching rule specifier, it does return a number of results:
(&
    (objectCategory=Person)
    (sAMAccountName=*)
    (memberOf=CN=somegroup,OU=someou,DC=mydomain,DC=org)
)
Comment 1 Yohannès ALEMU 2023-11-29 14:11:39 UTC
Hi Jonathan,

Thank you for your initial investigation. I had once this issue in the past an didn't dig into it much further (I could have a workaround).

Could you please check if you have some GPO where "Authenticated Users" token has been removed from the ACE ?

I have been able to reproduce the issue with the following scenario:

* removes the "Authenticated Users" token on the ACE on a GPO entry (any GPO will do) on CN=<GPO_GUID>,CN=Policies,CN=System. You can remove it from gpmc.msc into delegation tab on the target GPO.

* run ldbsearch -H ldap://$(hostname -s) '(&(ObjectClass=*)(memberof:1.2.840.113556.1.4.1941:=cn=group1,cn=users,dc=testad-9y3tb,dc=int))'  dn -U user1%password1

I get the following error message : 

"search error - LDAP error 1 LDAP_OPERATIONS_ERROR -  <00002020: Indexed and full searches both failed!"

There is nothing in the logs below loglevel 10 on the server side, and it is not categorized (it falls in the "all" category), but when searching the needle in the haystack, one can find this error message: 

ldb_request SUB dn=dc=testad-9y3tb,dc=int filter=(&(ObjectClass=*)(memberof:1.2.840.113556.1.4.1941:=cn=group1,cn=users,dc=testad-9y3tb,dc=int))
Access on CN={81989F0C-7601-4C22-928D-82E60BE5DEEC},CN=Policies,CN=System,DC=testad-9y3tb,DC=int deniedSecurity context:     : struct security_token

Note : the error can be triggered only if one use the memberof:1.2.840.113556.1.4.1941 OID for nested group search, otherwise it works properly.

I have not tried to check if it succeed when removing the commit you referenced in your message, but it looks like the same issue.

Cheers,

Yohannès, Simon, Denis
Comment 2 Douglas Bagnall 2023-12-28 00:03:43 UTC
Created attachment 18211 [details]
patch for testing

I think this patch will tell you where in the chain the problem is.

My suspicion is that the transitive search hits a point where permission is denied. What should happen at that point is the question -- should that branch be clipped off the results, or (as seems to happen now) the whole tree be hidden.

If it reports no error, or the error is not related to access rights, then I'm completely wrong and/or something worse or more interesting is happening.
Comment 3 Samba QA Contact 2024-03-22 06:08:04 UTC
This bug was referenced in samba master:

cebe12bc85a7f178e7ccaecd1c075f2e40478139
Comment 4 Douglas Bagnall 2024-10-16 22:09:08 UTC
(In reply to Samba QA Contact from comment #3)
> cebe12bc85a7f178e7ccaecd1c075f2e40478139

This patch that got into master means that in 4.20+ at log level 3, you will messages like from ldb_eval_transitive_filter_helper that look like

  search failure (50: insufficient access rights) looking for 'member' on 'CN=foo,DC=samdom,DC=example,DC=com'

which tells you where in the transitive chain the permissions failed.
Comment 5 Jonathan Hunter 2024-10-31 09:30:54 UTC
Thank you Douglas - that patch makes things much easier to see and I can indeed observe the query failing now. (I had to fix an unrelated issue with my docker test setup as I was missing some logs in my output, hence it took me a while :) )

The debug output from an 'ldapsearch' query is as follows, we can actually see a dsdb access check fail, and the new ldb_eval_transitive_filter_helper debug showing also.

Successful AuthZ: [LDAP,simple bind] user [MYDOMAIN]\[Administrator] [S-1-5-21-111111111-2222222222-3333333333-500] at [Thu, 31 Oct 2024 09:05:51.028580 UTC] Remote host [ipv4:172.17.0.4:49850] local host [ipv4:172.17.0.3:389]
{"timestamp": "2024-10-31T09:05:51.028675+0000", "type": "Authorization", "Authorization": {"version": {"major": 1, "minor": 2}, "localAddress": "ipv4:172.17.0.3:389", "remoteAddress": "ipv4:172.17.0.4:49850", "serviceDescription": "LDAP", "authType": "simple bind", "domain": "MYDOMAIN", "account": "Administrator", "sid": "S-1-5-21-111111111-2222222222-3333333333-500", "sessionId": "5978257f-dcd7-4534-a368-dc43152a7d50", "logonServer": "TESTDC1", "transportProtection": "TLS", "accountFlags": "0x00000010", "clientPolicyAccessCheck": null, "serverPolicyAccessCheck": null}}
ldapsrv_SearchRequest: ldb_request SUB dn=dc=mydomain,dc=org filter=(&(objectCategory=Person)(sAMAccountName=*)(memberOf:1.2.840.113556.1.4.1941:=CN=xxcn1,OU=xxou2,DC=mydomain,DC=org))
dsdb_search_dn: flags=0x00020000 CN=xxcn5,OU=xxou4,OU=xxou3,DC=mydomain,DC=org -> dsdb_access: Access check failed on OU=xxou4,OU=xxou3,DC=mydomain,DC=org (No such object)
ldb_eval_transitive_filter_helper: search failure (32: No such object) looking for 'memberOf' on 'CN=xxcn5,OU=xxou4,OU=xxou3,DC=mydomain,DC=org'
ldapsrv_SearchRequest: LDAP Query: Duration was 0.00s, SearchRequest by S-1-5-21-111111111-2222222222-3333333333-500 from ipv4:172.17.0.4:49850 filter: [(&(objectCategory=Person)(sAMAccountName=*)(memberOf:1.2.840.113556.1.4.1941:=CN=xxcn1,OU=xxou2,DC=mydomain,DC=org))] basedn: [dc=mydomain,dc=org] scope: [SUB] result: Success
stream_terminate_connection: Terminating connection - 'ldapsrv_call_wait_done: call->wait_recv() - NT_STATUS_LOCAL_DISCONNECT'

I don't know too much about the internals of this code, but I could hazard a guess as to why the check that was put in to avoid information leakage in bug 15270 has broken this scenario, i.e. samba is now unable to walk the tree - I had set a restrictive ACL on OU=xxou4 in my example above.

I would expect that samba should still be able to do this (it worked in 4.11 and before) as otherwise a user in CN=xxou4 who is added to a group outside that OU will not be picked up when using LDAP_MATHING_RULE_IN_CHAIN (but is still returned as a member using other methods), if that makes any sense at all..

I think this could well be the same issue as reported by Yohannès above, since I do have a restrictive ACE on the OU.

Could the fix be to amend what was done for bug 15270 and adjust it to allow group membership queries to continue to function, but not attribute queries? That wouldn't lead to an information disclosure of attribute contents, as far as I can see, but rather would enable a group membership query to continue to work (the query returns results fine without LDAP_MATCHING_RULE_IN_CHAIN) ??
Comment 6 Douglas Bagnall 2024-12-19 04:20:48 UTC
> Could the fix be to amend what was done for bug 15270 and adjust it to allow group membership queries to continue to function, but not attribute queries? 

The trouble is membership queries really are just attribute queries. I hesitate to second guess what access people really mean by their ACLs.

In this case, the membership might be available via other searches, since the member and memberOf attributes reflect each other, and you *could* deduce the whole chain from outside:

   open    |   restricted   |  open
           |                |
     A --------> B  - - - - - > C       member  -->
      < - - - -     <----------         memberof <--
           |                |           visible  ---
                                        hidden  - - - 

but it might not always be like that (here, there's no clue of the A:C relationship):

   open    |   restricted   |  open
           |                |
     A ------> B - -> D - - - > C       member  -->
      < - - - -  < - -  <------         memberof <--
           |                |           visible  ---
                                        hidden  - - - 


I still don't know for certain whether we should fail the whole search or just clip the tree. I mean, the search goes to the trouble of saying "no such object" when trying to follow a memberOf into secrecy, because we don't want to leak the secret fact. But by making the search fail, this just alerts the searcher, who can the try each memberOf in turn to discover the secret. It's not technically leaking anything, but it is turning on a big flashing sign.

If on the other hand the search interpreted "no such object" as "nothing to see here, move on to the next link", the result would be the transitive memberships that you are allowed to see. Maybe that's what you want.

Does anyone know what Windows does?