Merge branch 'js/safe-directory-plus'

Platform-specific code that determines if a directory is OK to use
as a repository has been taught to report more details, especially
on Windows.

* js/safe-directory-plus:
  mingw: handle a file owned by the Administrators group correctly
  mingw: be more informative when ownership check fails on FAT32
  mingw: provide details about unsafe directories' ownership
  setup: prepare for more detailed "dubious ownership" messages
  setup: fix some formatting
This commit is contained in:
Junio C Hamano
2022-08-14 23:19:28 -07:00
4 changed files with 81 additions and 15 deletions

View File

@ -1,6 +1,7 @@
#include "../git-compat-util.h"
#include "win32.h"
#include <aclapi.h>
#include <sddl.h>
#include <conio.h>
#include <wchar.h>
#include "../strbuf.h"
@ -2670,7 +2671,22 @@ static PSID get_current_user_sid(void)
return result;
}
int is_path_owned_by_current_sid(const char *path)
static int acls_supported(const char *path)
{
size_t offset = offset_1st_component(path);
WCHAR wroot[MAX_PATH];
DWORD file_system_flags;
if (offset &&
xutftowcsn(wroot, path, MAX_PATH, offset) > 0 &&
GetVolumeInformationW(wroot, NULL, 0, NULL, NULL,
&file_system_flags, NULL, 0))
return !!(file_system_flags & FILE_PERSISTENT_ACLS);
return 0;
}
int is_path_owned_by_current_sid(const char *path, struct strbuf *report)
{
WCHAR wpath[MAX_PATH];
PSID sid = NULL;
@ -2709,6 +2725,7 @@ int is_path_owned_by_current_sid(const char *path)
else if (sid && IsValidSid(sid)) {
/* Now, verify that the SID matches the current user's */
static PSID current_user_sid;
BOOL is_member;
if (!current_user_sid)
current_user_sid = get_current_user_sid();
@ -2717,6 +2734,46 @@ int is_path_owned_by_current_sid(const char *path)
IsValidSid(current_user_sid) &&
EqualSid(sid, current_user_sid))
result = 1;
else if (IsWellKnownSid(sid, WinBuiltinAdministratorsSid) &&
CheckTokenMembership(NULL, sid, &is_member) &&
is_member)
/*
* If owned by the Administrators group, and the
* current user is an administrator, we consider that
* okay, too.
*/
result = 1;
else if (report &&
IsWellKnownSid(sid, WinWorldSid) &&
!acls_supported(path)) {
/*
* On FAT32 volumes, ownership is not actually recorded.
*/
strbuf_addf(report, "'%s' is on a file system that does"
"not record ownership\n", path);
} else if (report) {
LPSTR str1, str2, to_free1 = NULL, to_free2 = NULL;
if (ConvertSidToStringSidA(sid, &str1))
to_free1 = str1;
else
str1 = "(inconvertible)";
if (!current_user_sid)
str2 = "(none)";
else if (!IsValidSid(current_user_sid))
str2 = "(invalid)";
else if (ConvertSidToStringSidA(current_user_sid, &str2))
to_free2 = str2;
else
str2 = "(inconvertible)";
strbuf_addf(report,
"'%s' is owned by:\n"
"\t'%s'\nbut the current user is:\n"
"\t'%s'\n", path, str1, str2);
LocalFree(to_free1);
LocalFree(to_free2);
}
}
/*