Skip to content

Fix clone ownership under Windows Administrator Protection#2039

Draft
tyrielv wants to merge 1 commit into
microsoft:masterfrom
tyrielv:tyrielv/fix-ap-clone-ownership
Draft

Fix clone ownership under Windows Administrator Protection#2039
tyrielv wants to merge 1 commit into
microsoft:masterfrom
tyrielv:tyrielv/fix-ap-clone-ownership

Conversation

@tyrielv

@tyrielv tyrielv commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Problem

Under Windows Administrator protection (AP), an elevated process runs as a hidden, profile-separated shadow admin account (MACHINE\admin_<user>) whose SID is a local account (S-1-5-21-…) that differs from the real, non-elevated user's SID.

When gvfs clone runs elevated, the enlistment's src and .git directories are created owned by the Administrators group. EnsureDirectoryIsOwnedByCurrentUser then reassigned ownership to the current user to satisfy git's dubious-ownership check. Under AP the "current user" is the shadow admin, so ownership was set to admin_<user>.

The real (non-elevated) user then hits:

fatal: detected dubious ownership in repository

because git's Administrators-group-membership grace does not cover another specific user's SID, and the shadow admin cannot SetOwner to the real user's SID either.

Fix

Detect AP via HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System!TypeOfAdminApprovalMode == 2. When AP is active, leave the directory owner as the Administrators group instead of reassigning it to the shadow admin.

An Administrators-owned directory is accepted by modern git and the libgit2 non-elevated-admin-owner overlay for any Administrators member — the real user, the shadow admin, and SYSTEM (for automount) alike. So skipping the reassignment under AP is correct for every consumer.

When AP is not active, behavior is unchanged (owner reassigned to the current user, as before).

Changes

  • GVFS.Platform.Windows/WindowsPlatform.cs — add IsAdminApprovalModeEnabled() (reads TypeOfAdminApprovalMode).
  • GVFS.Platform.Windows/WindowsFileSystem.cs — in EnsureDirectoryIsOwnedByCurrentUser, skip the Administrators→current-user reassignment when AP is active.

Testing

  • Builds clean (GVFS.Platform.Windows, 0 warnings / 0 errors).
  • Manual validation under a real AP machine is pending (requires enabling AP + reboot). The AP constraints this fix relies on were empirically verified on an AP machine in prior investigation.

Related

  • Follow-up to the SpringBoard DoubleCheck AP change (ADO PR 16074604, AB#62918022) — this PR owns the GVFS/VFSForGit side.
  • Original elevated-clone ownership fix: Fix ownership when cloning elevated #1829 (4e23d28a).

Under Windows "Administrator protection" (AP), an elevated process runs as a
hidden, profile-separated shadow admin account (MACHINE\admin_<user>) whose SID
is a local account (S-1-5-21-...) that differs from the real (non-elevated)
user's SID.

When `gvfs clone` runs elevated, the enlistment's `src` and `.git` directories
are created owned by the Administrators group. EnsureDirectoryIsOwnedByCurrentUser
then reassigned ownership to the current user to satisfy git's dubious-ownership
check. Under AP the "current user" is the shadow admin, so ownership was set to
admin_<user> — which the real user does not match. The real (non-elevated) user
then hit `fatal: detected dubious ownership`, because git's Administrators-group
membership grace does not cover another specific user's SID, and the shadow admin
cannot SetOwner to the real user's SID either.

Detect the AP shadow admin from the running process's own token — its effective
elevation identity — and, when present, leave the directory owner as the
Administrators group instead of reassigning it to the shadow admin. An
Administrators-owned directory is accepted by modern git and the libgit2
non-elevated-admin-owner overlay for any Administrators member — the real user,
the shadow admin, and SYSTEM (for automount) alike.

Detection inspects the token rather than the TypeOfAdminApprovalMode policy value
so it stays correct across an AP policy change that has not yet been rebooted
(where the policy value is pending but elevation still yields a shadow admin). A
shadow admin is identified as a local account SID (S-1-5-21-...) whose ProfileList
profile directory is ADMIN_-prefixed; the real interactive user (a domain or
Entra ID account) is excluded.

Assisted-by: Claude Opus 4.8
Signed-off-by: Tyrie Vella <tyrielv@gmail.com>
@tyrielv tyrielv force-pushed the tyrielv/fix-ap-clone-ownership branch from a251e89 to 8164d13 Compare July 3, 2026 03:39
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