runtime: Linux: Instantiating a LdapConnection with a server string including a port number in .Net6.0-rc1 System.DirectoryServices.Protocols throws later an error at a SendRequest

Description

If you instantiate a LdapConnection with a string consisting from a server name and a port number e.g.

LdapConnection ldap = new LdapConnection("ldap.example.com:636");

then a later method call like

DirectoryResponse dResp = ldap.SendRequest(request);

yields

Exception has occurred: CLR/System.DirectoryServices.Protocols.LdapException
An unhandled exception of type 'System.DirectoryServices.Protocols.LdapException' occurred in System.DirectoryServices.Protocols.dll: 'A bad parameter was passed to a routine.'
   at System.DirectoryServices.Protocols.LdapConnection.Connect()
   at System.DirectoryServices.Protocols.LdapConnection.SendRequestHelper(DirectoryRequest request, Int32& messageID)
   at System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request, TimeSpan requestTimeout)
   at System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request)

However when instantiating the LdapConnection in this manner

LdapConnection ldap = new LdapConnection(new LdapDirectoryIdentifier("ldap.example.com",636));

then same SendRequest works without exceptions.

Documentation at

.Net Documentation System_DirectoryServices_Protocols_LdapConnection__ctor_System_String_

states that

server String A string specifying the server which can be a domain name, LDAP server name or dotted strings representing the IP address of the LDAP server. Optionally, this parameter may also include a port number, separated from the right end of the string by a colon (😃.

Configuration

.Net6-rc1 Linux Ubuntu 18.04 x86-64

Regression?

Don’t know.

Other information

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 4
  • Comments: 15 (7 by maintainers)

Most upvoted comments

Now it is late for fixing it in .NET 8, in this RC2 timeframe we basically only fix regressions from previous release. Given that there is a work around we can consider fixing it in .NET 9.

Hey @joperezr. I’d like to work on this ticket. Before coding, just a small discussion since I see what the issue is.

The LdapDirectoryIdentifier not only accepts a server it also accepts servers. The default constructor is accepting array of servers. Currently we have 5 default constructors, and all of them are pointing to the base one who is accepting list of servers. There is one constructor which requires attention. As you can tell, it accepts a array of servers and a portNumber. Two questions.

  • Should the passed port number be default for all servers
  • Should we check if servers in the collection have port number and throw an exception if they do?

How about for .NET 8?

I got this issue on Kubuntu 22.04 (and on Mac OS 12.4) with the following .NET environment:

.NET SDK (reflecting any global.json):
 Version:   6.0.300
 Commit:    8473146e7d

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  22.04
 OS Platform: Linux
 RID:         ubuntu.22.04-x64
 Base Path:   /usr/share/dotnet/sdk/6.0.300/

Host (useful for support):
  Version: 6.0.5
  Commit:  70ae3df4a6

.NET SDKs installed:
  6.0.300 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.5 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.5 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

I have a .NET 6 project that uses System.DirectoryServices.Protocols version 6.0.1.

I can confirm that LDAP connection string with port (some.domain.com:389) works only on Windows, while on GNU/Linux and Mac OS that fails with “A bad parameter was passed to a routine” error. Removing the port from connection string (some.domain.com) does indeed resolve the issue (or at least that would be a workaround until the issue is actually resolved), given that one needs to connect to the default port.

@KamranShahid thank you for answering, Well, yes, there is a workaround by using a LdapDirectoryIdentifier.

But I just mention, that I faced with a problem using LdapConnection(string) ctor, because it is still not fixed.

By the way, I faced with another problem now

Thanks for volunteering @filipjelic. The main thing to track on this issue is that there shouldn’t be inconsistencies between Windows and Linux behaviors, so if the port number passed in to this constructor is defaulted to all servers in Windows, we would want to match that on Linux too. For your second question, I wouldn’t add that. When calling the constructor of the LdapConnection we are just creating a native handle of that connection, but not yet performing any sort of validation just yet. If the specified port is closed, I think that what should happen naturally is that constructor shouldn’t throw an exception, and instead when calling Bind() the exception should be thrown as I believe happens today.

Thanks for finding this issue and for logging it @p3rdu. We should be consistent to how Windows currently works here, which by looking at the documentation that you found, then we should likely be parsing this and setting the port accordingly. Did you get a chance to check if this works in Windows? I’m marking this issue as up-for-grabs in case anyone wants to get a stab at it before we get to it.