diff options
Diffstat (limited to 'src/w32.c')
| -rw-r--r-- | src/w32.c | 149 |
1 files changed, 124 insertions, 25 deletions
| @@ -120,6 +120,8 @@ static BOOL g_b_init_open_process_token; | |||
| 120 | static BOOL g_b_init_get_token_information; | 120 | static BOOL g_b_init_get_token_information; |
| 121 | static BOOL g_b_init_lookup_account_sid; | 121 | static BOOL g_b_init_lookup_account_sid; |
| 122 | static BOOL g_b_init_get_sid_identifier_authority; | 122 | static BOOL g_b_init_get_sid_identifier_authority; |
| 123 | static BOOL g_b_init_get_sid_sub_authority; | ||
| 124 | static BOOL g_b_init_get_sid_sub_authority_count; | ||
| 123 | 125 | ||
| 124 | /* | 126 | /* |
| 125 | BEGIN: Wrapper functions around OpenProcessToken | 127 | BEGIN: Wrapper functions around OpenProcessToken |
| @@ -161,6 +163,12 @@ typedef BOOL (WINAPI * LookupAccountSid_Proc) ( | |||
| 161 | PSID_NAME_USE peUse); | 163 | PSID_NAME_USE peUse); |
| 162 | typedef PSID_IDENTIFIER_AUTHORITY (WINAPI * GetSidIdentifierAuthority_Proc) ( | 164 | typedef PSID_IDENTIFIER_AUTHORITY (WINAPI * GetSidIdentifierAuthority_Proc) ( |
| 163 | PSID pSid); | 165 | PSID pSid); |
| 166 | typedef PDWORD (WINAPI * GetSidSubAuthority_Proc) ( | ||
| 167 | PSID pSid, | ||
| 168 | DWORD n); | ||
| 169 | typedef PUCHAR (WINAPI * GetSidSubAuthorityCount_Proc) ( | ||
| 170 | PSID pSid); | ||
| 171 | |||
| 164 | 172 | ||
| 165 | /* ** A utility function ** */ | 173 | /* ** A utility function ** */ |
| 166 | static BOOL | 174 | static BOOL |
| @@ -349,6 +357,57 @@ PSID_IDENTIFIER_AUTHORITY WINAPI get_sid_identifier_authority ( | |||
| 349 | return (s_pfn_Get_Sid_Identifier_Authority (pSid)); | 357 | return (s_pfn_Get_Sid_Identifier_Authority (pSid)); |
| 350 | } | 358 | } |
| 351 | 359 | ||
| 360 | PDWORD WINAPI get_sid_sub_authority ( | ||
| 361 | PSID pSid, | ||
| 362 | DWORD n) | ||
| 363 | { | ||
| 364 | static GetSidSubAuthority_Proc s_pfn_Get_Sid_Sub_Authority = NULL; | ||
| 365 | static DWORD zero = 0U; | ||
| 366 | HMODULE hm_advapi32 = NULL; | ||
| 367 | if (is_windows_9x () == TRUE) | ||
| 368 | { | ||
| 369 | return &zero; | ||
| 370 | } | ||
| 371 | if (g_b_init_get_sid_sub_authority == 0) | ||
| 372 | { | ||
| 373 | g_b_init_get_sid_sub_authority = 1; | ||
| 374 | hm_advapi32 = LoadLibrary ("Advapi32.dll"); | ||
| 375 | s_pfn_Get_Sid_Sub_Authority = | ||
| 376 | (GetSidSubAuthority_Proc) GetProcAddress ( | ||
| 377 | hm_advapi32, "GetSidSubAuthority"); | ||
| 378 | } | ||
| 379 | if (s_pfn_Get_Sid_Sub_Authority == NULL) | ||
| 380 | { | ||
| 381 | return &zero; | ||
| 382 | } | ||
| 383 | return (s_pfn_Get_Sid_Sub_Authority (pSid, n)); | ||
| 384 | } | ||
| 385 | |||
| 386 | PUCHAR WINAPI get_sid_sub_authority_count ( | ||
| 387 | PSID pSid) | ||
| 388 | { | ||
| 389 | static GetSidSubAuthorityCount_Proc s_pfn_Get_Sid_Sub_Authority_Count = NULL; | ||
| 390 | static UCHAR zero = 0U; | ||
| 391 | HMODULE hm_advapi32 = NULL; | ||
| 392 | if (is_windows_9x () == TRUE) | ||
| 393 | { | ||
| 394 | return &zero; | ||
| 395 | } | ||
| 396 | if (g_b_init_get_sid_sub_authority_count == 0) | ||
| 397 | { | ||
| 398 | g_b_init_get_sid_sub_authority_count = 1; | ||
| 399 | hm_advapi32 = LoadLibrary ("Advapi32.dll"); | ||
| 400 | s_pfn_Get_Sid_Sub_Authority_Count = | ||
| 401 | (GetSidSubAuthorityCount_Proc) GetProcAddress ( | ||
| 402 | hm_advapi32, "GetSidSubAuthorityCount"); | ||
| 403 | } | ||
| 404 | if (s_pfn_Get_Sid_Sub_Authority_Count == NULL) | ||
| 405 | { | ||
| 406 | return &zero; | ||
| 407 | } | ||
| 408 | return (s_pfn_Get_Sid_Sub_Authority_Count (pSid)); | ||
| 409 | } | ||
| 410 | |||
| 352 | /* | 411 | /* |
| 353 | END: Wrapper functions around OpenProcessToken | 412 | END: Wrapper functions around OpenProcessToken |
| 354 | and other functions in advapi32.dll that are only | 413 | and other functions in advapi32.dll that are only |
| @@ -547,39 +606,47 @@ init_user_info () | |||
| 547 | domain, &dlength, &user_type)) | 606 | domain, &dlength, &user_type)) |
| 548 | { | 607 | { |
| 549 | strcpy (the_passwd.pw_name, name); | 608 | strcpy (the_passwd.pw_name, name); |
| 550 | /* Determine a reasonable uid value. */ | 609 | /* Determine a reasonable uid value. */ |
| 551 | if (stricmp ("administrator", name) == 0) | 610 | if (stricmp ("administrator", name) == 0) |
| 552 | { | 611 | { |
| 553 | the_passwd.pw_uid = 0; | 612 | the_passwd.pw_uid = 500; /* well-known Administrator uid */ |
| 554 | the_passwd.pw_gid = 0; | 613 | the_passwd.pw_gid = 513; /* well-known None gid */ |
| 555 | } | 614 | } |
| 556 | else | 615 | else |
| 557 | { | 616 | { |
| 558 | SID_IDENTIFIER_AUTHORITY * pSIA; | 617 | /* Use the last sub-authority value of the RID, the relative |
| 559 | 618 | portion of the SID, as user/group ID. */ | |
| 560 | pSIA = get_sid_identifier_authority (*((PSID *) user_sid)); | 619 | DWORD n_subauthorities = |
| 561 | /* I believe the relative portion is the last 4 bytes (of 6) | 620 | *get_sid_sub_authority_count (*((PSID *) user_sid)); |
| 562 | with msb first. */ | 621 | |
| 563 | the_passwd.pw_uid = ((pSIA->Value[2] << 24) + | 622 | if (n_subauthorities < 1) |
| 564 | (pSIA->Value[3] << 16) + | 623 | the_passwd.pw_uid = 0; /* the "World" RID */ |
| 565 | (pSIA->Value[4] << 8) + | 624 | else |
| 566 | (pSIA->Value[5] << 0)); | 625 | { |
| 567 | /* restrict to conventional uid range for normal users */ | 626 | the_passwd.pw_uid = |
| 568 | the_passwd.pw_uid = the_passwd.pw_uid % 60001; | 627 | *get_sid_sub_authority (*((PSID *) user_sid), |
| 628 | n_subauthorities - 1); | ||
| 629 | /* Restrict to conventional uid range for normal users. */ | ||
| 630 | the_passwd.pw_uid %= 60001; | ||
| 631 | } | ||
| 569 | 632 | ||
| 570 | /* Get group id */ | 633 | /* Get group id */ |
| 571 | if (get_token_information (token, TokenPrimaryGroup, | 634 | if (get_token_information (token, TokenPrimaryGroup, |
| 572 | (PVOID) user_sid, sizeof (user_sid), &trash)) | 635 | (PVOID) user_sid, sizeof (user_sid), &trash)) |
| 573 | { | 636 | { |
| 574 | SID_IDENTIFIER_AUTHORITY * pSIA; | 637 | n_subauthorities = |
| 575 | 638 | *get_sid_sub_authority_count (*((PSID *) user_sid)); | |
| 576 | pSIA = get_sid_identifier_authority (*((PSID *) user_sid)); | 639 | |
| 577 | the_passwd.pw_gid = ((pSIA->Value[2] << 24) + | 640 | if (n_subauthorities < 1) |
| 578 | (pSIA->Value[3] << 16) + | 641 | the_passwd.pw_gid = 0; /* the "World" RID */ |
| 579 | (pSIA->Value[4] << 8) + | 642 | else |
| 580 | (pSIA->Value[5] << 0)); | 643 | { |
| 581 | /* I don't know if this is necessary, but for safety... */ | 644 | the_passwd.pw_gid = |
| 582 | the_passwd.pw_gid = the_passwd.pw_gid % 60001; | 645 | *get_sid_sub_authority (*((PSID *) user_sid), |
| 646 | n_subauthorities - 1); | ||
| 647 | /* I don't know if this is necessary, but for safety... */ | ||
| 648 | the_passwd.pw_gid %= 60001; | ||
| 649 | } | ||
| 583 | } | 650 | } |
| 584 | else | 651 | else |
| 585 | the_passwd.pw_gid = the_passwd.pw_uid; | 652 | the_passwd.pw_gid = the_passwd.pw_uid; |
| @@ -1938,6 +2005,36 @@ unc_volume_file_attributes (const char *path) | |||
| 1938 | return attrs; | 2005 | return attrs; |
| 1939 | } | 2006 | } |
| 1940 | 2007 | ||
| 2008 | /* Ensure a network connection is authenticated. */ | ||
| 2009 | static void | ||
| 2010 | logon_network_drive (const char *path) | ||
| 2011 | { | ||
| 2012 | NETRESOURCE resource; | ||
| 2013 | char share[MAX_PATH]; | ||
| 2014 | int i, n_slashes; | ||
| 2015 | |||
| 2016 | /* Only logon to networked drives. */ | ||
| 2017 | if (!IS_DIRECTORY_SEP (path[0]) || !IS_DIRECTORY_SEP (path[1])) | ||
| 2018 | return; | ||
| 2019 | n_slashes = 2; | ||
| 2020 | strncpy (share, path, MAX_PATH); | ||
| 2021 | /* Truncate to just server and share name. */ | ||
| 2022 | for (i = 2; i < MAX_PATH; i++) | ||
| 2023 | { | ||
| 2024 | if (IS_DIRECTORY_SEP (share[i]) && ++n_slashes > 3) | ||
| 2025 | { | ||
| 2026 | share[i] = '\0'; | ||
| 2027 | break; | ||
| 2028 | } | ||
| 2029 | } | ||
| 2030 | |||
| 2031 | resource.dwType = RESOURCETYPE_DISK; | ||
| 2032 | resource.lpLocalName = NULL; | ||
| 2033 | resource.lpRemoteName = share; | ||
| 2034 | resource.lpProvider = NULL; | ||
| 2035 | |||
| 2036 | WNetAddConnection2 (&resource, NULL, NULL, CONNECT_INTERACTIVE); | ||
| 2037 | } | ||
| 1941 | 2038 | ||
| 1942 | /* Shadow some MSVC runtime functions to map requests for long filenames | 2039 | /* Shadow some MSVC runtime functions to map requests for long filenames |
| 1943 | to reasonable short names if necessary. This was originally added to | 2040 | to reasonable short names if necessary. This was originally added to |
| @@ -2495,6 +2592,8 @@ stat (const char * path, struct stat * buf) | |||
| 2495 | } | 2592 | } |
| 2496 | else | 2593 | else |
| 2497 | { | 2594 | { |
| 2595 | logon_network_drive (name); | ||
| 2596 | |||
| 2498 | fh = FindFirstFile (name, &wfd); | 2597 | fh = FindFirstFile (name, &wfd); |
| 2499 | if (fh == INVALID_HANDLE_VALUE) | 2598 | if (fh == INVALID_HANDLE_VALUE) |
| 2500 | { | 2599 | { |
| @@ -2668,8 +2767,8 @@ fstat (int desc, struct stat * buf) | |||
| 2668 | buf->st_ino = fake_inode; | 2767 | buf->st_ino = fake_inode; |
| 2669 | 2768 | ||
| 2670 | /* consider files to belong to current user */ | 2769 | /* consider files to belong to current user */ |
| 2671 | buf->st_uid = 0; | 2770 | buf->st_uid = the_passwd.pw_uid; |
| 2672 | buf->st_gid = 0; | 2771 | buf->st_gid = the_passwd.pw_gid; |
| 2673 | 2772 | ||
| 2674 | buf->st_dev = info.dwVolumeSerialNumber; | 2773 | buf->st_dev = info.dwVolumeSerialNumber; |
| 2675 | buf->st_rdev = info.dwVolumeSerialNumber; | 2774 | buf->st_rdev = info.dwVolumeSerialNumber; |