Skip to content

fix(install): trust the local machine's built-in Administrator; name untrusted owners (#1705, #2023, #1686) - #2139

Open
DeusData wants to merge 3 commits into
mainfrom
fix/decision-b-win-sid-trust
Open

fix(install): trust the local machine's built-in Administrator; name untrusted owners (#1705, #2023, #1686)#2139
DeusData wants to merge 3 commits into
mainfrom
fix/decision-b-win-sid-trust

Conversation

@DeusData

@DeusData DeusData commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Problem

On Windows, an install/daemon runtime directory created by an elevated process is owned by the built-in Administrator account (RID 500 under the local machine account-domain SID) — even when that account is renamed or disabled. cbm's directory-owner/ACL trust refused it, so install/activation failed on those machines (#1705). Separately, an owner-trust refusal reported only a terse status -3, os 0, giving the operator nothing to act on (#2023, #1686).

Fix

#1705 — resolve this machine's built-in Administrator SID and trust it as a directory owner/grantee:
LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) + LsaQueryInformationPolicy(PolicyAccountDomainInformation)CreateWellKnownSid(WinAccountAdministratorSid, accountDomainSid), cached once per process (fail-closed on any LSA/synthesis failure). Wired into the daemon's win_sid_trusted and the CLI activation transaction's owner + ACE trust. owner-not-current-user (the exact-owner target rule) is left unchanged.

It is deliberately not IsWellKnownSid(WinAccountAdministratorSid) and not a trailing-RID-500 match — both would accept a foreign S-1-5-21-*-500 (a domain admin, or another machine's Administrator), a cross-machine trust escalation. PolicyAccountDomainInformation is the local SAM domain (not PolicyPrimaryDomainInformation = the AD domain), so on a domain-joined workstation a domain admin's -500 is foreign and rejected.

#2023 / #1686 — an owner-trust refusal now appends the offending owner's SID string to the note (the path was already carried).

Scope notes (by design)

  • Domain controller: a DC has no separate local SAM, so its account domain is the AD domain — there, this trusts the domain Administrator. On a DC that account is the machine-equivalent top admin, so this is consistent with the intent.
  • Cloned images: an un-sysprepped Windows clone shares the machine account-domain SID, so a sibling clone's built-in Administrator would be non-foreign. Inherent to any machine-SID-based identity.

Verification (native Windows arm64 VM)

Adversarially reviewed as a security-boundary change: the foreign--500 bypass does not materialize on a domain-joined machine (local SAM domain), the resolution is fail-closed, and the foreign--500 rejection is confirmed by an independently-derived test SID.

DeusData and others added 3 commits September 10, 2026 00:40
…untrusted owners (#1705, #2023, #1686)

Windows install/daemon runtime directories created by an elevated process are
owned by the built-in Administrator ACCOUNT (RID 500 under the local machine
account-domain SID), even when that account is renamed or disabled. cbm's
directory-owner/ACL trust refused it, breaking install/activation on such
machines.

#1705: resolve THIS machine's built-in Administrator SID via LSA
(LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) +
LsaQueryInformationPolicy(PolicyAccountDomainInformation) ->
CreateWellKnownSid(WinAccountAdministratorSid, accountDomainSid)), cached once
per process, and accept it as a trusted owner/grantee in the daemon
(win_sid_trusted) and the CLI activation transaction. Resolution is
deliberately NOT IsWellKnownSid(WinAccountAdministratorSid) and NOT a
trailing-RID-500 match: both accept a FOREIGN S-1-5-21-*-500 (a domain
administrator, or another machine's built-in Administrator), which would be a
cross-machine trust escalation. Any LSA or synthesis failure caches "none" and
grants no tolerance (fail closed). owner-not-current-user (the exact-owner
target rule) is unchanged.

#2023/#1686: an owner-trust refusal now names the offending owner SID (the path
was already carried), so a terse "status -3, os 0" becomes actionable.

Scope notes: on a domain controller -- which has no separate local SAM, so its
account domain IS the AD domain -- this trusts the domain Administrator, by
design (on a DC that account is the machine-equivalent top admin). An
un-sysprepped cloned Windows image shares the machine account-domain SID, so a
sibling clone's built-in Administrator would be non-foreign; this is inherent
to machine-SID identity.

Verified on a native Windows (arm64) VM: compiles under the sanitized build;
the daemon_ipc SID-trust test passes (local RID-500 trusted, a fabricated
foreign S-1-5-21-*-500 rejected, BUILTIN\Administrators trusted) at 35 passed /
0 failed with the fix, and 34 passed / 1 failed (ASSERT(local_ok)) with the
trust clause reverted -- the test binds precisely to the fix. #1856 (stock
ancestor ACEs): the Windows ancestor-ACL guards already pass; no defect
reproduced, no code change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The LSA typedefs and GetProcAddress casts in the #1705 local-Administrator
resolver were formatted with a different clang-format; CI clang-format-20
(the lint leg) flagged the line-wrapping. Reformatted only those lines with
the CI binary; no logic change.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
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.

1 participant