summaryrefslogtreecommitdiff
path: root/compat/mingw.c
diff options
context:
space:
mode:
authorJiang Xin <worldhello.net@gmail.com>2022-04-13 14:51:53 +0800
committerJiang Xin <worldhello.net@gmail.com>2022-04-13 14:51:53 +0800
commit61de00a32115b6090891f20797fdfd1501709ab9 (patch)
treee6a0290cef9e52589a8b78e55dbae3daf559e202 /compat/mingw.c
parentdfbdf52df590cf8af37b193d9bf9f9a41162f3ae (diff)
parent11cfe552610386954886543f5de87dcc49ad5735 (diff)
Merge branch 'master' of github.com:git/git
* 'master' of github.com:git/git: (25 commits) Git 2.36-rc2 i18n: fix some badly formatted i18n strings Git 2.36-rc1 t9902: split test to run on appropriate systems ls-tree doc: document interaction with submodules Documentation: add --batch-command to cat-file synopsis git-ls-tree.txt: fix the name of "%(objectsize:padded)" submodule-helper: fix usage string doc: replace "--" with {litdd} in credential-cache/fsmonitor contrib/scalar: fix 'all' target in Makefile Documentation/Makefile: fix "make info" regression in dad9cd7d518 configure.ac: fix HAVE_SYNC_FILE_RANGE definition git-compat-util: really support openssl as a source of entropy ls-tree: `-l` should not imply recursive listing Git 2.35.2 Git 2.34.2 Git 2.33.2 Git 2.32.1 Git 2.31.2 Git 2.30.3 ...
Diffstat (limited to 'compat/mingw.c')
-rw-r--r--compat/mingw.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/compat/mingw.c b/compat/mingw.c
index 58f347d6ae..6fe80fdf01 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1,5 +1,6 @@
#include "../git-compat-util.h"
#include "win32.h"
+#include <aclapi.h>
#include <conio.h>
#include <wchar.h>
#include "../strbuf.h"
@@ -2645,6 +2646,92 @@ static void setup_windows_environment(void)
}
}
+static PSID get_current_user_sid(void)
+{
+ HANDLE token;
+ DWORD len = 0;
+ PSID result = NULL;
+
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
+ return NULL;
+
+ 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)) {
+ error(_("failed to copy SID (%ld)"),
+ GetLastError());
+ FREE_AND_NULL(result);
+ }
+ }
+ FREE_AND_NULL(info);
+ }
+ CloseHandle(token);
+
+ return result;
+}
+
+int is_path_owned_by_current_sid(const char *path)
+{
+ WCHAR wpath[MAX_PATH];
+ PSID sid = NULL;
+ PSECURITY_DESCRIPTOR descriptor = NULL;
+ DWORD err;
+
+ static wchar_t home[MAX_PATH];
+
+ int result = 0;
+
+ if (xutftowcs_path(wpath, path) < 0)
+ return 0;
+
+ /*
+ * On Windows, the home directory is owned by the administrator, but for
+ * all practical purposes, it belongs to the user. Do pretend that it is
+ * owned by the user.
+ */
+ if (!*home) {
+ DWORD size = ARRAY_SIZE(home);
+ DWORD len = GetEnvironmentVariableW(L"HOME", home, size);
+ if (!len || len > size)
+ wcscpy(home, L"::N/A::");
+ }
+ if (!wcsicmp(wpath, home))
+ return 1;
+
+ /* Get the owner SID */
+ err = GetNamedSecurityInfoW(wpath, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION,
+ &sid, NULL, NULL, NULL, &descriptor);
+
+ if (err != ERROR_SUCCESS)
+ error(_("failed to get owner for '%s' (%ld)"), path, err);
+ else if (sid && IsValidSid(sid)) {
+ /* Now, verify that the SID matches the current user's */
+ static PSID current_user_sid;
+
+ if (!current_user_sid)
+ current_user_sid = get_current_user_sid();
+
+ if (current_user_sid &&
+ IsValidSid(current_user_sid) &&
+ EqualSid(sid, current_user_sid))
+ result = 1;
+ }
+
+ /*
+ * We can release the security descriptor struct only now because `sid`
+ * actually points into this struct.
+ */
+ if (descriptor)
+ LocalFree(descriptor);
+
+ return result;
+}
+
int is_valid_win32_path(const char *path, int allow_literal_nul)
{
const char *p = path;