Skip to content

Commit 620239a

Browse files
authored
Fix/multi server ldap binding linux (#79657)
* Fix LDAP configuration typo * Allow LDAP binding to multiple servers on Linux
1 parent 522e82b commit 620239a

File tree

5 files changed

+54
-29
lines changed

5 files changed

+54
-29
lines changed

src/libraries/Common/tests/System/DirectoryServices/LDAP.Configuration.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ this command views the status
2020
SLAPD OPENLDAP SERVER
2121
=====================
2222

23-
docker run -p:390:389 -e LDAP_DOMAIN=example.com -e LDAP_ROOTPASS=password -d nickstenning/slapd
23+
docker run -p 390:389 -e LDAP_DOMAIN=example.com -e LDAP_ROOTPASS=password -d nickstenning/slapd
2424

2525
and to test and view status
2626

@@ -125,4 +125,4 @@ Note:
125125
<SupportsServerSideSort>False</SupportsServerSideSort>
126126
</Connection>
127127

128-
</Configuration>
128+
</Configuration>

src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Linux.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ public partial class LdapConnection
1313
// Linux doesn't support setting FQDN so we mark the flag as if it is already set so we don't make a call to set it again.
1414
private bool _setFQDNDone = true;
1515

16-
private void InternalInitConnectionHandle(string hostname)
16+
private void InternalInitConnectionHandle()
1717
{
1818
if ((LdapDirectoryIdentifier)_directoryIdentifier == null)
1919
{
2020
throw new NullReferenceException();
2121
}
2222

23-
_ldapHandle = new ConnectionHandle($"ldap://{hostname}:{((LdapDirectoryIdentifier)_directoryIdentifier).PortNumber}");
23+
_ldapHandle = new ConnectionHandle();
2424
}
2525

2626
private int InternalConnectToServer()

src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.Windows.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,39 @@
44
using System.Diagnostics;
55
using System.Net;
66
using System.Runtime.CompilerServices;
7+
using System.Text;
78

89
namespace System.DirectoryServices.Protocols
910
{
1011
public partial class LdapConnection
1112
{
1213
private bool _setFQDNDone;
1314

14-
private void InternalInitConnectionHandle(string hostname)
15+
private void InternalInitConnectionHandle()
1516
{
17+
string hostname = null;
18+
string[] servers = ((LdapDirectoryIdentifier)_directoryIdentifier)?.Servers;
19+
if (servers != null && servers.Length != 0)
20+
{
21+
var temp = new StringBuilder(200);
22+
for (int i = 0; i < servers.Length; i++)
23+
{
24+
if (servers[i] != null)
25+
{
26+
temp.Append(servers[i]);
27+
if (i < servers.Length - 1)
28+
{
29+
temp.Append(' ');
30+
}
31+
}
32+
}
33+
34+
if (temp.Length != 0)
35+
{
36+
hostname = temp.ToString();
37+
}
38+
}
39+
1640
LdapDirectoryIdentifier directoryIdentifier = _directoryIdentifier as LdapDirectoryIdentifier;
1741

1842
// User wants to setup a connectionless session with server.

src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/ldap/LdapConnection.cs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -173,30 +173,7 @@ internal bool NeedDispose
173173

174174
internal void Init()
175175
{
176-
string hostname = null;
177-
string[] servers = ((LdapDirectoryIdentifier)_directoryIdentifier)?.Servers;
178-
if (servers != null && servers.Length != 0)
179-
{
180-
var temp = new StringBuilder(200);
181-
for (int i = 0; i < servers.Length; i++)
182-
{
183-
if (servers[i] != null)
184-
{
185-
temp.Append(servers[i]);
186-
if (i < servers.Length - 1)
187-
{
188-
temp.Append(' ');
189-
}
190-
}
191-
}
192-
193-
if (temp.Length != 0)
194-
{
195-
hostname = temp.ToString();
196-
}
197-
}
198-
199-
InternalInitConnectionHandle(hostname);
176+
InternalInitConnectionHandle();
200177

201178
// Create a WeakReference object with the target of ldapHandle and put it into our handle table.
202179
lock (s_objectLock)

src/libraries/System.DirectoryServices.Protocols/tests/DirectoryServicesProtocolsTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,30 @@ public void TestSortedSearch()
670670
}
671671
}
672672

673+
[ConditionalFact(nameof(IsLdapConfigurationExist))]
674+
public void TestMultipleServerBind()
675+
{
676+
LdapDirectoryIdentifier directoryIdentifier = string.IsNullOrEmpty(LdapConfiguration.Configuration.Port) ?
677+
new LdapDirectoryIdentifier(new string[] { LdapConfiguration.Configuration.ServerName, LdapConfiguration.Configuration.ServerName }, true, false) :
678+
new LdapDirectoryIdentifier(new string[] { LdapConfiguration.Configuration.ServerName, LdapConfiguration.Configuration.ServerName },
679+
int.Parse(LdapConfiguration.Configuration.Port, NumberStyles.None, CultureInfo.InvariantCulture),
680+
true, false);
681+
NetworkCredential credential = new NetworkCredential(LdapConfiguration.Configuration.UserName, LdapConfiguration.Configuration.Password);
682+
683+
using LdapConnection connection = new LdapConnection(directoryIdentifier, credential)
684+
{
685+
AuthType = AuthType.Basic
686+
};
687+
688+
// Set server protocol before bind; OpenLDAP servers default
689+
// to LDAP v2, which we do not support, and will return LDAP_PROTOCOL_ERROR
690+
connection.SessionOptions.ProtocolVersion = 3;
691+
connection.SessionOptions.SecureSocketLayer = LdapConfiguration.Configuration.UseTls;
692+
connection.Bind();
693+
694+
connection.Timeout = new TimeSpan(0, 3, 0);
695+
}
696+
673697
private void DeleteAttribute(LdapConnection connection, string entryDn, string attributeName)
674698
{
675699
string dn = entryDn + "," + LdapConfiguration.Configuration.SearchDn;

0 commit comments

Comments
 (0)