-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LdapSessionOptions.VerifyServerCertificate is not supported in non-Windows and error message is not helpful. #60972
Comments
Tagging subscribers to this area: @jay98014 Issue DetailsDescription
The same code works when using switching to version 5.0.0 of Reproduction StepsRun the following code under Linux <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.DirectoryServices.Protocols" Version="6.0.0-rc.2.21480.5" />
</ItemGroup>
</Project> using System.DirectoryServices.Protocols;
using System.Net;
var di = new LdapDirectoryIdentifier(server: "ad.almirex.com", 389);
var connection = new LdapConnection(di, new NetworkCredential("username","password","ad.almirex.dc"));
connection.Bind();
Console.WriteLine("Hello, World!"); If the package version is switched to Expected behaviorThe code works Actual behaviorThe code throws Regression?This worked in .NET 5 version of the package. Known WorkaroundsNone ConfigurationTested with .NET 6.0.100-rc.2.21505.57 SDK on WSL2 Ubuntu Other informationNo response
|
I think this is related to Ntlm somehow being broken on .NET 6. I switched it up like this: using System.DirectoryServices.Protocols;
using System.Net;
var di = new LdapDirectoryIdentifier(server: "ad.almirex.com", 389);
var connection = new LdapConnection(di, new NetworkCredential("user","password", "almirex.dc"), AuthType.Ntlm);
connection.Bind();
Console.WriteLine("Hello, World!"); and getting
The same code works with |
Thanks for logging the issue. Can you please try setting the connection auth type to Basic as well as setting the protocol version to 3.0? var di = new LdapDirectoryIdentifier(server: "ad.almirex.com", 389);
var connection = new LdapConnection(di, new NetworkCredential("user", "password", "almirex.dc"));
connection.SessionOptions.ProtocolVersion = 3;
connection.AuthType = AuthType.Basic;
connection.Bind();
Console.WriteLine("Hello, World!"); |
Ok, that seems to have partially fixed the issue, I can connect to the LDAP endpoint on 389. It however fails to connect to LDAPS when running under linux, even though .NET 6 release notes says this is supposed to be supported. This is the code used: using System.DirectoryServices.Protocols;
using System.Net;
var useSsl = true;
var port = useSsl ? 636 : 389;
var di = new LdapDirectoryIdentifier(server: "ad.almirex.com", port);
var connection = new LdapConnection(di, new NetworkCredential("username","password"), AuthType.Basic);
if (useSsl)
{
connection.SessionOptions.SecureSocketLayer = true;
connection.SessionOptions.VerifyServerCertificate = (ldapConnection, certificate) => true;
}
connection.Bind();
Console.WriteLine("Hello, World!"); |
I believe ldaps is only supported when using protocol version 3. Can you try setting the protocol version to 3.0 in your connection before calling bind? |
Didn't help. Looking closer it's actually choking on the setter for this line when run under Linux, but works fine on windows. connection.SessionOptions.VerifyServerCertificate = (ldapConnection, certificate) => true;
|
I see, that is definitely a bug in Linux that we should fix, I'll update the title of the issue to say that this specific session option is the one that isn't working correctly. Out of curiosity, is there a specific reason you are defining that callback? I ask because the SSL handshake will automatically verify the server certificate already, and seems like yours isn't really changing anything. Can we get confirmation that if you remove that line the code works as expected? |
Actually after looking this more closely, looks like the Option that this is internally trying to set is indeed not supported anywhere other than wldap32 (meaning this setting is not part of the LDAP spec) which explains why it doesn't work on Linux.
Perhaps what this issue should track is just to have the right documentation on this API to mention that this is not supported in Linux, and we should be throwing a better exception with better details on it. |
Thanks for the reply, in fact we found something similar here. One of our servers wasn't correctly configured, when we tried the other one it worked. Now we configured the server correctly and everything is working fine. Regarding the @joperezr any chance the error messages from theses cases can be more helpful? I used Apache Directory Server to try and connect to the server using SSL and it provided me better error messages, only then we started to investigate our server. The "server is unavailable" message from the .NET implementation is very generic. |
Yes, we have several issues for trying to surface the error messages better, we can use this issue to track the work of making that better for .NET 7 |
@joperezr was LdapSessionOptions.VerifyServerCertificate ever implemented on Linux? I'm having the exact same issues as the other folks on this thread, and the only workaround was to issue This is not a great workaround, because the |
You can set it in proc but you need to use PInvoke to call setenv in libc directly and not through the dotnet APIs. It’s not ideal but it at least doesn’t rely on the env var being set before the process starts. |
We haven't been able to prioritize this issue to add the support in Linux yet, but we would definitely be open into taking a contribution that addresses this in case anyone is interested in helping. Otherwise, we will keep it in the backlog and hopefully be able to get to it in 8.0, but that would greatly depend on the work going to the rest of the libraries and their priorities. |
Been struggling with this as well (LPAP via SSL on Linux). A few things that might be useful for others:
The Novell.Directory.Ldap.NETStandard library that some have mentioned can do this per connection / instance, but it would require a rewrite of most of the LDAP / AD related code. |
I cannot believe that this is working on Linux. All in all, this is quite a mess. My code is fully working on windows but I cannot connect using port 636 on linux. If I use 389, I can connect, but I have to use the full distinguished name as username and all my other methods in my class fail (e.g. searching users, etc). |
On linux (simplified version):
|
For setting securesocketlayer I get a "not supported on this platform" exception |
Did you use the exact code provided (auto bind to false, etc)? It works fine here. |
I'll send a Screenshot tomorrow |
This is the corresponding docker file: FROM mcr.microsoft.com/dotnet/aspnet:7.0-alpine AS base |
Just to make sure: Are you sure you are loading the correct runtime assemblies (Linux), not the reference ones from the nuget package? The only difference I noticed in your example code is I am using net 6 jammy (Ubuntu) but that doesn't explain the difference in behavior. |
no. I'm not sure. how can I check? and which ones are the correct ones? |
Ok, this is a very confusing issue. This one seems to work! Thanks for the hint. But still confused about these two packages... |
This is working for me // when using this constructor with servers, it doesn't work, it throws System.DirectoryServices.Protocols.LdapException: The LDAP server is unavailable
// var ldapDirectoryIdentifier = new LdapDirectoryIdentifier(_ldapSettings.Servers, _ldapSettings.Port, false, false);
var ldapDirectoryIdentifier = new LdapDirectoryIdentifier(_ldapSettings.Servers.First(), _ldapSettings.Port);
using var ldapConnection = new LdapConnection(ldapDirectoryIdentifier);
var credentials = new NetworkCredential(_ldapSettings.ServiceUsername, _ldapSettings.ServicePassword);
ldapConnection.SessionOptions.ProtocolVersion = 3;
ldapConnection.AuthType = AuthType.Basic;
ldapConnection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
ldapConnection.SessionOptions.SecureSocketLayer = true; Also I added issuing and root certificates to certificates store in Dockerfile. |
@YuriiSaichuk : The only thing which worked for me is completly removing System.DirectoryServices-Package and just keep the .protocols package. |
@joperezr |
IIRC, in Linux the certificate is always validated automatically, the problem is that this is done by openldap layer which LdapConnection PInvokes into, but as you noted there is no hook (that I'm aware of) into OpenLdap validation process in order to run custom code for additional validation. My best guess is that if that is what is desired here (running custom validation apart from the general validation of the server certificate) you'd need to look into open ldap's documentation and see if there is something you can configure there. |
OMG! This saved my bacon. This is working for me under .Net 7 running under the Ubuntu 22.04 container. (I do have the certificates installed as well.) It was setting the connection SessionOptions that got it working for me. |
LdapDirectoryIdentifier identifier = new LdapDirectoryIdentifier("ldap.example.com", 389); LdapConnection ldapConnection = new LdapConnection(identifier, networkCredential); if (Environment.OSVersion.Platform == PlatformID.Win32NT) ldapConnection.Bind(networkCredential); i have tried all your opinion still getting the errors in Linux server but not in windows |
This error was driving me crazy. Although it manifested slightly differently. I got the following error, which I think is slightly worse as it directs you into a completely different direction:
On Workaround for me:
|
To anyone stumbling upon this: the issue with SSL/TLS on Linux still persists even when you explicitly disable certificate verification (which I advise you to not do) I would suggest simply switching to Novell LDAP client: it works on Linux and has better API |
Description
LdapConnection
fails to bind on Linux when running .NET6.0.0-rc.2.21480.5
version ofSystem.DirectoryServices.Protocols
package and throwsThe same code works when using switching to version 5.0.0 of
System.DirectoryServices.Protocols
or running under windowsReproduction Steps
Run the following code under Linux
If the package version is switched to
5.0.0
, the above code works.Expected behavior
The code works
Actual behavior
The code throws
Regression?
This worked in .NET 5 version of the package.
Known Workarounds
None
Configuration
Tested with .NET 6.0.100-rc.2.21505.57 SDK on WSL2 Ubuntu
Other information
No response
The text was updated successfully, but these errors were encountered: