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
Open
fix(install): trust the local machine's built-in Administrator; name untrusted owners (#1705, #2023, #1686)#2139DeusData wants to merge 3 commits into
DeusData wants to merge 3 commits into
Conversation
…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>
…d-trust # Conflicts: # src/daemon/ipc.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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'swin_sid_trustedand 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 foreignS-1-5-21-*-500(a domain admin, or another machine's Administrator), a cross-machine trust escalation.PolicyAccountDomainInformationis the local SAM domain (notPolicyPrimaryDomainInformation= the AD domain), so on a domain-joined workstation a domain admin's-500is 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)
Verification (native Windows arm64 VM)
ntsecapi.h/LSA types resolve).daemon_ipcSID-trust test: 35 passed / 0 failed with the fix — local RID-500 trusted, a fabricated foreignS-1-5-21-111-222-333-500rejected,BUILTIN\Administratorstrusted.ASSERT(local_ok)attest_daemon_ipc.c:1032) — exactly the SID-trust test flips.Adversarially reviewed as a security-boundary change: the foreign-
-500bypass does not materialize on a domain-joined machine (local SAM domain), the resolution is fail-closed, and the foreign--500rejection is confirmed by an independently-derived test SID.