diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/w32.c | 193 |
2 files changed, 189 insertions, 14 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 2af33df079b..8f99dec139f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -6,6 +6,16 @@ | |||
| 6 | (stat): Only root directory passed to GetDriveType. Allow RAM | 6 | (stat): Only root directory passed to GetDriveType. Allow RAM |
| 7 | disk as well as local fixed disk when w32-get-true-file-attributes | 7 | disk as well as local fixed disk when w32-get-true-file-attributes |
| 8 | is set to `local'. | 8 | is set to `local'. |
| 9 | (CopySid_Proc, EqualSid_Proc, GetLengthSid_Proc): New typedefs. | ||
| 10 | (equal_sid, get_length_sid, copy_sid): New wrapper functions. | ||
| 11 | (w32_cached_id, w32_add_to_cache): New functions. | ||
| 12 | (get_name_and_id): Look account names in the cache before calling | ||
| 13 | lookup_account_sid. | ||
| 14 | (g_b_init_get_length_sid, g_b_init_equal_sid, g_b_init_copy_sid): | ||
| 15 | New initialization flags. | ||
| 16 | (globals_of_w32): Initialize them to zero. | ||
| 17 | (w32_system_process_attributes): Use w32_cached_id and | ||
| 18 | w32_add_to_cache. | ||
| 9 | 19 | ||
| 10 | 2008-08-14 Lawrence Mitchell <wence@gmx.li> | 20 | 2008-08-14 Lawrence Mitchell <wence@gmx.li> |
| 11 | 21 | ||
| @@ -188,6 +188,9 @@ static BOOL g_b_init_get_process_memory_info; | |||
| 188 | static BOOL g_b_init_get_process_working_set_size; | 188 | static BOOL g_b_init_get_process_working_set_size; |
| 189 | static BOOL g_b_init_global_memory_status; | 189 | static BOOL g_b_init_global_memory_status; |
| 190 | static BOOL g_b_init_global_memory_status_ex; | 190 | static BOOL g_b_init_global_memory_status_ex; |
| 191 | static BOOL g_b_init_get_length_sid; | ||
| 192 | static BOOL g_b_init_equal_sid; | ||
| 193 | static BOOL g_b_init_copy_sid; | ||
| 191 | 194 | ||
| 192 | /* | 195 | /* |
| 193 | BEGIN: Wrapper functions around OpenProcessToken | 196 | BEGIN: Wrapper functions around OpenProcessToken |
| @@ -281,6 +284,17 @@ typedef BOOL (WINAPI * GlobalMemoryStatus_Proc) ( | |||
| 281 | LPMEMORYSTATUS lpBuffer); | 284 | LPMEMORYSTATUS lpBuffer); |
| 282 | typedef BOOL (WINAPI * GlobalMemoryStatusEx_Proc) ( | 285 | typedef BOOL (WINAPI * GlobalMemoryStatusEx_Proc) ( |
| 283 | LPMEMORY_STATUS_EX lpBuffer); | 286 | LPMEMORY_STATUS_EX lpBuffer); |
| 287 | typedef BOOL (WINAPI * CopySid_Proc) ( | ||
| 288 | DWORD nDestinationSidLength, | ||
| 289 | PSID pDestinationSid, | ||
| 290 | PSID pSourceSid); | ||
| 291 | typedef BOOL (WINAPI * EqualSid_Proc) ( | ||
| 292 | PSID pSid1, | ||
| 293 | PSID pSid2); | ||
| 294 | typedef DWORD (WINAPI * GetLengthSid_Proc) ( | ||
| 295 | PSID pSid); | ||
| 296 | |||
| 297 | |||
| 284 | 298 | ||
| 285 | /* ** A utility function ** */ | 299 | /* ** A utility function ** */ |
| 286 | static BOOL | 300 | static BOOL |
| @@ -628,6 +642,81 @@ BOOL WINAPI is_valid_sid ( | |||
| 628 | return (s_pfn_Is_Valid_Sid (sid)); | 642 | return (s_pfn_Is_Valid_Sid (sid)); |
| 629 | } | 643 | } |
| 630 | 644 | ||
| 645 | BOOL WINAPI equal_sid ( | ||
| 646 | PSID sid1, | ||
| 647 | PSID sid2) | ||
| 648 | { | ||
| 649 | static EqualSid_Proc s_pfn_Equal_Sid = NULL; | ||
| 650 | HMODULE hm_advapi32 = NULL; | ||
| 651 | if (is_windows_9x () == TRUE) | ||
| 652 | { | ||
| 653 | return FALSE; | ||
| 654 | } | ||
| 655 | if (g_b_init_equal_sid == 0) | ||
| 656 | { | ||
| 657 | g_b_init_equal_sid = 1; | ||
| 658 | hm_advapi32 = LoadLibrary ("Advapi32.dll"); | ||
| 659 | s_pfn_Equal_Sid = | ||
| 660 | (EqualSid_Proc) GetProcAddress ( | ||
| 661 | hm_advapi32, "EqualSid"); | ||
| 662 | } | ||
| 663 | if (s_pfn_Equal_Sid == NULL) | ||
| 664 | { | ||
| 665 | return FALSE; | ||
| 666 | } | ||
| 667 | return (s_pfn_Equal_Sid (sid1, sid2)); | ||
| 668 | } | ||
| 669 | |||
| 670 | DWORD WINAPI get_length_sid ( | ||
| 671 | PSID sid) | ||
| 672 | { | ||
| 673 | static GetLengthSid_Proc s_pfn_Get_Length_Sid = NULL; | ||
| 674 | HMODULE hm_advapi32 = NULL; | ||
| 675 | if (is_windows_9x () == TRUE) | ||
| 676 | { | ||
| 677 | return 0; | ||
| 678 | } | ||
| 679 | if (g_b_init_get_length_sid == 0) | ||
| 680 | { | ||
| 681 | g_b_init_get_length_sid = 1; | ||
| 682 | hm_advapi32 = LoadLibrary ("Advapi32.dll"); | ||
| 683 | s_pfn_Get_Length_Sid = | ||
| 684 | (GetLengthSid_Proc) GetProcAddress ( | ||
| 685 | hm_advapi32, "GetLengthSid"); | ||
| 686 | } | ||
| 687 | if (s_pfn_Get_Length_Sid == NULL) | ||
| 688 | { | ||
| 689 | return 0; | ||
| 690 | } | ||
| 691 | return (s_pfn_Get_Length_Sid (sid)); | ||
| 692 | } | ||
| 693 | |||
| 694 | BOOL WINAPI copy_sid ( | ||
| 695 | DWORD destlen, | ||
| 696 | PSID dest, | ||
| 697 | PSID src) | ||
| 698 | { | ||
| 699 | static CopySid_Proc s_pfn_Copy_Sid = NULL; | ||
| 700 | HMODULE hm_advapi32 = NULL; | ||
| 701 | if (is_windows_9x () == TRUE) | ||
| 702 | { | ||
| 703 | return FALSE; | ||
| 704 | } | ||
| 705 | if (g_b_init_copy_sid == 0) | ||
| 706 | { | ||
| 707 | g_b_init_copy_sid = 1; | ||
| 708 | hm_advapi32 = LoadLibrary ("Advapi32.dll"); | ||
| 709 | s_pfn_Copy_Sid = | ||
| 710 | (CopySid_Proc) GetProcAddress ( | ||
| 711 | hm_advapi32, "CopySid"); | ||
| 712 | } | ||
| 713 | if (s_pfn_Copy_Sid == NULL) | ||
| 714 | { | ||
| 715 | return FALSE; | ||
| 716 | } | ||
| 717 | return (s_pfn_Copy_Sid (destlen, dest, src)); | ||
| 718 | } | ||
| 719 | |||
| 631 | /* | 720 | /* |
| 632 | END: Wrapper functions around OpenProcessToken | 721 | END: Wrapper functions around OpenProcessToken |
| 633 | and other functions in advapi32.dll that are only | 722 | and other functions in advapi32.dll that are only |
| @@ -2780,6 +2869,69 @@ get_rid (PSID sid) | |||
| 2780 | return *get_sid_sub_authority (sid, n_subauthorities - 1); | 2869 | return *get_sid_sub_authority (sid, n_subauthorities - 1); |
| 2781 | } | 2870 | } |
| 2782 | 2871 | ||
| 2872 | /* Caching SID and account values for faster lokup. */ | ||
| 2873 | |||
| 2874 | #ifdef __GNUC__ | ||
| 2875 | # define FLEXIBLE_ARRAY_MEMBER | ||
| 2876 | #else | ||
| 2877 | # define FLEXIBLE_ARRAY_MEMBER 1 | ||
| 2878 | #endif | ||
| 2879 | |||
| 2880 | struct w32_id { | ||
| 2881 | int rid; | ||
| 2882 | struct w32_id *next; | ||
| 2883 | char name[GNLEN+1]; | ||
| 2884 | unsigned char sid[FLEXIBLE_ARRAY_MEMBER]; | ||
| 2885 | }; | ||
| 2886 | |||
| 2887 | static struct w32_id *w32_idlist; | ||
| 2888 | |||
| 2889 | static int | ||
| 2890 | w32_cached_id (PSID sid, int *id, char *name) | ||
| 2891 | { | ||
| 2892 | struct w32_id *tail, *found; | ||
| 2893 | |||
| 2894 | for (found = NULL, tail = w32_idlist; tail; tail = tail->next) | ||
| 2895 | { | ||
| 2896 | if (equal_sid ((PSID)tail->sid, sid)) | ||
| 2897 | { | ||
| 2898 | found = tail; | ||
| 2899 | break; | ||
| 2900 | } | ||
| 2901 | } | ||
| 2902 | if (found) | ||
| 2903 | { | ||
| 2904 | *id = found->rid; | ||
| 2905 | strcpy (name, found->name); | ||
| 2906 | return 1; | ||
| 2907 | } | ||
| 2908 | else | ||
| 2909 | return 0; | ||
| 2910 | } | ||
| 2911 | |||
| 2912 | static void | ||
| 2913 | w32_add_to_cache (PSID sid, int id, char *name) | ||
| 2914 | { | ||
| 2915 | DWORD sid_len; | ||
| 2916 | struct w32_id *new_entry; | ||
| 2917 | |||
| 2918 | /* We don't want to leave behind stale cache from when Emacs was | ||
| 2919 | dumped. */ | ||
| 2920 | if (initialized) | ||
| 2921 | { | ||
| 2922 | sid_len = get_length_sid (sid); | ||
| 2923 | new_entry = xmalloc (offsetof (struct w32_id, sid) + sid_len); | ||
| 2924 | if (new_entry) | ||
| 2925 | { | ||
| 2926 | new_entry->rid = id; | ||
| 2927 | strcpy (new_entry->name, name); | ||
| 2928 | copy_sid (sid_len, (PSID)new_entry->sid, sid); | ||
| 2929 | new_entry->next = w32_idlist; | ||
| 2930 | w32_idlist = new_entry; | ||
| 2931 | } | ||
| 2932 | } | ||
| 2933 | } | ||
| 2934 | |||
| 2783 | #define UID 1 | 2935 | #define UID 1 |
| 2784 | #define GID 2 | 2936 | #define GID 2 |
| 2785 | 2937 | ||
| @@ -2808,7 +2960,7 @@ get_name_and_id (PSECURITY_DESCRIPTOR psd, const char *fname, | |||
| 2808 | 2960 | ||
| 2809 | if (!result || !is_valid_sid (sid)) | 2961 | if (!result || !is_valid_sid (sid)) |
| 2810 | use_dflt = 1; | 2962 | use_dflt = 1; |
| 2811 | else | 2963 | else if (!w32_cached_id (sid, id, nm)) |
| 2812 | { | 2964 | { |
| 2813 | /* If FNAME is a UNC, we need to lookup account on the | 2965 | /* If FNAME is a UNC, we need to lookup account on the |
| 2814 | specified machine. */ | 2966 | specified machine. */ |
| @@ -2833,6 +2985,7 @@ get_name_and_id (PSECURITY_DESCRIPTOR psd, const char *fname, | |||
| 2833 | { | 2985 | { |
| 2834 | *id = get_rid (sid); | 2986 | *id = get_rid (sid); |
| 2835 | strcpy (nm, name); | 2987 | strcpy (nm, name); |
| 2988 | w32_add_to_cache (sid, *id, name); | ||
| 2836 | } | 2989 | } |
| 2837 | } | 2990 | } |
| 2838 | return use_dflt; | 2991 | return use_dflt; |
| @@ -3748,11 +3901,18 @@ w32_system_process_attributes (pid) | |||
| 3748 | if (h_proc | 3901 | if (h_proc |
| 3749 | && open_process_token (h_proc, TOKEN_QUERY, &token) | 3902 | && open_process_token (h_proc, TOKEN_QUERY, &token) |
| 3750 | && get_token_information (token, TokenUser, | 3903 | && get_token_information (token, TokenUser, |
| 3751 | (PVOID)buf, sizeof (buf), &trash) | 3904 | (PVOID)buf, sizeof (buf), &trash)) |
| 3752 | && (memcpy (&user_token, buf, sizeof (user_token)), | ||
| 3753 | lookup_account_sid (NULL, user_token.User.Sid, uname, &ulength, | ||
| 3754 | domain, &dlength, &user_type))) | ||
| 3755 | { | 3905 | { |
| 3906 | memcpy (&user_token, buf, sizeof (user_token)); | ||
| 3907 | if (w32_cached_id (user_token.User.Sid, &euid, uname)) | ||
| 3908 | ulength = strlen (uname); | ||
| 3909 | else | ||
| 3910 | { | ||
| 3911 | lookup_account_sid (NULL, user_token.User.Sid, uname, &ulength, | ||
| 3912 | domain, &dlength, &user_type); | ||
| 3913 | euid = get_rid (user_token.User.Sid); | ||
| 3914 | w32_add_to_cache (user_token.User.Sid, euid, uname); | ||
| 3915 | } | ||
| 3756 | /* Determine a reasonable euid and gid values. */ | 3916 | /* Determine a reasonable euid and gid values. */ |
| 3757 | if (xstrcasecmp ("administrator", uname) == 0) | 3917 | if (xstrcasecmp ("administrator", uname) == 0) |
| 3758 | { | 3918 | { |
| @@ -3761,20 +3921,22 @@ w32_system_process_attributes (pid) | |||
| 3761 | } | 3921 | } |
| 3762 | else | 3922 | else |
| 3763 | { | 3923 | { |
| 3764 | /* Use the last sub-authority value of the RID, the relative | ||
| 3765 | portion of the SID, as user/group ID. */ | ||
| 3766 | euid = get_rid (user_token.User.Sid); | ||
| 3767 | |||
| 3768 | /* Get group id and name. */ | 3924 | /* Get group id and name. */ |
| 3769 | if (get_token_information (token, TokenPrimaryGroup, | 3925 | if (get_token_information (token, TokenPrimaryGroup, |
| 3770 | (PVOID)buf, sizeof (buf), &trash)) | 3926 | (PVOID)buf, sizeof (buf), &trash)) |
| 3771 | { | 3927 | { |
| 3772 | memcpy (&group_token, buf, sizeof (group_token)); | 3928 | memcpy (&group_token, buf, sizeof (group_token)); |
| 3773 | egid = get_rid (group_token.PrimaryGroup); | 3929 | if (w32_cached_id (group_token.PrimaryGroup, &egid, gname)) |
| 3774 | dlength = sizeof (domain); | 3930 | glength = strlen (gname); |
| 3775 | lookup_account_sid (NULL, group_token.PrimaryGroup, | 3931 | else |
| 3776 | gname, &glength, NULL, &dlength, | 3932 | { |
| 3777 | &user_type); | 3933 | dlength = sizeof (domain); |
| 3934 | lookup_account_sid (NULL, group_token.PrimaryGroup, | ||
| 3935 | gname, &glength, NULL, &dlength, | ||
| 3936 | &user_type); | ||
| 3937 | egid = get_rid (group_token.PrimaryGroup); | ||
| 3938 | w32_add_to_cache (group_token.PrimaryGroup, egid, gname); | ||
| 3939 | } | ||
| 3778 | } | 3940 | } |
| 3779 | else | 3941 | else |
| 3780 | egid = euid; | 3942 | egid = euid; |
| @@ -5457,6 +5619,9 @@ globals_of_w32 () | |||
| 5457 | g_b_init_get_process_working_set_size = 0; | 5619 | g_b_init_get_process_working_set_size = 0; |
| 5458 | g_b_init_global_memory_status = 0; | 5620 | g_b_init_global_memory_status = 0; |
| 5459 | g_b_init_global_memory_status_ex = 0; | 5621 | g_b_init_global_memory_status_ex = 0; |
| 5622 | g_b_init_equal_sid = 0; | ||
| 5623 | g_b_init_copy_sid = 0; | ||
| 5624 | g_b_init_get_length_sid = 0; | ||
| 5460 | /* The following sets a handler for shutdown notifications for | 5625 | /* The following sets a handler for shutdown notifications for |
| 5461 | console apps. This actually applies to Emacs in both console and | 5626 | console apps. This actually applies to Emacs in both console and |
| 5462 | GUI modes, since we had to fool windows into thinking emacs is a | 5627 | GUI modes, since we had to fool windows into thinking emacs is a |