diff options
author | Johannes Schindelin <johannes.schindelin@gmx.de> | 2022-03-17 10:57:43 +0100 |
---|---|---|
committer | Johannes Schindelin <johannes.schindelin@gmx.de> | 2022-03-24 00:31:32 +0100 |
commit | 303b876f76c2caccc9a289c4f14a2b2d3850684e (patch) | |
tree | 1a7e38217fac02c6f9251b78e1cb4d74101f76c7 /compat/mingw.c | |
parent | GIT-VERSION-GEN: bump to v2.33.1 (diff) | |
parent | Git 2.32.1 (diff) | |
download | tgif-303b876f76c2caccc9a289c4f14a2b2d3850684e.tar.xz |
Sync with 2.32.1
* maint-2.32:
Git 2.32.1
Git 2.31.2
Git 2.30.3
setup_git_directory(): add an owner check for the top-level directory
Add a function to determine whether a path is owned by the current user
Diffstat (limited to 'compat/mingw.c')
-rw-r--r-- | compat/mingw.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/compat/mingw.c b/compat/mingw.c index 9e0cd1e097..5e42191fa4 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" @@ -1083,6 +1084,7 @@ int pipe(int filedes[2]) return 0; } +#ifndef __MINGW64__ struct tm *gmtime_r(const time_t *timep, struct tm *result) { if (gmtime_s(result, timep) == 0) @@ -1096,6 +1098,7 @@ struct tm *localtime_r(const time_t *timep, struct tm *result) return result; return NULL; } +#endif char *mingw_getcwd(char *pointer, int len) { @@ -2622,6 +2625,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; |