git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] mingw: special-case administrators even more
@ 2025-03-25 10:38 Johannes Schindelin via GitGitGadget
  2025-03-25 10:38 ` [PATCH 1/2] " Johannes Schindelin via GitGitGadget
  2025-03-25 10:38 ` [PATCH 2/2] test-tool path-utils: support debugging "dubious ownership" issues Johannes Schindelin via GitGitGadget
  0 siblings, 2 replies; 3+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2025-03-25 10:38 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin

On Windows, a file created by a process running in elevated mode is owned by
the Administrators group (not by the user's account who would otherwise be
able to modify or delete the file in non-elevated mode). Let's adjust the
"safe directory" feature accordingly.

Naturally, this patch series does not add a regression test (because it
can't, you cannot automate elevating processes).

This patch series is a companion of
https://github.com/microsoft/git/pull/712.

Johannes Schindelin (2):
  mingw: special-case administrators even more
  test-tool path-utils: support debugging "dubious ownership" issues

 compat/mingw.c             | 39 +++++++++++++++++++++++++++-----------
 t/helper/test-path-utils.c | 19 +++++++++++++++++++
 2 files changed, 47 insertions(+), 11 deletions(-)


base-commit: 683c54c999c301c2cd6f715c411407c413b1d84e
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1893%2Fdscho%2Fadmins-are-admins-on-windows-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1893/dscho/admins-are-admins-on-windows-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1893
-- 
gitgitgadget

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] mingw: special-case administrators even more
  2025-03-25 10:38 [PATCH 0/2] mingw: special-case administrators even more Johannes Schindelin via GitGitGadget
@ 2025-03-25 10:38 ` Johannes Schindelin via GitGitGadget
  2025-03-25 10:38 ` [PATCH 2/2] test-tool path-utils: support debugging "dubious ownership" issues Johannes Schindelin via GitGitGadget
  1 sibling, 0 replies; 3+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2025-03-25 10:38 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

The check for dubious ownership has one particular quirk on Windows: if
running as an administrator, files owned by the Administrators _group_
are considered owned by the user.

The rationale for that is: When running in elevated mode, Git creates
files that aren't owned by the individual user but by the Administrators
group.

There is yet another quirk, though: The check I introduced to determine
whether the current user is an administrator uses the
`CheckTokenMembership()` function with the current process token. And
that check only succeeds when running in elevated mode!

Let's be a bit more lenient here and look harder whether the current
user is an administrator. We do this by looking for a so-called "linked
token". That token exists when administrators run in non-elevated mode,
and can be used to create a new process in elevated mode. And feeding
_that_ token to the `CheckTokenMembership()` function succeeds!

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 compat/mingw.c | 39 ++++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/compat/mingw.c b/compat/mingw.c
index f524c54d06d..305a999f1fc 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -2826,31 +2826,44 @@ static void setup_windows_environment(void)
 	}
 }
 
-static PSID get_current_user_sid(void)
+static void get_current_user_sid(PSID *sid, HANDLE *linked_token)
 {
 	HANDLE token;
 	DWORD len = 0;
-	PSID result = NULL;
+	TOKEN_ELEVATION_TYPE elevationType;
+	DWORD size;
+
+	*sid = NULL;
+	*linked_token = NULL;
 
 	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
-		return NULL;
+		return;
 
 	if (!GetTokenInformation(token, TokenUser, NULL, 0, &len)) {
 		TOKEN_USER *info = xmalloc((size_t)len);
 		if (GetTokenInformation(token, TokenUser, info, len, &len)) {
 			len = GetLengthSid(info->User.Sid);
-			result = xmalloc(len);
-			if (!CopySid(len, result, info->User.Sid)) {
+			*sid = xmalloc(len);
+			if (!CopySid(len, *sid, info->User.Sid)) {
 				error(_("failed to copy SID (%ld)"),
 				      GetLastError());
-				FREE_AND_NULL(result);
+				FREE_AND_NULL(*sid);
 			}
 		}
 		FREE_AND_NULL(info);
 	}
-	CloseHandle(token);
 
-	return result;
+	if (GetTokenInformation(token, TokenElevationType, &elevationType, sizeof(elevationType), &size) &&
+	    elevationType == TokenElevationTypeLimited) {
+		/*
+		 * The current process is run by a member of the Administrators
+		 * group, but is not running elevated.
+		 */
+		if (!GetTokenInformation(token, TokenLinkedToken, linked_token, sizeof(*linked_token), &size))
+			linked_token = NULL; /* there is no linked token */
+	}
+
+	CloseHandle(token);
 }
 
 static BOOL user_sid_to_user_name(PSID sid, LPSTR *str)
@@ -2931,18 +2944,22 @@ int is_path_owned_by_current_sid(const char *path, struct strbuf *report)
 	else if (sid && IsValidSid(sid)) {
 		/* Now, verify that the SID matches the current user's */
 		static PSID current_user_sid;
+		static HANDLE linked_token;
 		BOOL is_member;
 
 		if (!current_user_sid)
-			current_user_sid = get_current_user_sid();
+			get_current_user_sid(&current_user_sid, &linked_token);
 
 		if (current_user_sid &&
 		    IsValidSid(current_user_sid) &&
 		    EqualSid(sid, current_user_sid))
 			result = 1;
 		else if (IsWellKnownSid(sid, WinBuiltinAdministratorsSid) &&
-			 CheckTokenMembership(NULL, sid, &is_member) &&
-			 is_member)
+			 ((CheckTokenMembership(NULL, sid, &is_member) &&
+			   is_member) ||
+			  (linked_token &&
+			   CheckTokenMembership(linked_token, sid, &is_member) &&
+			   is_member)))
 			/*
 			 * If owned by the Administrators group, and the
 			 * current user is an administrator, we consider that
-- 
gitgitgadget


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] test-tool path-utils: support debugging "dubious ownership" issues
  2025-03-25 10:38 [PATCH 0/2] mingw: special-case administrators even more Johannes Schindelin via GitGitGadget
  2025-03-25 10:38 ` [PATCH 1/2] " Johannes Schindelin via GitGitGadget
@ 2025-03-25 10:38 ` Johannes Schindelin via GitGitGadget
  1 sibling, 0 replies; 3+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2025-03-25 10:38 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

This adds a new sub-sub-command for `test-tool`, simply passing through
the command-line arguments to the `is_path_owned_by_current_user()`
function.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 t/helper/test-path-utils.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c
index 72ac8d1b1b0..f3c59e50285 100644
--- a/t/helper/test-path-utils.c
+++ b/t/helper/test-path-utils.c
@@ -504,6 +504,25 @@ int cmd__path_utils(int argc, const char **argv)
 		return !!res;
 	}
 
+	if (argc > 1 && !strcmp(argv[1], "is_path_owned_by_current_user")) {
+		int res = 0;
+
+		for (int i = 2; i < argc; i++) {
+			struct strbuf buf = STRBUF_INIT;
+
+			if (is_path_owned_by_current_user(argv[i], &buf))
+				printf("'%s' is owned by current SID\n", argv[i]);
+			else {
+				printf("'%s' is not owned by current SID: %s\n", argv[i], buf.buf);
+				res = 1;
+			}
+
+			strbuf_release(&buf);
+		}
+
+		return res;
+	}
+
 	fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
 		argv[1] ? argv[1] : "(there was none)");
 	return 1;
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-03-25 10:38 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-25 10:38 [PATCH 0/2] mingw: special-case administrators even more Johannes Schindelin via GitGitGadget
2025-03-25 10:38 ` [PATCH 1/2] " Johannes Schindelin via GitGitGadget
2025-03-25 10:38 ` [PATCH 2/2] test-tool path-utils: support debugging "dubious ownership" issues Johannes Schindelin via GitGitGadget

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).