Skip to content

Fix LDAP referral callback host name marshaling - #132227

Draft
steveisok with Copilot wants to merge 2 commits into
mainfrom
copilot/fix-ldapconnection-referralcallback
Draft

Fix LDAP referral callback host name marshaling#132227
steveisok with Copilot wants to merge 2 commits into
mainfrom
copilot/fix-ldapconnection-referralcallback

Conversation

Copilot AI commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

main PR

Description

Referral callbacks decoded the native PCHAR HostName as UTF-16, producing garbled referral server identifiers.

  • Windows callback ABI
    • Decode HostName with Marshal.PtrToStringAnsi in both query and notify callback paths.
    • Preserve UTF-16 decoding for NewDN.
string target = $"{Marshal.PtrToStringAnsi(hostNamePtr)}:{portNumber}";
  • Regression coverage
    • Add Windows-focused tests for both callback paths using ANSI host-name buffers.

Customer Impact

Referral callback consumers receive the correct referred server identifier when chasing referrals.

Regression

Behavior differs from .NET Framework; this corrects the Windows callback marshaling mismatch.

Testing

Focused callback marshaling coverage for query and notify callbacks.

Risk

Low. The change aligns pointer decoding with the documented Windows LDAP callback ABI.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

Copilot AI lite review requested due to automatic review settings August 12, 2026 18:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
16 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Co-authored-by: steveisok <471438+steveisok@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 12, 2026 18:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Suppressed comments (4)

src/libraries/System.DirectoryServices.Protocols/tests/ReferralCallbackTests.cs:70

  • Same concern as the QueryForConnection marshaling test: this uses reflection over non-public members (including the private _ldapHandle field) and should be skipped on .NET Framework to avoid TFM-specific failures.
        [Fact]
        [PlatformSpecific(TestPlatforms.Windows)]
        public void ProcessNotifyConnection_MarshalsHostNameAsAnsi()

src/libraries/System.DirectoryServices.Protocols/tests/ReferralCallbackTests.cs:45

  • This test project multi-targets .NET Framework, but this test uses reflection over non-public implementation details (e.g., LdapSessionOptions.ProcessQueryConnection / LdapConnection._ldapHandle) that are not stable across TFMs. Other tests in this project explicitly skip .NET Framework for similar reflection-based access; this one should too to avoid NetFx-only failures.

This issue also appears on line 68 of the same file.

        [Fact]
        [PlatformSpecific(TestPlatforms.Windows)]
        public void ProcessQueryConnection_MarshalsHostNameAsAnsi()

src/libraries/System.DirectoryServices.Protocols/tests/ReferralCallbackTests.cs:166

  • AllocateAnsiString manually builds an ASCII buffer and double-null terminates it. Using Marshal.StringToHGlobalAnsi better matches the code under test (PtrToStringAnsi uses the active ANSI code page), reduces test-specific encoding assumptions, and simplifies the allocation logic.
        private static IntPtr AllocateAnsiString(string value)
        {
            byte[] bytes = System.Text.Encoding.ASCII.GetBytes(value);
            IntPtr pointer = Marshal.AllocHGlobal(bytes.Length + 2);
            Marshal.Copy(bytes, 0, pointer, bytes.Length);

src/libraries/System.DirectoryServices.Protocols/tests/ReferralCallbackTests.cs:169

  • GetCallbackMethod currently returns null if the method name/signature changes, which then fails later as a NullReferenceException. Throwing a targeted exception here makes failures easier to diagnose (especially given this is reflection over a private method).
        private static MethodInfo GetCallbackMethod(string name) =>
            typeof(LdapSessionOptions).GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic);
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI changed the title [WIP] Fix LdapConnection marshal HostName for ReferralCallback Fix LDAP referral callback host name marshaling Aug 12, 2026
Copilot AI requested a review from steveisok August 12, 2026 19:09
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-directoryservices
See info in area-owners.md if you want to be subscribed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LdapConnection incorrectly marshal HostName string for ReferralCallback

4 participants