Skip to content

Commit 48dffd2

Browse files
committed
fixup! Windows: add support for a Windows-wide configuration
We need to make sure that MinGit/Portable Git only pick up a legitimate ProgramData config. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 0567afb commit 48dffd2

File tree

1 file changed

+106
-1
lines changed

1 file changed

+106
-1
lines changed

compat/mingw.c

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <conio.h>
44
#include <wchar.h>
55
#include <winioctl.h>
6+
#include <aclapi.h>
7+
#include <sddl.h>
68
#include "../strbuf.h"
79
#include "../run-command.h"
810
#include "../cache.h"
@@ -3297,15 +3299,118 @@ int uname(struct utsname *buf)
32973299
return 0;
32983300
}
32993301

3302+
/*
3303+
* Verify that the file in question is owned by an administrator or system
3304+
* account, or at least by the current user.
3305+
*
3306+
* This function returns 1 if successful, 0 if the file is not owned by any of
3307+
* these, or -1 on error.
3308+
*/
3309+
static int validate_system_file_ownership(const char *path)
3310+
{
3311+
WCHAR wpath[MAX_LONG_PATH];
3312+
PSID owner_sid = NULL;
3313+
PSECURITY_DESCRIPTOR descriptor = NULL;
3314+
HANDLE token;
3315+
TOKEN_USER* info;
3316+
DWORD err, len;
3317+
int ret;
3318+
3319+
if (xutftowcs_long_path(wpath, path) < 0)
3320+
return -1;
3321+
3322+
err = GetNamedSecurityInfoW(wpath, SE_FILE_OBJECT,
3323+
OWNER_SECURITY_INFORMATION |
3324+
DACL_SECURITY_INFORMATION,
3325+
&owner_sid, NULL, NULL, NULL, &descriptor);
3326+
3327+
/* if the file does not exist, it does not have a valid owner */
3328+
if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) {
3329+
ret = 0;
3330+
owner_sid = NULL;
3331+
goto finish_validation;
3332+
}
3333+
3334+
if (err != ERROR_SUCCESS) {
3335+
ret = error(_("failed to validate '%s' (%ld)"), path, err);
3336+
owner_sid = NULL;
3337+
goto finish_validation;
3338+
}
3339+
3340+
if (!IsValidSid(owner_sid)) {
3341+
ret = error(_("invalid owner: '%s'"), path);
3342+
goto finish_validation;
3343+
}
3344+
3345+
if (IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) ||
3346+
IsWellKnownSid(owner_sid, WinLocalSystemSid)) {
3347+
ret = 1;
3348+
goto finish_validation;
3349+
}
3350+
3351+
/* Obtain current user's SID */
3352+
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) &&
3353+
!GetTokenInformation(token, TokenUser, NULL, 0, &len)) {
3354+
info = xmalloc((size_t)len);
3355+
if (!GetTokenInformation(token, TokenUser, info, len, &len))
3356+
FREE_AND_NULL(info);
3357+
}
3358+
3359+
if (!info)
3360+
ret = 0;
3361+
else {
3362+
ret = EqualSid(owner_sid, info->User.Sid) ? 1 : 0;
3363+
free(info);
3364+
}
3365+
3366+
finish_validation:
3367+
if (!ret && owner_sid) {
3368+
#define MAX_NAME_OR_DOMAIN 256
3369+
wchar_t owner_name[MAX_NAME_OR_DOMAIN];
3370+
wchar_t owner_domain[MAX_NAME_OR_DOMAIN];
3371+
wchar_t *p = NULL;
3372+
DWORD size = MAX_NAME_OR_DOMAIN;
3373+
SID_NAME_USE type;
3374+
char name[3 * MAX_NAME_OR_DOMAIN + 1];
3375+
3376+
if (!LookupAccountSidW(NULL, owner_sid, owner_name, &size,
3377+
owner_domain, &size, &type) ||
3378+
xwcstoutf(name, owner_name, ARRAY_SIZE(name)) < 0) {
3379+
if (!ConvertSidToStringSidW(owner_sid, &p))
3380+
strlcpy(name, "(unknown)", ARRAY_SIZE(name));
3381+
else {
3382+
if (xwcstoutf(name, p, ARRAY_SIZE(name)) < 0)
3383+
strlcpy(name, "(some user)",
3384+
ARRAY_SIZE(name));
3385+
LocalFree(p);
3386+
}
3387+
}
3388+
3389+
warning(_("'%s' has a dubious owner: '%s'.\n"
3390+
"For security reasons, it is therefore ignored.\n"
3391+
"To fix this, please transfer ownership to an "
3392+
"admininstrator."),
3393+
path, name);
3394+
}
3395+
3396+
if (descriptor)
3397+
LocalFree(descriptor);
3398+
3399+
return ret;
3400+
}
3401+
33003402
const char *program_data_config(void)
33013403
{
33023404
static struct strbuf path = STRBUF_INIT;
33033405
static unsigned initialized;
33043406

33053407
if (!initialized) {
33063408
const char *env = mingw_getenv("PROGRAMDATA");
3307-
if (env)
3409+
if (env) {
33083410
strbuf_addf(&path, "%s/Git/config", env);
3411+
if (validate_system_file_ownership(path.buf) != 1)
3412+
strbuf_setlen(&path, 0);
3413+
}
33093414
initialized = 1;
33103415
}
33113416
return *path.buf ? path.buf : NULL;

0 commit comments

Comments
 (0)