Sync with 2.31.2
* maint-2.31: 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
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
#include "../git-compat-util.h"
|
||||
#include "win32.h"
|
||||
#include <aclapi.h>
|
||||
#include <conio.h>
|
||||
#include <wchar.h>
|
||||
#include "../strbuf.h"
|
||||
@ -1062,6 +1063,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)
|
||||
@ -1075,6 +1077,7 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
|
||||
return result;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *mingw_getcwd(char *pointer, int len)
|
||||
{
|
||||
@ -2601,6 +2604,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;
|
||||
|
Reference in New Issue
Block a user