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>
This commit is contained in:
Corinna Vinschen 2016-02-17 16:40:27 +01:00
parent 182e2502c8
commit 205862ed08
3 changed files with 29 additions and 35 deletions

View File

@ -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");

View File

@ -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));

View File

@ -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
};