Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Present the name provided by the caller for GSSAPI/SASL authentication #21

Closed
wants to merge 2 commits into
from

Conversation

Projects
None yet
2 participants

In commit af63067 on 2008-04-21 there was an attempt to "Fix a problem with Net::LDAP when talking to a round-robin LDAP server(s) using SASL/GSSAPI authentication to use the provided hostname not the canonical name"

This commit changed Net::LDAP so that it passes an IP Address to SASL/GSSAPI as the server identification instead of the server name supplied by the client. This assumes that Kerberos (the usual GSSAPI mechanism employed) will do a reverse DNS lookup to construct the Kerberos service principal name, since IP Addresses are almost never used for this. This need not be the case; MIT Kerberos, for example, can be configured to resolve CNAME and PTR records, just CNAMEs, or perform no DNS canonicalization at all.

Since we've configured Kerberos to not do PTR lookups, Net::LDAP with SASL/GSSAPI does not work in our environment.

The problem here is in assuming that it's even possible for Net::LDAP to (as the Changes explanation says) "Pass correct hostname to SASL when connecting to a round-robin" There's no real way for the library to know what the "correct hostname" is supposed to be, beyond that specified by the caller. It's the responsibility of the systems administrator to ensure that Kerberos, DNS records, service principals, and application configuration are arranged such that they all work together, and if a library tries to second-guess this by altering the name passed to it, it will likely cause this kind of breakage at some point. As a default, a library should pass the hostname unaltered to SASL/GSSAPI so that it can obey the local rules for locating the correct service principal.

This isn't only a functional problem, it could be considered a security problem. DNS is insecure, but mutual authentication with Kerberos ensures that we can trust the server to which we connect and successfully authenticate. If we use the same (possibly compromised / spoofed) DNS system to find our server and construct the service name we use for authentication, we lose that benefit from mutual authentication. If the LDAP server is used to provide passwd/group maps for unix hosts, the results could be catastrophic.

On the other hand, sometimes we face the opposite problem -- getting Kerberos to work in a misconfigured environment where the rules in effect produce the wrong result. In that case it may be useful to offer the library client the option of performing some DNS canonicalization on its own, or alternately allow the client to specify the Kerberos principal directly -- but these should be options, not the default.

This patch reverts the behavior to using the name supplied by the caller instead of using the address to which a connection has been established. This will reliably produce the service name that the caller intended to authenticate. It also provides a new (documented) OPTION to bind, "sasl_authenticate_with" which if set to the (case insensitive) string "CONNECTED_IP", enables the current behavior, and if set to the (case insensitive string) "CONNECTED_NAME", performs the reverse dns lookup on the peeraddr (for environments which have kerberos configured to not perform reverse lookups).

I understand that changing the default behavior like this is not 100% backwards compatible and that there are some users whose programs may break as a result, but in my opinion the security ramifications of this behavior warrant some consideration.

mkomitee added some commits May 30, 2013

@mkomitee mkomitee Present the name provided by the caller for GSSAPI/SASL authentication
Reverts a change from af63067 which attempted to work around the use of
round-robin A records by always passing the IP address of the LDAP server to
SASL/GSSAPI which caused a reliance on Kerberos DNS canonicalization to guess
the correct service name for authentication. This causes problems with Kerberos
configurations that do not perform DNS canonicalization -- the service name
cannot be determined despite the fact that it was correctly provided by the
caller.

Provides for a new option which can be passed to bind which will force us to
continue to use the old behavior, but by default, uses the hostname as provided
by the caller for authentication purposes.

To reproduce the old behavior, instead of:

    $ldap->bind(...)

Use:

    $ldap->bind(... sasl_authenticate_with => 'ip')
ef43ec1
@mkomitee mkomitee Adding more sasl authentication options
Renamed the 'sasl_authenticate_with' value of 'ip' to 'connected_ip' and added
another 'sasl_authenticate_with' value of 'connected_name' which will cause us
to perform the reverse dns lookup for environments where the underlying kerberos
environment is configured to not perform them.
915ed09
Contributor

marschap commented Dec 14, 2013

Hi,

sorry for the long delay in answering.
Thanks for the pull request.

I think this issue has been fixed with commit f36b2cd in perl-ldap 0.57.

If it hasn't please feel free to open another pull request.

Best
PEter

@marschap marschap closed this Dec 14, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment