Open pollymykh opened 2 years ago
Tagging subscribers to this area: @dotnet/area-system-directoryservices, @jay98014 See info in area-owners.md if you want to be subscribed.
Author: | pollymykh |
---|---|
Assignees: | - |
Labels: | `area-System.DirectoryServices`, `untriaged` |
Milestone: | - |
Did you test both of the .NET versions on the same machine against the same server? Is the gss-ntlmssp package installed on the machine?
@filipnavara yes, same machine to run app, same AD server, same credentials, same codebase except the indicated nuget package version. gss-ntlmssp isn't installed on the machine I run my app on, should it be?
I believe @iinuwa may have some insight about what is going on but I am not particularly familiar with LDAP.
The error message look like something returned by GSSAPI library (the one that is responsible for Kerberos, NTLM and Negotiate authentication). Specifically, the Linux GSSAPI implementation is provided with the krb5
package and the gss-ntlmssp
optional package. The AuthUnknown
error code is something that I would expect if krb5
was intalled and gss-ntlmssp
was not installed.
However, I cannot find any explanation for the fact that it works with older version of the System.DirectoryServices.Protocols package. Majority of the fixes in that library after version 5.0.0 focused on unrelated bug fixes (TLS, referral chasing options). While it could be some unintentional side effect I cannot see any change that would be directly related.
The only change that touched the code, as far as I can see, is https://github.com/dotnet/runtime/pull/52904.
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)
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:
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.
@filipnavara this is almost 100% sure what is going on. If you take a look at 5.0 branch, you can see under a feature flag what our code (incorrectly) used to do:
We provided that feature flag only because this was a breaking change we made in 5.0.1 to fix this incorrect behavior we had in 5.0.0, so the feature flag allowed code to continue working in case they depended on the 5.0.0 behavior. If you see what we used to do, is basically that if credentials were used, then no matter which AuthType you had selected, we would always fallback to a simple bind (meaning AuthType.Basic)
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. 😅
@joperezr thank you for clarification. It seems like we have little choice now but to use Basic explicitly (since we're actually already using it with 5.0.0 logic). Does this behavior (switching to Basic when using credentials) only apply to Linux?
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.
@joperezr Is the request to support other AuthType
s being tracked anywhere? My use-case is such that the user is on a non-domain joined machine, but has their username and password. It's (rather) unlikely that they would know their full DN for the account, making using the AuthType.Basic
kind of a no-go for me. From my testing on Windows, it seems like AuthType.Ntlm
would allow the workflow I'm aiming for.
Unless there's a programmatic way to retrieve the user's DN before connecting to the directory...but that seems like a chicken and egg problem.
I can't find an issue for it from a quick search, so we can either create one for that or we can just re-use this one to track this (which is doing it specifically for Ntlm and Kerberos.)
hi @joperezr, What do you think about issue #82430?
BR,
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 😃
using LdapConnection conn = new(new LdapDirectoryIdentifier(hostname, 636));
conn.AuthType = AuthType.Negotiate;
conn.SessionOptions.SecureSocketLayer = true;
conn.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
conn.Bind();
Is there any updates on this or any tips to help troubleshoot? I'm trying to do an ldap search in an ubuntu container using kuberos. The above code is giving me the same "The feature is not supported" error when attempting the Bind.
Hello, The main AuthType supported in Linux is AuthType.Basic which will also need you to pass in credentials. Are you trying to reuse a connection on a system that is already domain joined?
Yes, I have a container that is doing kuberos auth to sql server (running kinit in a sidecar).. I was hoping I'd be able to piggy back on that to do ldap searches also so I don't need to mount a keytab as well as pass in the credentials
@joperezr are you saying AuthType.Negotiate is no longer a supported use-case in linux?
It is supported, but only in the scenario where you are domain joined. Note that having run kinit is likely not enough, as that doesn't mean your machine is truly domain-joined and instead you may just be authenticated. My suggestion would be for you to try to run the ldapsearch linux utilities without passing in your credentials, and seeing if you are able to do that. Main reason why I ask is because the PInvokes we make in Linux for a Sasl bind is very similar to the one that those command line utilities do, so I would expect those won't work either. We unfortunately don't have good error messages for these issues, so another advantage from running those commands is that turning on the verbose output may give you more information on what is wrong with your configuration.
makes sense, thank you!
FWIW, ldapsearch
does work with kinit
on non-domain joined Linux computers.
I too need NTLM/Kerberos support as well under Linux. Oddly, I did have it working, but seemingly without changing anything, it's stopped working. Clearly I'm going mad.
Scenario:
Dockerfile has some packages added:
RUN apt-get update \
&& apt-get install -y libldap-2.4-2
For a week or so this worked, but now just get the following exception:
System.DirectoryServices.Protocols.LdapException
HResult=0x80131500
Message=An unknown authentication error occurred.
Source=System.DirectoryServices.Protocols
StackTrace:
at System.DirectoryServices.Protocols.LdapConnection.BindHelper(NetworkCredential newCredential, Boolean needSetCredential)
I'm using a Windows credential instead of an application partition one as I need to read the schema partition. I don't think you can do that using an application partition credential (so DN format). I have tried.
Any help from MS/others appreciated.
Hi,
I've hoping to use the DirectoryServices.Protocols (8.0.0) package on a Linux host to integrate with an LDAP server using Kerberos authentication. In earlier post by @joperezr, it appears that Basic and Negotiate are supported. Does this mean, by extension, that Kerberos is supported? Apologies as this appears to have been discussed, but the original discussion is regarding earlier versions and am wondering what the official line is now.
I've also been developing locally using this package on a MacOS machine. Basic authenication works fine but as soon as I use either a Negotiate or Kerberos AuthType to connect I get "LdapException: The feature is not supported.". Should the story for MacOS be the same as for Linux? I've noticed another post (in a slightly different context) suggesting this error message may be misleading.
Any clarification would be much appreciated.
Hoping for some movement on this. I'd like to make my tooling multi-platform by using S.DS.P, but I need to use the NTLM auth workflow. 🙏
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