|
2 | 2 | #include "win32.h" |
3 | 3 | #include <conio.h> |
4 | 4 | #include <wchar.h> |
5 | | -#include <aclapi.h> |
6 | | -#include <sddl.h> |
7 | 5 | #include <winioctl.h> |
8 | 6 | #include "../strbuf.h" |
9 | 7 | #include "../run-command.h" |
@@ -3299,188 +3297,6 @@ int uname(struct utsname *buf) |
3299 | 3297 | return 0; |
3300 | 3298 | } |
3301 | 3299 |
|
3302 | | -/* |
3303 | | - * Determines whether the SID refers to an administrator or the current user. |
3304 | | - * |
3305 | | - * For convenience, the `info` parameter allows avoiding multiple calls to |
3306 | | - * `OpenProcessToken()` if this function is called more than once. The initial |
3307 | | - * value of `*info` is expected to be `NULL`, and it needs to be released via |
3308 | | - * `free()` after the last call to this function. |
3309 | | - * |
3310 | | - * Returns 0 if the SID indicates a dubious owner of system files, otherwise 1. |
3311 | | - */ |
3312 | | -static int is_valid_system_file_owner(PSID sid, TOKEN_USER **info) |
3313 | | -{ |
3314 | | - HANDLE token; |
3315 | | - DWORD len; |
3316 | | - char builtin_administrators_sid[SECURITY_MAX_SID_SIZE]; |
3317 | | - |
3318 | | - if (IsWellKnownSid(sid, WinBuiltinAdministratorsSid) || |
3319 | | - IsWellKnownSid(sid, WinLocalSystemSid)) |
3320 | | - return 1; |
3321 | | - |
3322 | | - /* Obtain current user's SID */ |
3323 | | - if (!*info && |
3324 | | - OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) { |
3325 | | - if (!GetTokenInformation(token, TokenUser, NULL, 0, &len)) { |
3326 | | - *info = xmalloc((size_t)len); |
3327 | | - if (!GetTokenInformation(token, TokenUser, *info, len, |
3328 | | - &len)) |
3329 | | - FREE_AND_NULL(*info); |
3330 | | - } |
3331 | | - CloseHandle(token); |
3332 | | - } |
3333 | | - |
3334 | | - if (*info && EqualSid(sid, (*info)->User.Sid)) |
3335 | | - return 1; |
3336 | | - |
3337 | | - /* Is the owner at least a member of BUILTIN\Administrators? */ |
3338 | | - len = ARRAY_SIZE(builtin_administrators_sid); |
3339 | | - if (CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, |
3340 | | - builtin_administrators_sid, &len)) { |
3341 | | - wchar_t name[256], domain[256]; |
3342 | | - DWORD name_size = ARRAY_SIZE(name); |
3343 | | - DWORD domain_size = ARRAY_SIZE(domain); |
3344 | | - SID_NAME_USE type; |
3345 | | - PSID *members; |
3346 | | - DWORD dummy, i; |
3347 | | - /* |
3348 | | - * We avoid including the `lm.h` header and linking to |
3349 | | - * `netapi32.dll` directly, in favor of lazy-loading that DLL |
3350 | | - * when, and _only_ when, needed. |
3351 | | - */ |
3352 | | - DECLARE_PROC_ADDR(netapi32.dll, DWORD, |
3353 | | - NetLocalGroupGetMembers, LPCWSTR, |
3354 | | - LPCWSTR, DWORD, LPVOID, DWORD, |
3355 | | - LPDWORD, LPDWORD, PDWORD_PTR); |
3356 | | - DECLARE_PROC_ADDR(netapi32.dll, DWORD, |
3357 | | - NetApiBufferFree, LPVOID); |
3358 | | - |
3359 | | - if (LookupAccountSidW(NULL, builtin_administrators_sid, |
3360 | | - name, &name_size, domain, &domain_size, |
3361 | | - &type) && |
3362 | | - INIT_PROC_ADDR(NetLocalGroupGetMembers) && |
3363 | | - /* |
3364 | | - * Technically, `NetLocalGroupGetMembers()` wants to assign |
3365 | | - * an array of type `LOCALGROUP_MEMBERS_INFO_0`, which |
3366 | | - * however contains only one field of type `PSID`, |
3367 | | - * therefore we can pretend that it is an array over the |
3368 | | - * type `PSID`. |
3369 | | - * |
3370 | | - * Also, we simply ignore the condition where |
3371 | | - * `ERROR_MORE_DATA` is returned; This should not happen |
3372 | | - * anyway, as we are passing `-1` as `prefmaxlen` |
3373 | | - * parameter, which is equivalent to the constant |
3374 | | - * `MAX_PREFERRED_LENGTH`. |
3375 | | - */ |
3376 | | - !NetLocalGroupGetMembers(NULL, name, 0, &members, -1, |
3377 | | - &len, &dummy, NULL)) { |
3378 | | - for (i = 0; i < len; i++) |
3379 | | - if (EqualSid(sid, members[i])) |
3380 | | - break; |
3381 | | - |
3382 | | - if (INIT_PROC_ADDR(NetApiBufferFree)) |
3383 | | - NetApiBufferFree(members); |
3384 | | - |
3385 | | - /* Did we find the `sid` in the members? */ |
3386 | | - return i < len; |
3387 | | - } |
3388 | | - } |
3389 | | - |
3390 | | - return 0; |
3391 | | -} |
3392 | | - |
3393 | | -/* |
3394 | | - * Verify that the file in question is owned by an administrator or system |
3395 | | - * account, or at least by the current user. |
3396 | | - * |
3397 | | - * This function returns 1 if successful, 0 if the file is not owned by any of |
3398 | | - * these, or -1 on error. |
3399 | | - */ |
3400 | | -static int validate_system_file_ownership(const char *path) |
3401 | | -{ |
3402 | | - WCHAR wpath[MAX_LONG_PATH]; |
3403 | | - PSID owner_sid = NULL, problem_sid = NULL; |
3404 | | - PSECURITY_DESCRIPTOR descriptor = NULL; |
3405 | | - TOKEN_USER* info = NULL; |
3406 | | - DWORD err; |
3407 | | - int ret; |
3408 | | - |
3409 | | - if (xutftowcs_long_path(wpath, path) < 0) |
3410 | | - return -1; |
3411 | | - |
3412 | | - err = GetNamedSecurityInfoW(wpath, SE_FILE_OBJECT, |
3413 | | - OWNER_SECURITY_INFORMATION | |
3414 | | - DACL_SECURITY_INFORMATION, |
3415 | | - &owner_sid, NULL, NULL, NULL, &descriptor); |
3416 | | - |
3417 | | - /* if the file does not exist, it does not have a valid owner */ |
3418 | | - if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) |
3419 | | - ret = 0; |
3420 | | - else if (err != ERROR_SUCCESS) |
3421 | | - ret = error(_("failed to validate '%s' (%ld)"), path, err); |
3422 | | - else if (!IsValidSid(owner_sid)) |
3423 | | - ret = error(_("invalid owner: '%s'"), path); |
3424 | | - else if (is_valid_system_file_owner(owner_sid, &info)) |
3425 | | - ret = 1; |
3426 | | - else { |
3427 | | - ret = 0; |
3428 | | - problem_sid = owner_sid; |
3429 | | - } |
3430 | | - |
3431 | | - if (!ret && problem_sid) { |
3432 | | -#define MAX_NAME_OR_DOMAIN 256 |
3433 | | - wchar_t name[MAX_NAME_OR_DOMAIN]; |
3434 | | - wchar_t domain[MAX_NAME_OR_DOMAIN]; |
3435 | | - wchar_t *p = NULL; |
3436 | | - DWORD size = MAX_NAME_OR_DOMAIN; |
3437 | | - SID_NAME_USE type; |
3438 | | - char utf[3 * MAX_NAME_OR_DOMAIN + 1]; |
3439 | | - |
3440 | | - if (!LookupAccountSidW(NULL, problem_sid, name, &size, |
3441 | | - domain, &size, &type) || |
3442 | | - xwcstoutf(utf, name, ARRAY_SIZE(utf)) < 0) { |
3443 | | - if (!ConvertSidToStringSidW(problem_sid, &p)) |
3444 | | - strlcpy(utf, "(unknown)", ARRAY_SIZE(utf)); |
3445 | | - else { |
3446 | | - if (xwcstoutf(utf, p, ARRAY_SIZE(utf)) < 0) |
3447 | | - strlcpy(utf, "(some user)", |
3448 | | - ARRAY_SIZE(utf)); |
3449 | | - LocalFree(p); |
3450 | | - } |
3451 | | - } |
3452 | | - |
3453 | | - warning(_("'%s' has a dubious owner: '%s'.\n" |
3454 | | - "For security reasons, it is therefore ignored.\n" |
3455 | | - "To fix this, please transfer ownership to an " |
3456 | | - "admininstrator."), |
3457 | | - path, utf); |
3458 | | - } |
3459 | | - |
3460 | | - if (descriptor) |
3461 | | - LocalFree(descriptor); |
3462 | | - free(info); |
3463 | | - |
3464 | | - return ret; |
3465 | | -} |
3466 | | - |
3467 | | -const char *program_data_config(void) |
3468 | | -{ |
3469 | | - static struct strbuf path = STRBUF_INIT; |
3470 | | - static unsigned initialized; |
3471 | | - |
3472 | | - if (!initialized) { |
3473 | | - const char *env = mingw_getenv("PROGRAMDATA"); |
3474 | | - if (env) { |
3475 | | - strbuf_addf(&path, "%s/Git/config", env); |
3476 | | - if (validate_system_file_ownership(path.buf) != 1) |
3477 | | - strbuf_setlen(&path, 0); |
3478 | | - } |
3479 | | - initialized = 1; |
3480 | | - } |
3481 | | - return *path.buf ? path.buf : NULL; |
3482 | | -} |
3483 | | - |
3484 | 3300 | /* |
3485 | 3301 | * Based on https://stackoverflow.com/questions/43002803 |
3486 | 3302 | * |
|
0 commit comments