|
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