Mercurial > emacs
comparison src/w32.c @ 97875:a77c2abc7237
(init_user_info): Allocate buf[] with xmalloc using the size needed by
GetTokenInformation.
(w32_system_process_attributes): Check return values of all system APIs.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Sat, 30 Aug 2008 16:46:06 +0000 |
parents | 1f8e4a26957e |
children | 038d7d21b786 |
comparison
equal
deleted
inserted
replaced
97874:9468eeadf007 | 97875:a77c2abc7237 |
---|---|
905 Use the relative portion of the identifier authority value from | 905 Use the relative portion of the identifier authority value from |
906 the user-sid as the user id value (same for group id using the | 906 the user-sid as the user id value (same for group id using the |
907 primary group sid from the process token). */ | 907 primary group sid from the process token). */ |
908 | 908 |
909 char uname[UNLEN+1], gname[GNLEN+1], domain[1025]; | 909 char uname[UNLEN+1], gname[GNLEN+1], domain[1025]; |
910 DWORD ulength = sizeof (uname), dlength = sizeof (domain), trash; | 910 DWORD ulength = sizeof (uname), dlength = sizeof (domain), needed; |
911 DWORD glength = sizeof (gname); | 911 DWORD glength = sizeof (gname); |
912 HANDLE token = NULL; | 912 HANDLE token = NULL; |
913 SID_NAME_USE user_type; | 913 SID_NAME_USE user_type; |
914 unsigned char buf[1024]; | 914 unsigned char *buf = NULL; |
915 DWORD blen = 0; | |
915 TOKEN_USER user_token; | 916 TOKEN_USER user_token; |
916 TOKEN_PRIMARY_GROUP group_token; | 917 TOKEN_PRIMARY_GROUP group_token; |
917 | 918 BOOL result; |
918 if (open_process_token (GetCurrentProcess (), TOKEN_QUERY, &token) | 919 |
919 && get_token_information (token, TokenUser, | 920 result = open_process_token (GetCurrentProcess (), TOKEN_QUERY, &token); |
920 (PVOID)buf, sizeof (buf), &trash) | 921 if (result) |
921 && (memcpy (&user_token, buf, sizeof (user_token)), | 922 { |
922 lookup_account_sid (NULL, user_token.User.Sid, uname, &ulength, | 923 result = get_token_information (token, TokenUser, NULL, 0, &blen); |
923 domain, &dlength, &user_type))) | 924 if (!result && GetLastError () == ERROR_INSUFFICIENT_BUFFER) |
925 { | |
926 buf = xmalloc (blen); | |
927 result = get_token_information (token, TokenUser, | |
928 (LPVOID)buf, blen, &needed); | |
929 if (result) | |
930 { | |
931 memcpy (&user_token, buf, sizeof (user_token)); | |
932 result = lookup_account_sid (NULL, user_token.User.Sid, | |
933 uname, &ulength, | |
934 domain, &dlength, &user_type); | |
935 } | |
936 } | |
937 else | |
938 result = FALSE; | |
939 } | |
940 if (result) | |
924 { | 941 { |
925 strcpy (dflt_passwd.pw_name, uname); | 942 strcpy (dflt_passwd.pw_name, uname); |
926 /* Determine a reasonable uid value. */ | 943 /* Determine a reasonable uid value. */ |
927 if (xstrcasecmp ("administrator", uname) == 0) | 944 if (xstrcasecmp ("administrator", uname) == 0) |
928 { | 945 { |
934 /* Use the last sub-authority value of the RID, the relative | 951 /* Use the last sub-authority value of the RID, the relative |
935 portion of the SID, as user/group ID. */ | 952 portion of the SID, as user/group ID. */ |
936 dflt_passwd.pw_uid = get_rid (user_token.User.Sid); | 953 dflt_passwd.pw_uid = get_rid (user_token.User.Sid); |
937 | 954 |
938 /* Get group id and name. */ | 955 /* Get group id and name. */ |
939 if (get_token_information (token, TokenPrimaryGroup, | 956 result = get_token_information (token, TokenPrimaryGroup, |
940 (PVOID)buf, sizeof (buf), &trash)) | 957 (LPVOID)buf, blen, &needed); |
958 if (!result && GetLastError () == ERROR_INSUFFICIENT_BUFFER) | |
959 { | |
960 buf = xrealloc (buf, blen = needed); | |
961 result = get_token_information (token, TokenPrimaryGroup, | |
962 (LPVOID)buf, blen, &needed); | |
963 } | |
964 if (result) | |
941 { | 965 { |
942 memcpy (&group_token, buf, sizeof (group_token)); | 966 memcpy (&group_token, buf, sizeof (group_token)); |
943 dflt_passwd.pw_gid = get_rid (group_token.PrimaryGroup); | 967 dflt_passwd.pw_gid = get_rid (group_token.PrimaryGroup); |
944 dlength = sizeof (domain); | 968 dlength = sizeof (domain); |
969 /* If we can get at the real Primary Group name, use that. | |
970 Otherwise, the default group name was already set to | |
971 "None" in globals_of_w32. */ | |
945 if (lookup_account_sid (NULL, group_token.PrimaryGroup, | 972 if (lookup_account_sid (NULL, group_token.PrimaryGroup, |
946 gname, &glength, NULL, &dlength, | 973 gname, &glength, NULL, &dlength, |
947 &user_type)) | 974 &user_type)) |
948 strcpy (dflt_group_name, gname); | 975 strcpy (dflt_group_name, gname); |
949 } | 976 } |
950 else | 977 else |
951 dflt_passwd.pw_gid = dflt_passwd.pw_uid; | 978 dflt_passwd.pw_gid = dflt_passwd.pw_uid; |
952 } | 979 } |
953 } | 980 } |
954 /* If security calls are not supported (presumably because we | 981 /* If security calls are not supported (presumably because we |
955 are running under Windows 95), fallback to this. */ | 982 are running under Windows 9X), fallback to this: */ |
956 else if (GetUserName (uname, &ulength)) | 983 else if (GetUserName (uname, &ulength)) |
957 { | 984 { |
958 strcpy (dflt_passwd.pw_name, uname); | 985 strcpy (dflt_passwd.pw_name, uname); |
959 if (xstrcasecmp ("administrator", uname) == 0) | 986 if (xstrcasecmp ("administrator", uname) == 0) |
960 dflt_passwd.pw_uid = 0; | 987 dflt_passwd.pw_uid = 0; |
978 | 1005 |
979 /* Set dir and shell from environment variables. */ | 1006 /* Set dir and shell from environment variables. */ |
980 strcpy (dflt_passwd.pw_dir, getenv ("HOME")); | 1007 strcpy (dflt_passwd.pw_dir, getenv ("HOME")); |
981 strcpy (dflt_passwd.pw_shell, getenv ("SHELL")); | 1008 strcpy (dflt_passwd.pw_shell, getenv ("SHELL")); |
982 | 1009 |
1010 xfree (buf); | |
983 if (token) | 1011 if (token) |
984 CloseHandle (token); | 1012 CloseHandle (token); |
985 } | 1013 } |
986 | 1014 |
987 int | 1015 int |
3808 Lisp_Object cmd_str, decoded_cmd, tem; | 3836 Lisp_Object cmd_str, decoded_cmd, tem; |
3809 HANDLE h_snapshot, h_proc; | 3837 HANDLE h_snapshot, h_proc; |
3810 DWORD proc_id; | 3838 DWORD proc_id; |
3811 int found_proc = 0; | 3839 int found_proc = 0; |
3812 char uname[UNLEN+1], gname[GNLEN+1], domain[1025]; | 3840 char uname[UNLEN+1], gname[GNLEN+1], domain[1025]; |
3813 DWORD ulength = sizeof (uname), dlength = sizeof (domain), trash; | 3841 DWORD ulength = sizeof (uname), dlength = sizeof (domain), needed; |
3814 DWORD glength = sizeof (gname); | 3842 DWORD glength = sizeof (gname); |
3815 HANDLE token = NULL; | 3843 HANDLE token = NULL; |
3816 SID_NAME_USE user_type; | 3844 SID_NAME_USE user_type; |
3817 unsigned char buf[1024]; | 3845 unsigned char *buf = NULL; |
3846 DWORD blen = 0; | |
3818 TOKEN_USER user_token; | 3847 TOKEN_USER user_token; |
3819 TOKEN_PRIMARY_GROUP group_token; | 3848 TOKEN_PRIMARY_GROUP group_token; |
3820 int euid; | 3849 int euid; |
3821 int egid; | 3850 int egid; |
3822 DWORD sess; | 3851 DWORD sess; |
3826 MEMORYSTATUS memst; | 3855 MEMORYSTATUS memst; |
3827 MEMORY_STATUS_EX memstex; | 3856 MEMORY_STATUS_EX memstex; |
3828 double totphys = 0.0; | 3857 double totphys = 0.0; |
3829 Lisp_Object ctime, stime, utime, etime; | 3858 Lisp_Object ctime, stime, utime, etime; |
3830 double pcpu; | 3859 double pcpu; |
3860 BOOL result = FALSE; | |
3831 | 3861 |
3832 CHECK_NUMBER_OR_FLOAT (pid); | 3862 CHECK_NUMBER_OR_FLOAT (pid); |
3833 proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid); | 3863 proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid); |
3834 | 3864 |
3835 h_snapshot = create_toolhelp32_snapshot (TH32CS_SNAPPROCESS, 0); | 3865 h_snapshot = create_toolhelp32_snapshot (TH32CS_SNAPPROCESS, 0); |
3896 FALSE, proc_id); | 3926 FALSE, proc_id); |
3897 restore_privilege (&priv_current); | 3927 restore_privilege (&priv_current); |
3898 revert_to_self (); | 3928 revert_to_self (); |
3899 } | 3929 } |
3900 } | 3930 } |
3901 if (h_proc | 3931 if (h_proc) |
3902 && open_process_token (h_proc, TOKEN_QUERY, &token) | 3932 { |
3903 && get_token_information (token, TokenUser, | 3933 result = open_process_token (h_proc, TOKEN_QUERY, &token); |
3904 (PVOID)buf, sizeof (buf), &trash)) | 3934 if (result) |
3905 { | 3935 { |
3906 memcpy (&user_token, buf, sizeof (user_token)); | 3936 result = get_token_information (token, TokenUser, NULL, 0, &blen); |
3907 if (w32_cached_id (user_token.User.Sid, &euid, uname)) | 3937 if (!result && GetLastError () == ERROR_INSUFFICIENT_BUFFER) |
3908 ulength = strlen (uname); | 3938 { |
3939 buf = xmalloc (blen); | |
3940 result = get_token_information (token, TokenUser, | |
3941 (LPVOID)buf, blen, &needed); | |
3942 if (result) | |
3943 { | |
3944 memcpy (&user_token, buf, sizeof (user_token)); | |
3945 if (!w32_cached_id (user_token.User.Sid, &euid, uname)) | |
3946 { | |
3947 euid = get_rid (user_token.User.Sid); | |
3948 result = lookup_account_sid (NULL, user_token.User.Sid, | |
3949 uname, &ulength, | |
3950 domain, &dlength, | |
3951 &user_type); | |
3952 if (result) | |
3953 w32_add_to_cache (user_token.User.Sid, euid, uname); | |
3954 else | |
3955 { | |
3956 strcpy (uname, "unknown"); | |
3957 result = TRUE; | |
3958 } | |
3959 } | |
3960 ulength = strlen (uname); | |
3961 } | |
3962 } | |
3963 } | |
3964 if (result) | |
3965 { | |
3966 /* Determine a reasonable euid and gid values. */ | |
3967 if (xstrcasecmp ("administrator", uname) == 0) | |
3968 { | |
3969 euid = 500; /* well-known Administrator uid */ | |
3970 egid = 513; /* well-known None gid */ | |
3971 } | |
3972 else | |
3973 { | |
3974 /* Get group id and name. */ | |
3975 result = get_token_information (token, TokenPrimaryGroup, | |
3976 (LPVOID)buf, blen, &needed); | |
3977 if (!result && GetLastError () == ERROR_INSUFFICIENT_BUFFER) | |
3978 { | |
3979 buf = xrealloc (buf, blen = needed); | |
3980 result = get_token_information (token, TokenPrimaryGroup, | |
3981 (LPVOID)buf, blen, &needed); | |
3982 } | |
3983 if (result) | |
3984 { | |
3985 memcpy (&group_token, buf, sizeof (group_token)); | |
3986 if (!w32_cached_id (group_token.PrimaryGroup, &egid, gname)) | |
3987 { | |
3988 egid = get_rid (group_token.PrimaryGroup); | |
3989 dlength = sizeof (domain); | |
3990 result = | |
3991 lookup_account_sid (NULL, group_token.PrimaryGroup, | |
3992 gname, &glength, NULL, &dlength, | |
3993 &user_type); | |
3994 if (result) | |
3995 w32_add_to_cache (group_token.PrimaryGroup, | |
3996 egid, gname); | |
3997 else | |
3998 { | |
3999 strcpy (gname, "None"); | |
4000 result = TRUE; | |
4001 } | |
4002 } | |
4003 glength = strlen (gname); | |
4004 } | |
4005 } | |
4006 } | |
4007 if (buf) | |
4008 xfree (buf); | |
4009 } | |
4010 if (!result) | |
4011 { | |
4012 if (!is_windows_9x ()) | |
4013 { | |
4014 /* We couldn't open the process token, presumably because of | |
4015 insufficient access rights. Assume this process is run | |
4016 by the system. */ | |
4017 strcpy (uname, "SYSTEM"); | |
4018 strcpy (gname, "None"); | |
4019 euid = 18; /* SYSTEM */ | |
4020 egid = 513; /* None */ | |
4021 glength = strlen (gname); | |
4022 ulength = strlen (uname); | |
4023 } | |
4024 /* If we are running under Windows 9X, where security calls are | |
4025 not supported, we assume all processes are run by the current | |
4026 user. */ | |
4027 else if (GetUserName (uname, &ulength)) | |
4028 { | |
4029 if (xstrcasecmp ("administrator", uname) == 0) | |
4030 euid = 0; | |
4031 else | |
4032 euid = 123; | |
4033 egid = euid; | |
4034 strcpy (gname, "None"); | |
4035 glength = strlen (gname); | |
4036 ulength = strlen (uname); | |
4037 } | |
3909 else | 4038 else |
3910 { | 4039 { |
3911 lookup_account_sid (NULL, user_token.User.Sid, uname, &ulength, | 4040 euid = 123; |
3912 domain, &dlength, &user_type); | 4041 egid = 123; |
3913 euid = get_rid (user_token.User.Sid); | 4042 strcpy (uname, "administrator"); |
3914 w32_add_to_cache (user_token.User.Sid, euid, uname); | 4043 ulength = strlen (uname); |
3915 } | 4044 strcpy (gname, "None"); |
3916 /* Determine a reasonable euid and gid values. */ | 4045 glength = strlen (gname); |
3917 if (xstrcasecmp ("administrator", uname) == 0) | 4046 } |
3918 { | 4047 if (token) |
3919 euid = 500; /* well-known Administrator uid */ | 4048 CloseHandle (token); |
3920 egid = 513; /* well-known None gid */ | 4049 } |
3921 } | |
3922 else | |
3923 { | |
3924 /* Get group id and name. */ | |
3925 if (get_token_information (token, TokenPrimaryGroup, | |
3926 (PVOID)buf, sizeof (buf), &trash)) | |
3927 { | |
3928 memcpy (&group_token, buf, sizeof (group_token)); | |
3929 if (w32_cached_id (group_token.PrimaryGroup, &egid, gname)) | |
3930 glength = strlen (gname); | |
3931 else | |
3932 { | |
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 } | |
3940 } | |
3941 else | |
3942 egid = euid; | |
3943 } | |
3944 } | |
3945 else if (!is_windows_9x ()) | |
3946 { | |
3947 /* We couldn't open the process token, presumably because of | |
3948 insufficient access rights. Assume this process is run by | |
3949 the system. */ | |
3950 strcpy (uname, "SYSTEM"); | |
3951 strcpy (gname, "None"); | |
3952 euid = 18; /* SYSTEM */ | |
3953 egid = 513; /* None */ | |
3954 glength = strlen (gname); | |
3955 ulength = strlen (uname); | |
3956 } | |
3957 /* If we are running under Windows 9X, where security calls are not | |
3958 supported, we assume all processes are run by the current | |
3959 user. */ | |
3960 else if (GetUserName (uname, &ulength)) | |
3961 { | |
3962 if (xstrcasecmp ("administrator", uname) == 0) | |
3963 euid = 0; | |
3964 else | |
3965 euid = 123; | |
3966 egid = euid; | |
3967 strcpy (gname, "None"); | |
3968 glength = strlen (gname); | |
3969 ulength = strlen (uname); | |
3970 } | |
3971 else | |
3972 { | |
3973 euid = 123; | |
3974 egid = 123; | |
3975 strcpy (uname, "administrator"); | |
3976 ulength = strlen (uname); | |
3977 strcpy (gname, "None"); | |
3978 glength = strlen (gname); | |
3979 } | |
3980 if (token) | |
3981 CloseHandle (token); | |
3982 | 4050 |
3983 attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (euid)), attrs); | 4051 attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (euid)), attrs); |
3984 tem = make_unibyte_string (uname, ulength); | 4052 tem = make_unibyte_string (uname, ulength); |
3985 attrs = Fcons (Fcons (Quser, | 4053 attrs = Fcons (Fcons (Quser, |
3986 code_convert_string_norecord (tem, Vlocale_coding_system, 0)), | 4054 code_convert_string_norecord (tem, Vlocale_coding_system, 0)), |