runtime: System.DirectoryServices.Protocols LdapConnection doesn't work with Ntlm and Kerberos on Linux

Description

We have a simple LDAP connector in our app that currently works with System.DirectoryServices.Protocols 5.0.0 nuget package. To use SSL/TLS features I’m trying to upgrade in to package 6.0.0 and higher, but when I do that I find that it’s not possible to connect using Ntlm or Kerberos AuthType anymore and those are what our clients mostly use.

Reproduction Steps

App is netcore3.1. The connection code looks like this

_ldapConnection = new LdapConnection(_ldapServer) { AuthType = authType }; _ldapConnection.SessionOptions.ProtocolVersion = 3; if (IsWindows()) { _ldapConnection.SessionOptions.ReferralChasing = ReferralChasingOptions.None; } if (useSsl) { _ldapConnection.SessionOptions.SecureSocketLayer = true; if (IsWindows()) { _ldapConnection.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback(VerifyServerCertificate); } } var credentials = new NetworkCredential(_ldapServerLogin, _ldapServerPassword, keyDistributionCenter ?? string.Empty); _ldapConnection.Bind(credentials);

The only thing I change is nuget package version from 5.0.0 to 6.0.0.

Expected behavior

Successful bind when AuthType is Ntlm or Kerberos and app runs on Windows or Linux

Actual behavior

Successful bind on Windows, but on Linux I get the following errors Ntlm: Error code AuthUnknown (86) (System.DirectoryServices.Protocols.LdapException: An unknown authentication error occurred.) Kerberos: Error code NotSupported (92) (System.DirectoryServices.Protocols.LdapException: The feature is not supported.)

Regression?

Works with System.DirectoryServices.Protocols 5.0.0 nuget package on both Windows and Linux

Known Workarounds

No response

Configuration

No response

Other information

No response

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 15 (11 by maintainers)

Most upvoted comments

Yes it only applies to Linux. If your Linux box is already domain-joined to your LDAP server and have a valid kerberos ticket for it, then you should be able to use that as well if you don’t want to use credentials. Otherwise, yes, the choice would be to use Basic auth and if your LDAP server supports it, then using setting SSL or TLS options to true before calling Bind in order to encrypt the communication before passing your credentials to authenticate.

Hi @corsiva, unfortunately I’m no longer focusing on System.DirectoryServices.* libraries, but looks like my colleagues who now own this are already engaged in that issue with you 😃

and also in package 5.0.1 BTW

That explains why I missed the change. I always look at the tip of the servicing branches. 😅

Hello @pollymykh thank you for logging the issue, and thanks @filipnavara for the initial triage. Seems like you are using credentials to login, and in such case, you aren’t really doing Kerberos authentication. If you take a look at this comment on an issue that was logged right after 5.0 release, we discovered that in the 5.0.0 package setting AuthType to a value like Kerberos would basically be incorrectly discarded if you provided credentials, since we were silently falling back to Basic. I suspect this is why if you use 5.0.0 NuGet package it “works” (quoted since you aren’t really doing Kerberos auth, we are silently falling back to basic auth instead.), but in 6.0.0 it doesn’t. This is because after figuring out we had this problem, we now fail if you try to use Kerberos auth in 6.0 (and also in package 5.0.1 BTW) and provided credentials.

In Linux, we currently only support two types of authentication:

  • AuthType.Basic = You use credentials to authenticate. This is NOT the default value, so you do need to change your code and specifically set your AuthType to basic when using credentials. You can decide to use this over SSL or TLS so that credentials are encrypted when the connection happens.
  • AuthType.Negotiate = You don’t provide credentials to authenticate, and you are running on a machine/user that is domain-joined (AD-joined) to the LDAP server. In this case, we use the underlying GSSAPI libs to authenticate using the machine/user existing kerberos token.

All of the rest of the Authentication types are currently not supported in Linux. We do plan to add support for them, but haven’t planned that work for a milestone yet.

My suspicion is that the authentication type may have inadvertently been ignored in version 5.0.0 (on Linux) and it silently proceeded with Basic authentication. Would it be possible to run Wireshark traces for both package versions? (assuming that it may fail early for 6.0.0 and not produce anything useful)