diff options
author | Johannes Schindelin <johannes.schindelin@gmx.de> | 2022-03-17 12:57:31 +0300 |
---|---|---|
committer | Johannes Schindelin <johannes.schindelin@gmx.de> | 2022-03-24 02:24:29 +0300 |
commit | 6a2381a3e5176b8deb69c799ed2b600366d36d39 (patch) | |
tree | 9078babba9f51e3de0818cba5989c36cdff691d8 /compat | |
parent | 48bf2fa8bad054d66bd79c6ba903c89c704201f7 (diff) | |
parent | cb95038137e9e66fc6a6b4a0e8db62bcc521b709 (diff) |
Sync with 2.30.3
* maint-2.30:
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')
-rw-r--r-- | compat/mingw.c | 89 | ||||
-rw-r--r-- | compat/mingw.h | 7 |
2 files changed, 96 insertions, 0 deletions
diff --git a/compat/mingw.c b/compat/mingw.c index a43599841c..38ac35913d 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" @@ -1060,6 +1061,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) @@ -1073,6 +1075,7 @@ struct tm *localtime_r(const time_t *timep, struct tm *result) return result; return NULL; } +#endif char *mingw_getcwd(char *pointer, int len) { @@ -2599,6 +2602,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; diff --git a/compat/mingw.h b/compat/mingw.h index c9a52ad64a..ffa53a44b0 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -454,6 +454,13 @@ char *mingw_query_user_email(void); #endif /** + * Verifies that the specified path is owned by the user running the + * current process. + */ +int is_path_owned_by_current_sid(const char *path); +#define is_path_owned_by_current_user is_path_owned_by_current_sid + +/** * Verifies that the given path is a valid one on Windows. * * In particular, path segments are disallowed which |