From 12eac211c9d8cfe8304b0232cd472bc005d71745 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 29 Apr 2011 07:34:05 +0000 Subject: [PATCH] * advapi32.cc (GetTokenInformation): Remove. (SetTokenInformation): Remove. * grp.cc: Replace above functions throughout with their ntdll.dll equivalent. * sec_auth.cc: Ditto. * syscalls.cc: Ditto. * uinfo.cc: Ditto. --- winsup/cygwin/ChangeLog | 10 +++ winsup/cygwin/advapi32.cc | 16 ---- winsup/cygwin/grp.cc | 18 ++-- winsup/cygwin/sec_auth.cc | 185 +++++++++++++++++++++----------------- winsup/cygwin/syscalls.cc | 51 +++++++---- winsup/cygwin/uinfo.cc | 41 +++++---- 6 files changed, 181 insertions(+), 140 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 569e7d9b7..53da07a9c 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,13 @@ +2011-04-29 Corinna Vinschen + + * advapi32.cc (GetTokenInformation): Remove. + (SetTokenInformation): Remove. + * grp.cc: Replace above functions throughout with their ntdll.dll + equivalent. + * sec_auth.cc: Ditto. + * syscalls.cc: Ditto. + * uinfo.cc: Ditto. + 2011-04-29 Corinna Vinschen * posix_ipc.cc (ipc_cond_timedwait): Only wait for pthread's diff --git a/winsup/cygwin/advapi32.cc b/winsup/cygwin/advapi32.cc index e8c238055..41eb71e60 100644 --- a/winsup/cygwin/advapi32.cc +++ b/winsup/cygwin/advapi32.cc @@ -82,22 +82,6 @@ OpenThreadToken (HANDLE thread, DWORD access, BOOL as_self, PHANDLE tok) DEFAULT_NTSTATUS_TO_BOOL_RETURN } -BOOL WINAPI -GetTokenInformation(HANDLE tok, TOKEN_INFORMATION_CLASS infoclass, LPVOID buf, - DWORD len, PDWORD retlen) -{ - NTSTATUS status = NtQueryInformationToken (tok, infoclass, buf, len, retlen); - DEFAULT_NTSTATUS_TO_BOOL_RETURN -} - -BOOL WINAPI -SetTokenInformation (HANDLE tok, TOKEN_INFORMATION_CLASS infoclass, PVOID buf, - ULONG len) -{ - NTSTATUS status = NtSetInformationToken (tok, infoclass, buf, len); - DEFAULT_NTSTATUS_TO_BOOL_RETURN -} - BOOL WINAPI RevertToSelf () { diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc index 970e62627..76dd5ec50 100644 --- a/winsup/cygwin/grp.cc +++ b/winsup/cygwin/grp.cc @@ -1,7 +1,7 @@ /* grp.cc Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2007, 2008, 2009 Red Hat, Inc. + 2007, 2008, 2009, 2011 Red Hat, Inc. Original stubs by Jason Molenda of Cygnus Support, crash@cygnus.com First implementation by Gunther Ebert, gunther.ebert@ixos-leipzig.de @@ -21,6 +21,7 @@ details. */ #include "fhandler.h" #include "dtable.h" #include "cygheap.h" +#include "ntdll.h" #include "pwdgrp.h" static __group32 *group_buf; @@ -314,8 +315,9 @@ internal_getgrent (int pos) int internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) { + NTSTATUS status; HANDLE hToken = NULL; - DWORD size; + ULONG size; int cnt = 0; struct __group32 *gr; @@ -344,13 +346,15 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) hToken = cygheap->user.primary_token (); else hToken = hProcToken; - - if (GetTokenInformation (hToken, TokenGroups, NULL, 0, &size) - || GetLastError () == ERROR_INSUFFICIENT_BUFFER) + + status = NtQueryInformationToken (hToken, TokenGroups, NULL, 0, &size); + if (NT_SUCCESS (status) || status == STATUS_BUFFER_TOO_SMALL) { PTOKEN_GROUPS groups = (PTOKEN_GROUPS) alloca (size); - if (GetTokenInformation (hToken, TokenGroups, groups, size, &size)) + status = NtQueryInformationToken (hToken, TokenGroups, groups, + size, &size); + if (NT_SUCCESS (status)) { cygsid sid; @@ -379,7 +383,7 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) } } else - debug_printf ("%d = GetTokenInformation(NULL) %E", size); + debug_printf ("%lu = NtQueryInformationToken(NULL) %p", size, status); return cnt; error: diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 23e805d19..575a1d3c1 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -32,7 +32,7 @@ details. */ /* Starting with Windows Vista, the token returned by system functions is a restricted token. The full admin token is linked to it and can - be fetched with GetTokenInformation. This function returns the original + be fetched with NtQueryInformationToken. This function returns the original token on pre-Vista, and the elevated token on Vista++ if it's available, the original token otherwise. The token handle is also made inheritable since that's necessary anyway. */ @@ -42,7 +42,7 @@ get_full_privileged_inheritable_token (HANDLE token) if (wincap.has_mandatory_integrity_control ()) { TOKEN_LINKED_TOKEN linked; - DWORD size; + ULONG size; /* When fetching the linked token without TCB privs, then the linked token is not a primary token, only an impersonation token, which is @@ -50,8 +50,9 @@ get_full_privileged_inheritable_token (HANDLE token) token using DuplicateTokenEx does NOT work for the linked token in this case. So we have to switch on TCB privs to get a primary token. This is generally performed in the calling functions. */ - if (GetTokenInformation (token, TokenLinkedToken, - (PVOID) &linked, sizeof linked, &size)) + if (NT_SUCCESS (NtQueryInformationToken (token, TokenLinkedToken, + (PVOID) &linked, sizeof linked, + &size))) { debug_printf ("Linked Token: %p", linked.LinkedToken); if (linked.LinkedToken) @@ -61,8 +62,9 @@ get_full_privileged_inheritable_token (HANDLE token) /* At this point we don't know if the user actually had TCB privileges. Check if the linked token is a primary token. If not, just return the original token. */ - if (GetTokenInformation (linked.LinkedToken, TokenType, - (PVOID) &type, sizeof type, &size) + if (NT_SUCCESS (NtQueryInformationToken (linked.LinkedToken, + TokenType, (PVOID) &type, + sizeof type, &size)) && type != TokenPrimary) debug_printf ("Linked Token is not a primary token!"); else @@ -660,23 +662,26 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list, bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern) { - DWORD size; + NTSTATUS status; + ULONG size; bool intern = false; if (pintern) { TOKEN_SOURCE ts; - if (!GetTokenInformation (token, TokenSource, - &ts, sizeof ts, &size)) - debug_printf ("GetTokenInformation(), %E"); + status = NtQueryInformationToken (token, TokenSource, &ts, sizeof ts, + &size); + if (!NT_SUCCESS (status)) + debug_printf ("NtQueryInformationToken(), %p", status); else *pintern = intern = !memcmp (ts.SourceName, "Cygwin.1", 8); } /* Verify usersid */ cygsid tok_usersid = NO_SID; - if (!GetTokenInformation (token, TokenUser, - &tok_usersid, sizeof tok_usersid, &size)) - debug_printf ("GetTokenInformation(), %E"); + status = NtQueryInformationToken (token, TokenUser, &tok_usersid, + sizeof tok_usersid, &size); + if (!NT_SUCCESS (status)) + debug_printf ("NtQueryInformationToken(), %p", status); if (usersid != tok_usersid) return false; @@ -705,64 +710,69 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern) } PTOKEN_GROUPS my_grps; - bool sawpg = false, ret = false; - if (!GetTokenInformation (token, TokenGroups, NULL, 0, &size) && - GetLastError () != ERROR_INSUFFICIENT_BUFFER) - debug_printf ("GetTokenInformation(token, TokenGroups), %E"); - else if (!(my_grps = (PTOKEN_GROUPS) alloca (size))) - debug_printf ("alloca (my_grps) failed."); - else if (!GetTokenInformation (token, TokenGroups, my_grps, size, &size)) - debug_printf ("GetTokenInformation(my_token, TokenGroups), %E"); - else + status = NtQueryInformationToken (token, TokenGroups, NULL, 0, &size); + if (!NT_SUCCESS (status) && status != STATUS_BUFFER_TOO_SMALL) { - if (groups.issetgroups ()) /* setgroups was called */ - { - cygsid gsid; - struct __group32 *gr; - bool saw[groups.sgsids.count ()]; - memset (saw, 0, sizeof(saw)); - - /* token groups found in /etc/group match the user.gsids ? */ - for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) - if (gsid.getfromgr (gr) && sid_in_token_groups (my_grps, gsid)) - { - int pos = groups.sgsids.position (gsid); - if (pos >= 0) - saw[pos] = true; - else if (groups.pgsid == gsid) - sawpg = true; -#if 0 - /* With this `else', verify_token returns false if we find - groups in the token, which are not in the group list set - with setgroups(). That's rather dangerous. What we're - really interested in is that all groups in the setgroups() - list are in the token. A token created through ADVAPI - should be allowed to contain more groups than requested - through setgroups(), esecially since Vista and the - addition of integrity groups. So we disable this statement - for now. */ - else if (gsid != well_known_world_sid - && gsid != usersid) - goto done; -#endif - } - /* user.sgsids groups must be in the token, except for builtin groups. - These can be different on domain member machines compared to - domain controllers, so these builtin groups may be validly missing - from a token created through password or lsaauth logon. */ - for (int gidx = 0; gidx < groups.sgsids.count (); gidx++) - if (!saw[gidx] - && !groups.sgsids.sids[gidx].is_well_known_sid () - && !sid_in_token_groups (my_grps, groups.sgsids.sids[gidx])) - return false; - } - /* The primary group must be in the token */ - ret = sawpg - || sid_in_token_groups (my_grps, groups.pgsid) - || groups.pgsid == usersid; + debug_printf ("NtQueryInformationToken(token, TokenGroups), %p", status); + return false; } - return ret; + my_grps = (PTOKEN_GROUPS) alloca (size); + status = NtQueryInformationToken (token, TokenGroups, my_grps, size, &size); + if (!NT_SUCCESS (status)) + { + debug_printf ("NtQueryInformationToken(my_token, TokenGroups), %p", + status); + return false; + } + + bool sawpg = false; + + if (groups.issetgroups ()) /* setgroups was called */ + { + cygsid gsid; + struct __group32 *gr; + bool saw[groups.sgsids.count ()]; + memset (saw, 0, sizeof(saw)); + + /* token groups found in /etc/group match the user.gsids ? */ + for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) + if (gsid.getfromgr (gr) && sid_in_token_groups (my_grps, gsid)) + { + int pos = groups.sgsids.position (gsid); + if (pos >= 0) + saw[pos] = true; + else if (groups.pgsid == gsid) + sawpg = true; +#if 0 + /* With this `else', verify_token returns false if we find + groups in the token, which are not in the group list set + with setgroups(). That's rather dangerous. What we're + really interested in is that all groups in the setgroups() + list are in the token. A token created through ADVAPI + should be allowed to contain more groups than requested + through setgroups(), esecially since Vista and the + addition of integrity groups. So we disable this statement + for now. */ + else if (gsid != well_known_world_sid + && gsid != usersid) + goto done; +#endif + } + /* user.sgsids groups must be in the token, except for builtin groups. + These can be different on domain member machines compared to + domain controllers, so these builtin groups may be validly missing + from a token created through password or lsaauth logon. */ + for (int gidx = 0; gidx < groups.sgsids.count (); gidx++) + if (!saw[gidx] + && !groups.sgsids.sids[gidx].is_well_known_sid () + && !sid_in_token_groups (my_grps, groups.sgsids.sids[gidx])) + return false; + } + /* The primary group must be in the token */ + return sawpg + || sid_in_token_groups (my_grps, groups.pgsid) + || groups.pgsid == usersid; } HANDLE @@ -795,7 +805,7 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw) HANDLE primary_token = INVALID_HANDLE_VALUE; PTOKEN_GROUPS my_tok_gsids = NULL; - DWORD size; + ULONG size; size_t psize = 0; /* SE_CREATE_TOKEN_NAME privilege needed to call NtCreateToken. */ @@ -817,26 +827,37 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw) id of the user account running current process. */ if (usersid == well_known_system_sid) /* nothing to do */; - else if (!GetTokenInformation (hProcToken, TokenStatistics, - &stats, sizeof stats, &size)) - debug_printf - ("GetTokenInformation(hProcToken, TokenStatistics), %E"); else - auth_luid = stats.AuthenticationId; + { + status = NtQueryInformationToken (hProcToken, TokenStatistics, + &stats, sizeof stats, &size); + if (!NT_SUCCESS (status)) + debug_printf ("NtQueryInformationToken(hProcToken, " + "TokenStatistics), %p", status); + else + auth_luid = stats.AuthenticationId; + } /* Retrieving current processes group list to be able to inherit some important well known group sids. */ - if (!GetTokenInformation (hProcToken, TokenGroups, NULL, 0, &size) - && GetLastError () != ERROR_INSUFFICIENT_BUFFER) - debug_printf ("GetTokenInformation(hProcToken, TokenGroups), %E"); + status = NtQueryInformationToken (hProcToken, TokenGroups, NULL, 0, + &size); + if (!NT_SUCCESS (status) && status != STATUS_BUFFER_TOO_SMALL) + debug_printf ("NtQueryInformationToken(hProcToken, TokenGroups), %p", + status); else if (!(my_tok_gsids = (PTOKEN_GROUPS) malloc (size))) debug_printf ("malloc (my_tok_gsids) failed."); - else if (!GetTokenInformation (hProcToken, TokenGroups, my_tok_gsids, - size, &size)) + else { - debug_printf ("GetTokenInformation(hProcToken, TokenGroups), %E"); - free (my_tok_gsids); - my_tok_gsids = NULL; + status = NtQueryInformationToken (hProcToken, TokenGroups, + my_tok_gsids, size, &size); + if (!NT_SUCCESS (status)) + { + debug_printf ("NtQueryInformationToken(hProcToken, TokenGroups), " + "%p", status); + free (my_tok_gsids); + my_tok_gsids = NULL; + } } } diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index c05c58798..40b590af7 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -2961,6 +2961,8 @@ seteuid32 (__uid32_t uid) if (new_token != hProcToken) { + NTSTATUS status; + if (!request_restricted_uid_switch) { /* Avoid having HKCU use default user */ @@ -2969,21 +2971,27 @@ seteuid32 (__uid32_t uid) } /* Try setting owner to same value as user. */ - if (!SetTokenInformation (new_token, TokenOwner, - &usersid, sizeof usersid)) - debug_printf ("SetTokenInformation(user.token, TokenOwner), %E"); + status = NtSetInformationToken (new_token, TokenOwner, + &usersid, sizeof usersid); + if (!NT_SUCCESS (status)) + debug_printf ("NtSetInformationToken (user.token, TokenOwner), %p", + status); /* Try setting primary group in token to current group */ - if (!SetTokenInformation (new_token, TokenPrimaryGroup, - &groups.pgsid, sizeof (cygsid))) - debug_printf ("SetTokenInformation(user.token, TokenPrimaryGroup), %E"); + status = NtSetInformationToken (new_token, TokenPrimaryGroup, + &groups.pgsid, sizeof (cygsid)); + if (!NT_SUCCESS (status)) + debug_printf ("NtSetInformationToken (user.token, TokenPrimaryGroup)," + "%p", status); /* Try setting default DACL */ PACL dacl_buf = (PACL) alloca (MAX_DACL_LEN (5)); if (sec_acl (dacl_buf, true, true, usersid)) { TOKEN_DEFAULT_DACL tdacl = { dacl_buf }; - if (!SetTokenInformation (new_token, TokenDefaultDacl, - &tdacl, sizeof (tdacl))) - debug_printf ("SetTokenInformation (TokenDefaultDacl), %E"); + status = NtSetInformationToken (new_token, TokenDefaultDacl, + &tdacl, sizeof (tdacl)); + if (!NT_SUCCESS (status)) + debug_printf ("NtSetInformationToken (TokenDefaultDacl), %p", + status); } } @@ -3095,6 +3103,7 @@ setegid32 (__gid32_t gid) return 0; } + NTSTATUS status; user_groups * groups = &cygheap->user.groups; cygsid gsid; struct __group32 * gr = internal_getgrgid (gid); @@ -3110,17 +3119,23 @@ setegid32 (__gid32_t gid) if (cygheap->user.issetuid ()) { /* If impersonated, update impersonation token... */ - if (!SetTokenInformation (cygheap->user.primary_token (), - TokenPrimaryGroup, &gsid, sizeof gsid)) - debug_printf ("SetTokenInformation(primary_token, " - "TokenPrimaryGroup), %E"); - if (!SetTokenInformation (cygheap->user.imp_token (), TokenPrimaryGroup, - &gsid, sizeof gsid)) - debug_printf ("SetTokenInformation(token, TokenPrimaryGroup), %E"); + status = NtSetInformationToken (cygheap->user.primary_token (), + TokenPrimaryGroup, &gsid, sizeof gsid); + if (!NT_SUCCESS (status)) + debug_printf ("NtSetInformationToken (primary_token, " + "TokenPrimaryGroup), %p", status); + status = NtSetInformationToken (cygheap->user.imp_token (), + TokenPrimaryGroup, &gsid, sizeof gsid); + if (!NT_SUCCESS (status)) + debug_printf ("NtSetInformationToken (token, TokenPrimaryGroup), %p", + status); } cygheap->user.deimpersonate (); - if (!SetTokenInformation (hProcToken, TokenPrimaryGroup, &gsid, sizeof gsid)) - debug_printf ("SetTokenInformation(hProcToken, TokenPrimaryGroup), %E"); + status = NtSetInformationToken (hProcToken, TokenPrimaryGroup, + &gsid, sizeof gsid); + if (!NT_SUCCESS (status)) + debug_printf ("NtSetInformationToken (hProcToken, TokenPrimaryGroup), %p", + status); clear_procimptoken (); cygheap->user.reimpersonate (); return 0; diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index dd2d6ed9c..dd87bd5f0 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -59,32 +59,35 @@ cygheap_user::init () else set_name ("unknown"); - DWORD siz; + NTSTATUS status; + ULONG size; PSECURITY_DESCRIPTOR psd; - if (!GetTokenInformation (hProcToken, TokenPrimaryGroup, - &groups.pgsid, sizeof (cygsid), &siz)) - system_printf ("GetTokenInformation (TokenPrimaryGroup), %E"); + status = NtQueryInformationToken (hProcToken, TokenPrimaryGroup, + &groups.pgsid, sizeof (cygsid), &size); + if (!NT_SUCCESS (status)) + system_printf ("NtQueryInformationToken (TokenPrimaryGroup), %p", status); /* Get the SID from current process and store it in effec_cygsid */ - if (!GetTokenInformation (hProcToken, TokenUser, &effec_cygsid, - sizeof (cygsid), &siz)) + status = NtQueryInformationToken (hProcToken, TokenUser, &effec_cygsid, + sizeof (cygsid), &size); + if (!NT_SUCCESS (status)) { - system_printf ("GetTokenInformation (TokenUser), %E"); + system_printf ("NtQueryInformationToken (TokenUser), %p", status); return; } /* Set token owner to the same value as token user */ - if (!SetTokenInformation (hProcToken, TokenOwner, &effec_cygsid, - sizeof (cygsid))) - debug_printf ("SetTokenInformation(TokenOwner), %E"); + status = NtSetInformationToken (hProcToken, TokenOwner, &effec_cygsid, + sizeof (cygsid)); + if (!NT_SUCCESS (status)) + debug_printf ("NtSetInformationToken(TokenOwner), %p", status); /* Standard way to build a security descriptor with the usual DACL */ PSECURITY_ATTRIBUTES sa_buf = (PSECURITY_ATTRIBUTES) alloca (1024); psd = (PSECURITY_DESCRIPTOR) (sec_user_nih (sa_buf, sid()))->lpSecurityDescriptor; - NTSTATUS status; BOOLEAN acl_exists, dummy; TOKEN_DEFAULT_DACL dacl; @@ -94,9 +97,10 @@ cygheap_user::init () { /* Set the default DACL and the process DACL */ - if (!SetTokenInformation (hProcToken, TokenDefaultDacl, &dacl, - sizeof (dacl))) - system_printf ("SetTokenInformation (TokenDefaultDacl), %E"); + status = NtSetInformationToken (hProcToken, TokenDefaultDacl, &dacl, + sizeof (dacl)); + if (!NT_SUCCESS (status)) + system_printf ("NtSetInformationToken (TokenDefaultDacl), %p", status); if ((status = NtSetSecurityObject (NtCurrentProcess (), DACL_SECURITY_INFORMATION, psd))) system_printf ("NtSetSecurityObject, %lx", status); @@ -128,9 +132,12 @@ internal_getlogin (cygheap_user &user) if (gsid != user.groups.pgsid) { /* Set primary group to the group in /etc/passwd. */ - if (!SetTokenInformation (hProcToken, TokenPrimaryGroup, - &gsid, sizeof gsid)) - debug_printf ("SetTokenInformation(TokenPrimaryGroup), %E"); + NTSTATUS status = NtSetInformationToken (hProcToken, + TokenPrimaryGroup, + &gsid, sizeof gsid); + if (!NT_SUCCESS (status)) + debug_printf ("NtSetInformationToken (TokenPrimaryGroup), %p", + status); else user.groups.pgsid = gsid; clear_procimptoken ();