Skip to content

Commit 6e3eb0d

Browse files
authored
Fix System.DirectoryServices.Protocols to work on Linux (#67338)
Co-authored-by: Petteri Stenius <[email protected]>
1 parent 794a199 commit 6e3eb0d

File tree

2 files changed

+86
-14
lines changed

2 files changed

+86
-14
lines changed

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

+22-13
Original file line numberDiff line numberDiff line change
@@ -634,30 +634,39 @@ private int SendRequestHelper(DirectoryRequest request, ref int messageID)
634634
}
635635

636636
// Process the attribute.
637-
string stringValue = null;
638-
if (assertion[0] is byte[] byteArray)
637+
byte[] byteArray;
638+
if (assertion[0] is string str)
639639
{
640-
if (byteArray != null && byteArray.Length != 0)
641-
{
642-
berValuePtr = new BerVal
643-
{
644-
bv_len = byteArray.Length,
645-
bv_val = Marshal.AllocHGlobal(byteArray.Length)
646-
};
647-
Marshal.Copy(byteArray, 0, berValuePtr.bv_val, byteArray.Length);
648-
}
640+
var encoder = new UTF8Encoding();
641+
byteArray = encoder.GetBytes(str);
642+
}
643+
else if (assertion[0] is Uri uri)
644+
{
645+
var encoder = new UTF8Encoding();
646+
byteArray = encoder.GetBytes(uri.ToString());
647+
}
648+
else if (assertion[0] is byte[] bytes)
649+
{
650+
byteArray = bytes;
649651
}
650652
else
651653
{
652-
stringValue = assertion[0].ToString();
654+
throw new ArgumentException(SR.ValidValueType);
653655
}
654656

657+
berValuePtr = new BerVal
658+
{
659+
bv_len = byteArray.Length,
660+
bv_val = Marshal.AllocHGlobal(byteArray.Length)
661+
};
662+
Marshal.Copy(byteArray, 0, berValuePtr.bv_val, byteArray.Length);
663+
655664
// It is a compare request.
656665
error = LdapPal.CompareDirectoryEntries(
657666
_ldapHandle,
658667
((CompareRequest)request).DistinguishedName,
659668
assertion.Name,
660-
stringValue,
669+
null,
661670
berValuePtr,
662671
serverControlArray, clientControlArray, ref messageID);
663672
}

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

+64-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Collections.Generic;
45
using System.Diagnostics;
56
using System.DirectoryServices.Tests;
67
using System.Globalization;
78
using System.Net;
9+
using System.Text;
810
using System.Threading;
911
using Xunit;
1012

@@ -474,6 +476,67 @@ private static void RunAsyncSearch(IAsyncResult asyncResult)
474476
}
475477
}
476478

479+
public static IEnumerable<object[]> TestCompareRequestTheory_TestData()
480+
{
481+
yield return new object[] { "input", "input", ResultCode.CompareTrue };
482+
yield return new object[] { "input", Encoding.UTF8.GetBytes("input"), ResultCode.CompareTrue };
483+
484+
yield return new object[] { "input", "false", ResultCode.CompareFalse };
485+
yield return new object[] { "input", new byte[] { 1, 2, 3, 4, 5 }, ResultCode.CompareFalse };
486+
487+
yield return new object[] { "http://example.com/", "http://example.com/", ResultCode.CompareTrue };
488+
yield return new object[] { "http://example.com/", new Uri("http://example.com/"), ResultCode.CompareTrue };
489+
yield return new object[] { "http://example.com/", Encoding.UTF8.GetBytes("http://example.com/"), ResultCode.CompareTrue };
490+
491+
yield return new object[] { "http://example.com/", "http://false/", ResultCode.CompareFalse };
492+
yield return new object[] { "http://example.com/", new Uri("http://false/"), ResultCode.CompareFalse };
493+
yield return new object[] { "http://example.com/", Encoding.UTF8.GetBytes("http://false/"), ResultCode.CompareFalse };
494+
}
495+
496+
[ConditionalTheory(nameof(IsLdapConfigurationExist))]
497+
[MemberData(nameof(TestCompareRequestTheory_TestData))]
498+
public void TestCompareRequestTheory(object value, object assertion, ResultCode compareResult)
499+
{
500+
using (LdapConnection connection = GetConnection())
501+
{
502+
string ouName = "ProtocolsGroup10";
503+
string rdn = "ou=" + ouName;
504+
505+
DeleteEntry(connection, rdn);
506+
AddOrganizationalUnit(connection, rdn);
507+
508+
string dn = rdn + "," + LdapConfiguration.Configuration.SearchDn;
509+
510+
// set description to value
511+
var mod = new ModifyRequest(dn, DirectoryAttributeOperation.Replace, "description", value);
512+
var response = connection.SendRequest(mod);
513+
Assert.Equal(ResultCode.Success, response.ResultCode);
514+
515+
// compare description to assertion
516+
var cmp = new CompareRequest(dn, new DirectoryAttribute("description", assertion));
517+
response = connection.SendRequest(cmp);
518+
// assert compare result
519+
Assert.Equal(compareResult, response.ResultCode);
520+
521+
// compare description to value
522+
cmp = new CompareRequest(dn, new DirectoryAttribute("description", value));
523+
response = connection.SendRequest(cmp);
524+
// compare result always true
525+
Assert.Equal(ResultCode.CompareTrue, response.ResultCode);
526+
}
527+
}
528+
529+
[ConditionalFact(nameof(IsLdapConfigurationExist))]
530+
public void TestCompareRequest()
531+
{
532+
using (LdapConnection connection = GetConnection())
533+
{
534+
// negative case: ou=NotFound does not exist
535+
var cmp = new CompareRequest("ou=NotFound," + LdapConfiguration.Configuration.SearchDn, "ou", "NotFound");
536+
Assert.Throws<DirectoryOperationException>(() => connection.SendRequest(cmp));
537+
}
538+
}
539+
477540
[ConditionalFact(nameof(IsActiveDirectoryServer))]
478541
public void TestPageRequests()
479542
{
@@ -586,7 +649,7 @@ public void TestSortedSearch()
586649
}
587650
}
588651
}
589-
652+
590653
private void DeleteAttribute(LdapConnection connection, string entryDn, string attributeName)
591654
{
592655
string dn = entryDn + "," + LdapConfiguration.Configuration.SearchDn;

0 commit comments

Comments
 (0)