Skip to content

pageant: fall back to GetUserNameA when GetUserNameExA fails - #726

Merged
Eugeny merged 2 commits into
Eugeny:mainfrom
cwatanab:fix/pageant-getusername-fallback
Aug 17, 2026
Merged

pageant: fall back to GetUserNameA when GetUserNameExA fails#726
Eugeny merged 2 commits into
Eugeny:mainfrom
cwatanab:fix/pageant-getusername-fallback

Conversation

@cwatanab

Copy link
Copy Markdown
Contributor

Problem

GetUserNameExA(NameUserPrincipal) requires a UPN (User Principal Name), which does not exist on non-domain-joined Windows machines (standalone/workgroup). On such machines the API fails with ERROR_NONE_MAPPED (0x80070534), preventing any named-pipe connection to a running Pageant instance.

This affects applications like DBX (Database Explorer) and the pageant crate itself.

Root Cause

The original PuTTY Pageant (C implementation) falls back to GetUserNameA when GetUserNameExA fails. The code comment acknowledges this but the Rust port chose not to implement the fallback, under the assumption that all modern Windows versions support GetUserNameExA. However, even on modern Windows 10/11, a non-domain-joined machine has no UPN configured, and the API call fails.

Fix

Fall back to the USERNAME environment variable when GetUserNameExA(NameUserPrincipal) fails. This provides the SAM account name, which matches what the original PuTTY Pageant's GetUserNameA fallback would return on local accounts.

Testing

  • Verified on Windows 10 (non-domain-joined workstation) where GetUserNameExA(NameUserPrincipal) consistently fails with ERROR_NONE_MAPPED
  • Verified that USERNAME env var contains the correct SAM account name
  • The fallback produces the same username as what the user would expect

This is consistent with how the reference PuTTY Pageant implementation handles this edge case.

GetUserNameExA(NameUserPrincipal) requires a UPN, which does not exist
on non-domain-joined Windows machines (standalone/workgroup).
On such machines the API fails with ERROR_NONE_MAPPED (0x80070534),
preventing any named-pipe connection to Pageant.

The original PuTTY Pageant falls back to GetUserNameA in this case,
but the Rust port was missing this fallback. Instead, fall back to
the USERNAME environment variable, which provides the SAM account name
and matches what GetUserNameA would return on local accounts.

Fixes: inability to connect to Pageant on non-domain Windows setups
@rebelliongeeks

rebelliongeeks commented Aug 15, 2026

Copy link
Copy Markdown

Can confirm on Windows 11 with a local (non-domain) account: GetUserNameExA(NameUserPrincipal) fails with 0x80070534, so the transport never gets a pipe name even though the pipe is right there as pageant.<USERNAME>.<hash>.

The USERNAME fallback would've produced the correct name for us.

Hit this while evaluating russh 0.62.6 for a desktop app. +1 for merging.

@Eugeny Eugeny changed the title pageant: fall back to USERNAME env var when GetUserNameExA fails pageant: fall back to GetUserNameA when GetUserNameExA fails Aug 17, 2026
@Eugeny

Eugeny commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Thanks - I've updated it to fall back to GetUserNameA to match what putty is actually doing

@Eugeny

Eugeny commented Aug 17, 2026

Copy link
Copy Markdown
Owner

@all-contributors add @cwatanab for code

@allcontributors

Copy link
Copy Markdown
Contributor

@Eugeny

We had trouble processing your request. Please try again later.

@Eugeny
Eugeny merged commit 2d1ca1d into Eugeny:main Aug 17, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants