-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
System.DirectoryServices.Protocols - Linux support #36888
Comments
I don't think preview4 contains the PR. The preview4 branch was last committed to on May 1st: https://github.com/dotnet/runtime/commits/release/5.0-preview4 And the Linux support was merged on May 7th: 55d3260 So the cut for preview4 was taken before this change was merged. It does appear in the preview5 branch. |
Great! So I suppose the next preview version will be available. |
@brunohbrito when you do get the bits to try could you please let us know your feedback - even if you do not encounter any problems? This is the kind of feature that can have configuration specific issues and the more validation we get thru release the better. Cc @joperezr |
@brunohbrito just wondering, would you be willing to try our nightly builds so you get a chance to try this now? If you’d rather wait for next preview that’s fine too. Preview 5 will have Linux support but won’t have default credentials working yet (meaning you don’t need to pass in credentials to ldapconnection if your Linux machine is domain joined) but preview 6 will have that plus OSX support. Nightly builds have all 3. |
@joperezr I'm getting into night build right now, I'll try it and them I give you some feedbacks |
Hi @joperezr / @danmosemsft , To do theses tests I'm using an Active Directory under Windows Server 2019 Datacenter. Scenario 1 - Authenticating userI'm running the following code snippet both for Windows and Linux Environment. var credential = new NetworkCredential("<username>", "<password>");
var connection = new LdapConnection(new LdapDirectoryIdentifier("<ip(13.0.0.0)>", 389, false, false), credential)
{
AuthType = AuthType.Ntlm
};
connection.Bind(); Windows Environment - Running in .NET Core 3.1 and .NET 5.0The code runs fine. Linux - Running in a container. runtime:5.0-buster-slimAt first run I got an error:
To fix that, I've changed the Dockerfile adding apt-get: FROM mcr.microsoft.com/dotnet/core/runtime:5.0-buster-slim AS base
RUN apt-get update && apt-get install -y libldap-2.4-2
WORKDIR /app Then I got a 2nd error: So, to fix that I'd to concat the domain name with username. // FROM
// var credential = new NetworkCredential("<username>", "<password>");
// TO:
var credential = new NetworkCredential(@"<domain>\<username>", "<password>"); And the connection was successfull. Even when added Linux - Using runtime:3.1-buster-slimEverything was fine, except by the needs to concat the libldap suggestionsI was looking at libldap docs. So, why we don't concat domain name in every case (when it's available) for Linux? My suggestions is, at BindHelper() on LdapConnection.cs line 1099, remove this I've made a PR, in case you agree to theses changes. Scenario 2 - SearchingI was trying to search a user specific metadata by following code snippet: var searchFilter = $"(|([email protected])(sAMAccountName={username}))";
var searchRequest = new SearchRequest("DC=brunobrito,DC=net", searchFilter, SearchScope.Subtree, "displayName", "cn", "mail" );
var response = (SearchResponse)connection.SendRequest(searchRequest); tl;dr: I've tried in many ways to perform a Search in Linux scenarios. I just can't. Windows Environment - Running in .NET Core 3.1 and .NET 5.0The code runs fine. It search users in many ways. Returns all metadata. Linux environmentThe Search doesn't work. Always some kind of error. I tried to change the search filter, parameters even the user credentials. But always get the same error: Bug - search_ext_s wrong signatureWhen I changed the Timeout parameter: searchRequest.TimeLimit = TimeSpan.FromMinutes(2); Some crash occurs, bipassing even the trycatch. I got that the parameters Summary - Final discussionI understand that under the hood we are at top of different drivers. While in Windows is wldap32.dll, Linux is libldap. But I think theses differences will make a huge difference for developers. They aren't used to deal with this kind of low level diffs. Why not go in the same directions of Novell.Directory.Ldap.NETStandard? It's isn't a SO dependent. Btw I'had succes in all tests using it. I'll create separated Issues for better discussion. |
@brunohbrito this is very useful thank you for opening the issues. We will take a look and fix as needed. |
Thank you so much for trying out our bits and we really appreciate the feedback 😄
Yes in order to run in Linux or OSX we do require libldap to be installed, which is the case for most Linux distros out there as well as OSX. That said, I do believe that minimal OS versions like the ones used in docker might stripped these dependencies out, so it makes sense you were hitting that. I think it may be a good idea to either add a note on the package to say that we have that as a dependency or perhaps in the code we could catch the dllnotfoundexception and wrap it in a more friendly message saying you are lacking that dependency, would that sound like a good plan?
I'm not sure if this is possible, in Windows if you are domain-joined you can probably get away with it because Windows carries a bit extra info on the domain realm you are joined in, but for Linux this is a bit different given that Linux has a separation between local accounts and LDAP accounts. All that said I would like to understand more about your scenario, is your Linux machine domain joined? If so, have you ran a kinit in order to get a valid Kerberos ticket? That would be the equivalent of being signed in on Windows.
I'll take a look at it, thanks so much for your contribution.
For your search issue, have you ever tried passing in null as attributeList? What may be happening here is that one of the attributes you are passing in is not present on all entities found which could lead to an error. My suggestion would be to try something like: var searchFilter = $"(|([email protected])(sAMAccountName={username}))";
var searchRequest = new SearchRequest("DC=brunobrito,DC=net", searchFilter, SearchScope.Subtree, null ); // Passing null as attributelist basically means return all attributes
var response = (SearchResponse)connection.SendRequest(searchRequest);
Good catch, yeah that sounds like a problem, we should probably log a separate bug for that and fix it.
You are correct that our managed implementations are pretty much the same between Windows and Linux, and we are basically just using different native libraries (or drivers) underneath with just a few places where we handle calls differently between Windows and Linux. That said, we only made this decision because both underlying drivers (wldap32 and libldap) are simply just the implementation of a protocol (LDAP Protocol) to the point where they even have about 95% same signatures between them and they also have the same behavior. Because of this, the only main differences are not in the calls themselves, but just in the way that OSes handle Active directory authentication and domain joined management (which are the issues you found in your first scenario). Windows does have some shortcuts available so that for example, you don't always need to pass in domain/REALM, or it is easier to find the right LDAP server without developers needing to do much configuration, but those differences are mostly just ways how OSes differ on authentication handling. If you have your code not rely on these Windows shortcuts (meaning you pass in the user@REALM as credential) then I would expect this to work both in Windows and Linux. Again thank you so much for your feedback, it is very valuable in making sure that we have a great solution for managing LDAP on Linux/OSX 😄 |
Yes, It sounds good to me. Maybe a message redirecting user to some docs explaining how to solve it. There is a chance to Visual Studio identify which package is referenced during Add Docker Support from Solution Explorer and auto add apt-get some required packages?
No, either my Linux and Windows wasn't joined at domain. I've created a Virtual Machine at Azure and made a simple Active directory config just for theses tests.
Yes. I've tried in many ways to check if something was wrong with my payload. But when I changed for Windows or performs the same search with Novell.Ldap, I got results.
Great! I'm very excited to use it! One of my projects rely on that!
A special thanks to @ralmsdeveloper who helped me in some scenarios, also to build and debug dotnet/runtime (was painful) |
Hello there, Edit: |
Hello @GrowSharp yes, that is by design:
the native library that we use underneath for our Linux implementation is openldap, which doesn't support this option like wldap32 does. Here is more info on openldapand the options they do support in case you are interested: https://www.openldap.org/software/man.cgi?query=ldap_get_option&sektion=3&apropos=0&manpath=OpenLDAP+2.4-Release |
Oh, I see, thanks. Today I'm going to implement role searching. Will let you know how it went. |
Okay, took me little longer than expected, but I have some news. On windows everything works perfectly. I even got some performance boost from it which is nice (and understandable, because I went from .AccountManagement to .Protocols). But on Linux: (same setup as last time, Ubuntu 20.04, .NET Core 3.1, .Protocols version 5.0.0-preview.5.20278.1) 1.) Anonymous bind doesn't work ( 2.) When searching for a role by CN that contains 3.) This is really weird thing that happens sometimes and I have nothing to show for it. So what happens: |
For 1), we do support anonymous bind but we do require for you to be on a Linux machine which is domain joined to an Ldap server. The best way I found to test to make sure that I was successfully authenticated to the server, was by trying to run the ldapwhoami command on the terminal and passing in the realm I wanted to connect to, for example: For 2) it would be good to get more info includding your full code and what you get in windows vs Linux. In theory both underlying native libraries use the same filter language which follows the ldap protocol, so I would be interested in learning why is the behavior different. Please do log a separate issue for that so with more info so that we can take a look. Number 3) I'm not really sure what might be going on to be honest, and unfortunately there is little info there we can use to come up with a repro to understand what is going on. If you manage to get a consistent repro we would be very interested in checking it out and understanding what is wrong. |
I did some more digging. This time on different machine. Centos 7 with .NET Core 3.1 and .Protocols version 5.0.0-preview.5.20278.1
On windows or with accounts without special characters it works correctly tho. Now please tell me, if you need anything more and for which bugs you wan't me to create separate issues. |
can you log one issue for each of the problems you are seeing? That way we can focus each one on individual investigations. I haven't been able to reproduce1-3, and I haven't tried 4 but as part of the investigation of that issue I'll create a user with a password with special characters and try to reproduce that. |
Created separated issues as asked:
|
I believe this can be closed now that the issues are broken out. Let me know if I'm mistaken. |
I'm trying to make a LDAP Connection under aspnet:3.1-buster-slim container. It returns the error:
System.DirectoryServices.Protocols is not supported on this platform
I found a PR #35380 which says that support Linux now. My nuget package is 5.0.0-preview.4.20251.6 from may 18.
Am I missing something?
Configuration
Which version of .NET is the code running on?
.NET Core 3.1
What OS and version, and what distro if applicable?
Debian 10
The text was updated successfully, but these errors were encountered: