Skip to content

Add named pipe (RPC/NP) transport support to SamServer#223

Merged
MichaelGrafnetter merged 3 commits intomasterfrom
claude/musing-ride
Mar 26, 2026
Merged

Add named pipe (RPC/NP) transport support to SamServer#223
MichaelGrafnetter merged 3 commits intomasterfrom
claude/musing-ride

Conversation

@MichaelGrafnetter
Copy link
Copy Markdown
Owner

When SamConnectWithCreds is used, the RPC connection defaults to TCP, which blocks password change operations. Add a useNamedPipes parameter to SamServer that establishes an authenticated SMB session (IPC$) before connecting, forcing RPC over named pipes (ncacn_np).

Restores WNet P/Invoke methods (WNetAddConnection2, WNetCancelConnection2) using CsWin32-generated types (NETRESOURCEW, NET_RESOURCE_SCOPE, etc.) instead of the previously deleted manual enum/struct files.

Closes #150

When SamConnectWithCreds is used, the RPC connection defaults to TCP,
which blocks password change operations. Add a useNamedPipes parameter
to SamServer that establishes an authenticated SMB session (IPC$) before
connecting, forcing RPC over named pipes (ncacn_np).

Restores WNet P/Invoke methods (WNetAddConnection2, WNetCancelConnection2)
using CsWin32-generated types (NETRESOURCEW, NET_RESOURCE_SCOPE, etc.)
instead of the previously deleted manual enum/struct files.

Closes #218

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 26, 2026 04:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an opt-in (currently default-on) path to force SAMR RPC to use named pipes by pre-establishing an authenticated SMB IPC$ session, addressing “Access is denied” failures during password hash reset when connecting via SamConnectWithCreds.

Changes:

  • Extend SamServer with a useNamedPipes option and lifecycle management for an SMB IPC$ session.
  • Add mpr.dll interop (WNetAddConnection2W, WNetCancelConnection2W) and supporting CsWin32 types/enums.
  • Update PowerShell SAM cmdlet base class to instantiate SamServer with named pipes enabled.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
Src/DSInternals.SAM/Wrappers/SamServer.cs Adds named-pipe transport support by creating/disposing an IPC$ SMB session around SAM connect.
Src/DSInternals.SAM/NativeMethods.txt Extends CsWin32 generation inputs with NETRESOURCE/WNet-related types/enums.
Src/DSInternals.SAM/Interop/NativeMethods.Mpr.cs Introduces mpr.dll P/Invokes and a helper to connect to IPC$ with credentials.
Src/DSInternals.SAM/Interop/NamedPipeConnection.cs New helper to manage IPC$ SMB connection lifetime used to force ncacn_np.
Src/DSInternals.SAM/Interop/Enums/NetCancelOptions.cs Adds flags wrapper for WNetCancelConnection2 options.
Src/DSInternals.PowerShell/Commands/Base/SamCommandBase.cs Forces named pipes on for SAM cmdlets when creating SamServer.
Comments suppressed due to low confidence (1)

Src/DSInternals.SAM/Wrappers/SamServer.cs:66

  • If SamConnect*/Validator.AssertSuccess throws after _namedPipeConnection is created, the constructor exits early and the SMB session is never disposed, leaving an authenticated \\server\IPC$ connection behind. Consider creating the NamedPipeConnection in a local variable and disposing it in a catch/finally when the SAM connect fails, or only assigning it to the field after the SAM handle is successfully opened.
        if (useNamedPipes && credential != null)
        {
            // Establish an authenticated SMB session to force RPC over named pipes
            _namedPipeConnection = new NamedPipeConnection(serverName, credential);
        }

        NtStatus result = (credential != null) ?
            NativeMethods.SamConnectWithCreds(serverName, out SafeSamHandle serverHandle, accessMask, credential) :
            NativeMethods.SamConnect(serverName, out serverHandle, accessMask);

        Validator.AssertSuccess(result);
        this.Handle = serverHandle;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

MichaelGrafnetter and others added 2 commits March 26, 2026 05:44
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@MichaelGrafnetter MichaelGrafnetter merged commit fe13ad1 into master Mar 26, 2026
1 check passed
@MichaelGrafnetter MichaelGrafnetter deleted the claude/musing-ride branch March 26, 2026 06:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

set-samaccountpasswordhash : Access is denied

2 participants