Description of problem:
Setting nsslapd-allow-anonymous-access to off prevents anonymous access to the root DSE. I'm not sure I understand section 3.4 of RFC 2251 which seems to cover this. It says a server MUST provide information about itself but later warns that this might be covered by access controls.
% ldapsearch -x -s base -b "" "(objectclass=*)" namingcontexts
ldap_bind: Inappropriate authentication (48)
additional info: Anonymous access is not allowed
RFC 4512, section 5.1 states the following:
An LDAP server SHALL provide information about itself and other
information that is specific to each server. This is represented as
a group of attributes located in the root DSE, which is named with
the DN with zero RDNs (whose [RFC4514] representation is as the
These attributes are retrievable, subject to access control and other
restrictions, if a client performs a Search operation [RFC4511] with
an empty baseObject, scope of baseObject, the filter
"(objectClass=*)" [RFC4515], and the attributes field listing the
names of the desired attributes.
What we are doing seems to be legal with regards to the RFC. One can restrict access to the root DSE entry, which we are doing when nsslapd-allow-anonymous-access is turned off.
The nsslapd-allow-anonymous-access switch is designed to truly eliminate all anonymous access as early as possible, basically only allowing an unauthenticated user to only perform operations that prove that it has a non-anonymous authorization identity (BIND, SASL BIND, and startTLS). It would be recommended to use ACIs if you want more granularity in what an anonymous user can do.
Are you trying to allow anonymous access only for searching the root DSE entry? Is there a reason you are avoiding using ACIs to do this?
This came up in a conversation between Simo and Martin about sssd, whether one can always assume the root DSE is searchable.
I noticed a similar issue when turning nsslapd-allow-anonymous-access off in the IPA client. We have an option of using a one-time password and I need to get the namingContexts. With anonymous access disabled this fails.
If using ACIs is not sufficient, I see two approaches that we can take:
- Allow anonymous to attempt to search for the root DSE when nsslapd-allow-anonymous-access is set to off (this search may still be restricted by ACIs).
- Add another configuration setting that can control if anonymous can search the root DSE or not when nsslapd-allow-anonymous-access is set to off.
I don't really like the idea of adding another config setting when we already have enough confusion about the difference between the anonymous and unauthenticated binds switch. The problem with the first approach is that we're still processing the search operation (at least parsing the BER) for any search attempt by an anonymous user to figure out if we should allow it or not. The way the anonymous access switch works now is designed to avoid processing anything we can for an anonymous user to prevent exposure to any kind of DoS attack. The first approach somewhat defeats this design.
How about a 3-way switch? on/off work as they do today, dseonly is a compromise between the two?
Does parsing include the base? I would say that we should just check if base is empty and let the request continue. If the base is not empty the flag should be respected.
Is this a lot of parsing?
I think first approach is the right one and RFC compliant.
The correct functionality IMO is more important than attempt to prevent a DoS attack.
(In reply to comment #4)
> How about a 3-way switch? on/off work as they do today, dseonly is a compromise
> between the two?
Yes, this approach would be doable.
(In reply to comment #5)
> Does parsing include the base? I would say that we should just check if base is
> empty and let the request continue. If the base is not empty the flag should be
> Is this a lot of parsing?
> I think first approach is the right one and RFC compliant.
> The correct functionality IMO is more important than attempt to prevent a DoS
Yes, parsing the search operation includes getting the search base. The amount of parsing is not the issue. The issue is parsing anything at all for an anonymous user ties up system resources (or opens the server to some sort of an attack). The RFC really doesn't apply here, as access control is not specified by the LDAP RFCs.
The whole point of adding the anonymous access switch was to not allow an unauthenticated user from tying up any server resources (or as little as possible). One could already not allow anonymous to perform any operations via ACIs prior to the addition of this switch, but the operations would still be parsed and then rejected. Cutting of access at an earlier point was a requested feature from users of the Directory Server, so we should not break this.
I think making this setting something other than on/off as Rob suggests is probably the right approach. This allows anonymous access to be truly disabled for those who want to do that, but it also allows one to allow anonymous access to the root DSE only without needing to allow it from an ACI.
One other point to make is that a client that performs an explicit anonymous BIND operation will be rejected when the anonymous access switch is turned off. This is by design. It is not required to perform an explicit BIND operation before other operations in LDAPv3, but some clients may still choose to send the BIND first. Opening up anonymous access to the root DSE with this switch will not (and should not) change this behavior.
Created attachment 468061 [details]
Pushed to master. Thanks to Noriko for the review!
Counting objects: 23, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (12/12), 2.69 KiB, done.
Total 12 (delta 10), reused 0 (delta 0)
e98841c..b3b0217 master -> master
This Bug fix is tested and verified.
Test cases are automated under bindControl test suit.