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:
parent
182e2502c8
commit
205862ed08
|
@ -503,10 +503,8 @@ sid_in_token_groups (PTOKEN_GROUPS grps, cygpsid sid)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps,
|
get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps)
|
||||||
LUID auth_luid, int &auth_pos)
|
|
||||||
{
|
{
|
||||||
auth_pos = -1;
|
|
||||||
if (my_grps)
|
if (my_grps)
|
||||||
{
|
{
|
||||||
grp_list += well_known_local_sid;
|
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_interactive_sid;
|
||||||
grp_list *= well_known_users_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
|
bool
|
||||||
|
@ -589,14 +577,12 @@ get_server_groups (cygsidlist &grp_list, PSID usersid)
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
|
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_world_sid;
|
||||||
grp_list *= well_known_authenticated_users_sid;
|
grp_list *= well_known_authenticated_users_sid;
|
||||||
if (well_known_system_sid == usersid)
|
if (well_known_system_sid != usersid)
|
||||||
auth_pos = -1;
|
get_token_group_sidlist (grp_list, my_grps);
|
||||||
else
|
|
||||||
get_token_group_sidlist (grp_list, my_grps, auth_luid, auth_pos);
|
|
||||||
if (!get_server_groups (grp_list, usersid))
|
if (!get_server_groups (grp_list, usersid))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -607,12 +593,11 @@ get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_setgroups_sidlist (cygsidlist &tmp_list, PSID usersid,
|
get_setgroups_sidlist (cygsidlist &tmp_list, PSID usersid,
|
||||||
PTOKEN_GROUPS my_grps, user_groups &groups,
|
PTOKEN_GROUPS my_grps, user_groups &groups)
|
||||||
LUID auth_luid, int &auth_pos)
|
|
||||||
{
|
{
|
||||||
tmp_list *= well_known_world_sid;
|
tmp_list *= well_known_world_sid;
|
||||||
tmp_list *= well_known_authenticated_users_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);
|
get_server_groups (tmp_list, usersid);
|
||||||
for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
|
for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
|
||||||
tmp_list += groups.sgsids.sids[gidx];
|
tmp_list += groups.sgsids.sids[gidx];
|
||||||
|
@ -891,7 +876,16 @@ create_token (cygsid &usersid, user_groups &new_groups)
|
||||||
SECURITY_QUALITY_OF_SERVICE sqos =
|
SECURITY_QUALITY_OF_SERVICE sqos =
|
||||||
{ sizeof sqos, SecurityImpersonation, SECURITY_STATIC_TRACKING, FALSE };
|
{ sizeof sqos, SecurityImpersonation, SECURITY_STATIC_TRACKING, FALSE };
|
||||||
OBJECT_ATTRIBUTES oa = { sizeof oa, 0, 0, 0, 0, &sqos };
|
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 };
|
LARGE_INTEGER exp = { QuadPart:INT64_MAX };
|
||||||
|
|
||||||
TOKEN_USER user;
|
TOKEN_USER user;
|
||||||
|
@ -940,8 +934,6 @@ create_token (cygsid &usersid, user_groups &new_groups)
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
debug_printf ("NtQueryInformationToken(hProcToken, "
|
debug_printf ("NtQueryInformationToken(hProcToken, "
|
||||||
"TokenStatistics), %y", status);
|
"TokenStatistics), %y", status);
|
||||||
else
|
|
||||||
auth_luid = stats.AuthenticationId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieving current processes group list to be able to inherit
|
/* 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. */
|
/* Create list of groups, the user is member in. */
|
||||||
int auth_pos;
|
|
||||||
if (new_groups.issetgroups ())
|
if (new_groups.issetgroups ())
|
||||||
get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups,
|
get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups);
|
||||||
auth_luid, auth_pos);
|
|
||||||
else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
|
else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
|
||||||
my_tok_gsids, auth_luid, auth_pos))
|
my_tok_gsids))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Primary group. */
|
/* Primary group. */
|
||||||
|
@ -991,8 +981,6 @@ create_token (cygsid &usersid, user_groups &new_groups)
|
||||||
| SE_GROUP_ENABLED_BY_DEFAULT
|
| SE_GROUP_ENABLED_BY_DEFAULT
|
||||||
| SE_GROUP_ENABLED;
|
| 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
|
/* Retrieve list of privileges of that user. Based on the usersid and
|
||||||
the returned privileges, get_priv_list sets the mandatory_integrity_sid
|
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;
|
LSA_OPERATIONAL_MODE sec_mode;
|
||||||
NTSTATUS status, sub_status;
|
NTSTATUS status, sub_status;
|
||||||
ULONG package_id, size;
|
ULONG package_id, size;
|
||||||
LUID auth_luid = SYSTEM_LUID;
|
|
||||||
struct {
|
struct {
|
||||||
LSA_STRING str;
|
LSA_STRING str;
|
||||||
CHAR buf[16];
|
CHAR buf[16];
|
||||||
|
@ -1115,12 +1102,10 @@ lsaauth (cygsid &usersid, user_groups &new_groups)
|
||||||
ts.SourceIdentifier.LowPart = 0x0103;
|
ts.SourceIdentifier.LowPart = 0x0103;
|
||||||
|
|
||||||
/* Create list of groups, the user is member in. */
|
/* Create list of groups, the user is member in. */
|
||||||
int auth_pos;
|
|
||||||
if (new_groups.issetgroups ())
|
if (new_groups.issetgroups ())
|
||||||
get_setgroups_sidlist (tmp_gsids, usersid, NULL, new_groups, auth_luid,
|
get_setgroups_sidlist (tmp_gsids, usersid, NULL, new_groups);
|
||||||
auth_pos);
|
|
||||||
else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
|
else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
|
||||||
NULL, auth_luid, auth_pos))
|
NULL))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
tmp_gsids.debug_print ("tmp_gsids");
|
tmp_gsids.debug_print ("tmp_gsids");
|
||||||
|
|
|
@ -52,6 +52,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
||||||
has_processor_groups:false,
|
has_processor_groups:false,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
has_new_pebteb_region:false,
|
has_new_pebteb_region:false,
|
||||||
|
has_broken_whoami:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_processor_groups:false,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
has_new_pebteb_region:false,
|
has_new_pebteb_region:false,
|
||||||
|
has_broken_whoami:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_processor_groups:false,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
has_new_pebteb_region:false,
|
has_new_pebteb_region:false,
|
||||||
|
has_broken_whoami:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_processor_groups:true,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
has_new_pebteb_region:false,
|
has_new_pebteb_region:false,
|
||||||
|
has_broken_whoami:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_processor_groups:true,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
has_new_pebteb_region:false,
|
has_new_pebteb_region:false,
|
||||||
|
has_broken_whoami:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_processor_groups:true,
|
||||||
has_broken_prefetchvm:true,
|
has_broken_prefetchvm:true,
|
||||||
has_new_pebteb_region:false,
|
has_new_pebteb_region:false,
|
||||||
|
has_broken_whoami:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_processor_groups:true,
|
||||||
has_broken_prefetchvm:false,
|
has_broken_prefetchvm:false,
|
||||||
has_new_pebteb_region:true,
|
has_new_pebteb_region:true,
|
||||||
|
has_broken_whoami:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
||||||
|
|
|
@ -45,6 +45,7 @@ struct wincaps
|
||||||
unsigned has_processor_groups : 1;
|
unsigned has_processor_groups : 1;
|
||||||
unsigned has_broken_prefetchvm : 1;
|
unsigned has_broken_prefetchvm : 1;
|
||||||
unsigned has_new_pebteb_region : 1;
|
unsigned has_new_pebteb_region : 1;
|
||||||
|
unsigned has_broken_whoami : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class wincapc
|
class wincapc
|
||||||
|
@ -104,6 +105,7 @@ public:
|
||||||
bool IMPLEMENT (has_processor_groups)
|
bool IMPLEMENT (has_processor_groups)
|
||||||
bool IMPLEMENT (has_broken_prefetchvm)
|
bool IMPLEMENT (has_broken_prefetchvm)
|
||||||
bool IMPLEMENT (has_new_pebteb_region)
|
bool IMPLEMENT (has_new_pebteb_region)
|
||||||
|
bool IMPLEMENT (has_broken_whoami)
|
||||||
|
|
||||||
#undef IMPLEMENT
|
#undef IMPLEMENT
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue