[newlib-cygwin] setuid: Create token from scratch without credentials of caller
Corinna Vinschen
corinna@sourceware.org
Thu Feb 18 10:31:00 GMT 2016
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=205862ed08649df8f50b926a2c58c963f571b044
commit 205862ed08649df8f50b926a2c58c963f571b044
Author: Corinna Vinschen <corinna@vinschen.de>
Date: Wed Feb 17 16:40:27 2016 +0100
setuid: Create token from scratch without credentials of caller
* sec_auth.cc (get_token_group_sidlist): Drop auth_luid and
auth_pos parameter. Remove code adding a logon SID.
(get_initgroups_sidlist): Drop auth_luid and auth_pos parameter.
Drop in call to get_token_group_sidlist. Accommodate in callers.
(get_setgroups_sidlist): Ditto.
(create_token): Explicitely set auth_luid to ANONYMOUS_LOGON_LUID
or LOCALSERVICE_LUID depending on OS. Explain why.
Remove handling of logon SID since we don't generate one anymore.
(lsaauth): Drop now unused local variable auth_luid and auth_pos.
* wincap.h (wincaps::has_broken_whoami): New element.
* wincap.cc: Implement above element throughout.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diff:
---
winsup/cygwin/sec_auth.cc | 55 +++++++++++++++++------------------------------
winsup/cygwin/wincap.cc | 7 ++++++
winsup/cygwin/wincap.h | 2 ++
3 files changed, 29 insertions(+), 35 deletions(-)
diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc
index d44cb2d..ba29339 100644
--- a/winsup/cygwin/sec_auth.cc
+++ b/winsup/cygwin/sec_auth.cc
@@ -503,10 +503,8 @@ sid_in_token_groups (PTOKEN_GROUPS grps, cygpsid sid)
}
static void
-get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps,
- LUID auth_luid, int &auth_pos)
+get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps)
{
- auth_pos = -1;
if (my_grps)
{
grp_list += well_known_local_sid;
@@ -538,16 +536,6 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps,
grp_list *= well_known_interactive_sid;
grp_list *= well_known_users_sid;
}
- if (get_ll (auth_luid) != 999LL) /* != SYSTEM_LUID */
- {
- for (DWORD i = 0; i < my_grps->GroupCount; ++i)
- if (my_grps->Groups[i].Attributes & SE_GROUP_LOGON_ID)
- {
- grp_list += my_grps->Groups[i].Sid;
- auth_pos = grp_list.count () - 1;
- break;
- }
- }
}
bool
@@ -589,14 +577,12 @@ get_server_groups (cygsidlist &grp_list, PSID usersid)
static bool
get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
- PTOKEN_GROUPS my_grps, LUID auth_luid, int &auth_pos)
+ PTOKEN_GROUPS my_grps)
{
grp_list *= well_known_world_sid;
grp_list *= well_known_authenticated_users_sid;
- if (well_known_system_sid == usersid)
- auth_pos = -1;
- else
- get_token_group_sidlist (grp_list, my_grps, auth_luid, auth_pos);
+ if (well_known_system_sid != usersid)
+ get_token_group_sidlist (grp_list, my_grps);
if (!get_server_groups (grp_list, usersid))
return false;
@@ -607,12 +593,11 @@ get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
static void
get_setgroups_sidlist (cygsidlist &tmp_list, PSID usersid,
- PTOKEN_GROUPS my_grps, user_groups &groups,
- LUID auth_luid, int &auth_pos)
+ PTOKEN_GROUPS my_grps, user_groups &groups)
{
tmp_list *= well_known_world_sid;
tmp_list *= well_known_authenticated_users_sid;
- get_token_group_sidlist (tmp_list, my_grps, auth_luid, auth_pos);
+ get_token_group_sidlist (tmp_list, my_grps);
get_server_groups (tmp_list, usersid);
for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
tmp_list += groups.sgsids.sids[gidx];
@@ -891,7 +876,16 @@ create_token (cygsid &usersid, user_groups &new_groups)
SECURITY_QUALITY_OF_SERVICE sqos =
{ sizeof sqos, SecurityImpersonation, SECURITY_STATIC_TRACKING, FALSE };
OBJECT_ATTRIBUTES oa = { sizeof oa, 0, 0, 0, 0, &sqos };
- LUID auth_luid = SYSTEM_LUID;
+ /* Up to Windows 7, when using a authwentication LUID other than "Anonymous",
+ Windows whoami prints the wrong username, the one from the login session,
+ not the one from the actual user token of the process. This is apparently
+ fixed in Windows 8. However, starting with Windows 8, access rights of
+ the anonymous logon session is further restricted. Therefore we create
+ the new user token with the authentication id of the local service
+ account. Hopefully that's sufficient. */
+ const LUID auth_luid_7 = ANONYMOUS_LOGON_LUID;
+ const LUID auth_luid_8 = LOCALSERVICE_LUID;
+ LUID auth_luid = wincap.has_broken_whoami () ? auth_luid_7 : auth_luid_8;
LARGE_INTEGER exp = { QuadPart:INT64_MAX };
TOKEN_USER user;
@@ -940,8 +934,6 @@ create_token (cygsid &usersid, user_groups &new_groups)
if (!NT_SUCCESS (status))
debug_printf ("NtQueryInformationToken(hProcToken, "
"TokenStatistics), %y", status);
- else
- auth_luid = stats.AuthenticationId;
}
/* Retrieving current processes group list to be able to inherit
@@ -968,12 +960,10 @@ create_token (cygsid &usersid, user_groups &new_groups)
}
/* Create list of groups, the user is member in. */
- int auth_pos;
if (new_groups.issetgroups ())
- get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups,
- auth_luid, auth_pos);
+ get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups);
else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
- my_tok_gsids, auth_luid, auth_pos))
+ my_tok_gsids))
goto out;
/* Primary group. */
@@ -991,8 +981,6 @@ create_token (cygsid &usersid, user_groups &new_groups)
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_ENABLED;
}
- if (auth_pos >= 0)
- new_tok_gsids->Groups[auth_pos].Attributes |= SE_GROUP_LOGON_ID;
/* Retrieve list of privileges of that user. Based on the usersid and
the returned privileges, get_priv_list sets the mandatory_integrity_sid
@@ -1052,7 +1040,6 @@ lsaauth (cygsid &usersid, user_groups &new_groups)
LSA_OPERATIONAL_MODE sec_mode;
NTSTATUS status, sub_status;
ULONG package_id, size;
- LUID auth_luid = SYSTEM_LUID;
struct {
LSA_STRING str;
CHAR buf[16];
@@ -1115,12 +1102,10 @@ lsaauth (cygsid &usersid, user_groups &new_groups)
ts.SourceIdentifier.LowPart = 0x0103;
/* Create list of groups, the user is member in. */
- int auth_pos;
if (new_groups.issetgroups ())
- get_setgroups_sidlist (tmp_gsids, usersid, NULL, new_groups, auth_luid,
- auth_pos);
+ get_setgroups_sidlist (tmp_gsids, usersid, NULL, new_groups);
else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
- NULL, auth_luid, auth_pos))
+ NULL))
goto out;
tmp_gsids.debug_print ("tmp_gsids");
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index 201bd25..c7c9f2e 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -52,6 +52,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_processor_groups:false,
has_broken_prefetchvm:false,
has_new_pebteb_region:false,
+ has_broken_whoami:true,
};
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -86,6 +87,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_processor_groups:false,
has_broken_prefetchvm:false,
has_new_pebteb_region:false,
+ has_broken_whoami:true,
};
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -120,6 +122,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
has_processor_groups:false,
has_broken_prefetchvm:false,
has_new_pebteb_region:false,
+ has_broken_whoami:true,
};
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -154,6 +157,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_processor_groups:true,
has_broken_prefetchvm:false,
has_new_pebteb_region:false,
+ has_broken_whoami:true,
};
wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -188,6 +192,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_processor_groups:true,
has_broken_prefetchvm:false,
has_new_pebteb_region:false,
+ has_broken_whoami:false,
};
wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -222,6 +227,7 @@ wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_processor_groups:true,
has_broken_prefetchvm:true,
has_new_pebteb_region:false,
+ has_broken_whoami:false,
};
wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -256,6 +262,7 @@ wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) =
has_processor_groups:true,
has_broken_prefetchvm:false,
has_new_pebteb_region:true,
+ has_broken_whoami:false,
};
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index 4508974..9e29d4f 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -45,6 +45,7 @@ struct wincaps
unsigned has_processor_groups : 1;
unsigned has_broken_prefetchvm : 1;
unsigned has_new_pebteb_region : 1;
+ unsigned has_broken_whoami : 1;
};
class wincapc
@@ -104,6 +105,7 @@ public:
bool IMPLEMENT (has_processor_groups)
bool IMPLEMENT (has_broken_prefetchvm)
bool IMPLEMENT (has_new_pebteb_region)
+ bool IMPLEMENT (has_broken_whoami)
#undef IMPLEMENT
};
More information about the Cygwin-cvs
mailing list