diff options
author | Ron Yorston <rmy@pobox.com> | 2019-03-02 12:52:52 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2019-03-02 13:11:38 +0000 |
commit | cf46a1c167ce3d532b10e83b6cc2a1994ac09668 (patch) | |
tree | 75e59b882ddf5b0c570eb9f6c6cef609c7160021 | |
parent | d6a7bfff8a510bb4035fbd1cf29b555abff65b2f (diff) | |
download | busybox-w32-cf46a1c167ce3d532b10e83b6cc2a1994ac09668.tar.gz busybox-w32-cf46a1c167ce3d532b10e83b6cc2a1994ac09668.tar.bz2 busybox-w32-cf46a1c167ce3d532b10e83b6cc2a1994ac09668.zip |
win32: let stat(2) report numeric uids for local users
Further extend file identification so stat(2) returns the relative
identifier as a numeric uid for files with owner SIDs that look like
a local or domain user.
See:
https://blogs.technet.microsoft.com/markrussinovich/2009/11/03/the-machine-sid-duplication-myth-and-why-sysprep-matters/
https://cygwin.com/cygwin-ug-net/ntsec.html
-rw-r--r-- | include/mingw.h | 4 | ||||
-rw-r--r-- | win32/mingw.c | 55 |
2 files changed, 49 insertions, 10 deletions
diff --git a/include/mingw.h b/include/mingw.h index f8e833138..f99582ca5 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -8,8 +8,8 @@ | |||
8 | typedef int gid_t; | 8 | typedef int gid_t; |
9 | typedef int uid_t; | 9 | typedef int uid_t; |
10 | 10 | ||
11 | #define DEFAULT_UID 1000 | 11 | #define DEFAULT_UID 4095 |
12 | #define DEFAULT_GID 1000 | 12 | #define DEFAULT_GID 4095 |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * arpa/inet.h | 15 | * arpa/inet.h |
diff --git a/win32/mingw.c b/win32/mingw.c index d7bdc10f6..f84cb76d3 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -391,13 +391,20 @@ static int has_exec_format(const char *name) | |||
391 | } | 391 | } |
392 | 392 | ||
393 | #if ENABLE_FEATURE_IDENTIFY_OWNER | 393 | #if ENABLE_FEATURE_IDENTIFY_OWNER |
394 | static int file_belongs_to_me(HANDLE fh) | 394 | static uid_t file_owner(HANDLE fh) |
395 | { | 395 | { |
396 | PSID pSidOwner; | 396 | PSID pSidOwner; |
397 | PSECURITY_DESCRIPTOR pSD; | 397 | PSECURITY_DESCRIPTOR pSD; |
398 | static PTOKEN_USER user = NULL; | 398 | static PTOKEN_USER user = NULL; |
399 | static int initialised = 0; | 399 | static int initialised = 0; |
400 | int equal; | 400 | int equal; |
401 | uid_t uid = 0; | ||
402 | DWORD *ptr; | ||
403 | unsigned char prefix[] = { | ||
404 | 0x01, 0x05, 0x00, 0x00, | ||
405 | 0x00, 0x00, 0x00, 0x05, | ||
406 | 0x15, 0x00, 0x00, 0x00 | ||
407 | }; | ||
401 | 408 | ||
402 | /* get SID of current user */ | 409 | /* get SID of current user */ |
403 | if (!initialised) { | 410 | if (!initialised) { |
@@ -418,16 +425,51 @@ static int file_belongs_to_me(HANDLE fh) | |||
418 | } | 425 | } |
419 | 426 | ||
420 | if (user == NULL) | 427 | if (user == NULL) |
421 | return TRUE; | 428 | return DEFAULT_UID; |
422 | 429 | ||
423 | /* get SID of file's owner */ | 430 | /* get SID of file's owner */ |
424 | if (GetSecurityInfo(fh, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, | 431 | if (GetSecurityInfo(fh, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, |
425 | &pSidOwner, NULL, NULL, NULL, &pSD) != ERROR_SUCCESS) | 432 | &pSidOwner, NULL, NULL, NULL, &pSD) != ERROR_SUCCESS) |
426 | return FALSE; | 433 | return 0; |
427 | 434 | ||
428 | equal = EqualSid(pSidOwner, user->User.Sid); | 435 | equal = EqualSid(pSidOwner, user->User.Sid); |
429 | LocalFree(pSD); | 436 | LocalFree(pSD); |
430 | return equal; | 437 | |
438 | if (equal) | ||
439 | return DEFAULT_UID; | ||
440 | |||
441 | /* for local or domain users use the RID as uid */ | ||
442 | if (memcmp(pSidOwner, prefix, sizeof(prefix)) == 0) { | ||
443 | ptr = (DWORD *)pSidOwner; | ||
444 | if (ptr[6] >= 500 && ptr[6] < DEFAULT_UID) | ||
445 | uid = (uid_t)ptr[6]; | ||
446 | } | ||
447 | return uid; | ||
448 | |||
449 | #if 0 | ||
450 | /* this is how it would be done properly using the API */ | ||
451 | { | ||
452 | PSID_IDENTIFIER_AUTHORITY auth; | ||
453 | unsigned char *count; | ||
454 | PDWORD subauth; | ||
455 | unsigned char nt_auth[] = { | ||
456 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x05 | ||
457 | }; | ||
458 | |||
459 | if (IsValidSid(pSidOwner) ) { | ||
460 | auth = GetSidIdentifierAuthority(pSidOwner); | ||
461 | count = GetSidSubAuthorityCount(pSidOwner); | ||
462 | subauth = GetSidSubAuthority(pSidOwner, 0); | ||
463 | if (memcmp(auth, nt_auth, sizeof(nt_auth)) == 0 && | ||
464 | *count == 5 && *subauth == 21) { | ||
465 | subauth = GetSidSubAuthority(pSidOwner, 4); | ||
466 | if (*subauth >= 500 && *subauth < DEFAULT_UID) | ||
467 | uid = (uid_t)*subauth; | ||
468 | } | ||
469 | } | ||
470 | return uid; | ||
471 | } | ||
472 | #endif | ||
431 | } | 473 | } |
432 | #endif | 474 | #endif |
433 | 475 | ||
@@ -499,10 +541,7 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf) | |||
499 | hdata.nNumberOfLinks; | 541 | hdata.nNumberOfLinks; |
500 | } | 542 | } |
501 | #if ENABLE_FEATURE_IDENTIFY_OWNER | 543 | #if ENABLE_FEATURE_IDENTIFY_OWNER |
502 | if (!file_belongs_to_me(fh)) { | 544 | buf->st_uid = buf->st_gid = file_owner(fh); |
503 | buf->st_uid = 0; | ||
504 | buf->st_gid = 0; | ||
505 | } | ||
506 | #endif | 545 | #endif |
507 | CloseHandle(fh); | 546 | CloseHandle(fh); |
508 | } | 547 | } |