Cygwin: drop create_token and dependent functions
Given we only called create_token on W7 WOW64 anyway, we can now drop this function and all other functions only called from there entirely. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
23b5466aed
commit
7bed18558d
|
@ -379,41 +379,6 @@ sid_in_token_groups (PTOKEN_GROUPS grps, cygpsid sid)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps)
|
|
||||||
{
|
|
||||||
if (my_grps)
|
|
||||||
{
|
|
||||||
grp_list += well_known_local_sid;
|
|
||||||
grp_list += well_known_console_logon_sid;
|
|
||||||
if (sid_in_token_groups (my_grps, well_known_dialup_sid))
|
|
||||||
grp_list *= well_known_dialup_sid;
|
|
||||||
if (sid_in_token_groups (my_grps, well_known_network_sid))
|
|
||||||
grp_list *= well_known_network_sid;
|
|
||||||
if (sid_in_token_groups (my_grps, well_known_batch_sid))
|
|
||||||
grp_list *= well_known_batch_sid;
|
|
||||||
grp_list *= well_known_interactive_sid;
|
|
||||||
#if 0
|
|
||||||
/* Don't add the SERVICE group when switching the user context.
|
|
||||||
That's much too dangerous, since the service group adds the
|
|
||||||
SE_IMPERSONATE_NAME privilege to the user. After all, the
|
|
||||||
process started with this token is not the service process
|
|
||||||
anymore anyway. */
|
|
||||||
if (sid_in_token_groups (my_grps, well_known_service_sid))
|
|
||||||
grp_list *= well_known_service_sid;
|
|
||||||
#endif
|
|
||||||
if (sid_in_token_groups (my_grps, well_known_this_org_sid))
|
|
||||||
grp_list *= well_known_this_org_sid;
|
|
||||||
grp_list *= well_known_users_sid;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
grp_list += well_known_local_sid;
|
|
||||||
grp_list *= well_known_interactive_sid;
|
|
||||||
grp_list *= well_known_users_sid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
get_server_groups (cygsidlist &grp_list, PSID usersid,
|
get_server_groups (cygsidlist &grp_list, PSID usersid,
|
||||||
acct_disabled_chk_t check_account_disabled)
|
acct_disabled_chk_t check_account_disabled)
|
||||||
|
@ -470,180 +435,6 @@ get_server_groups (cygsidlist &grp_list, PSID usersid,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
|
|
||||||
PTOKEN_GROUPS my_grps)
|
|
||||||
{
|
|
||||||
if (well_known_system_sid != usersid)
|
|
||||||
get_token_group_sidlist (grp_list, my_grps);
|
|
||||||
if (!get_server_groups (grp_list, usersid, CHK_DISABLED))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* special_pgrp true if pgrpsid is not in normal groups */
|
|
||||||
grp_list += pgrpsid;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
get_setgroups_sidlist (cygsidlist &tmp_list, PSID usersid,
|
|
||||||
PTOKEN_GROUPS my_grps, user_groups &groups)
|
|
||||||
{
|
|
||||||
get_token_group_sidlist (tmp_list, my_grps);
|
|
||||||
if (!get_server_groups (tmp_list, usersid, CHK_DISABLED))
|
|
||||||
return false;
|
|
||||||
for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
|
|
||||||
tmp_list += groups.sgsids.sids[gidx];
|
|
||||||
tmp_list += groups.pgsid;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fixed size TOKEN_PRIVILEGES list to reflect privileges given to the
|
|
||||||
SYSTEM account by default. */
|
|
||||||
const struct
|
|
||||||
{
|
|
||||||
DWORD PrivilegeCount;
|
|
||||||
LUID_AND_ATTRIBUTES Privileges[28];
|
|
||||||
} sys_privs =
|
|
||||||
{
|
|
||||||
28,
|
|
||||||
{
|
|
||||||
{ { SE_CREATE_TOKEN_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_LOCK_MEMORY_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_INCREASE_QUOTA_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_TCB_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_SECURITY_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_TAKE_OWNERSHIP_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_LOAD_DRIVER_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_SYSTEM_PROFILE_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_SYSTEMTIME_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_PROF_SINGLE_PROCESS_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_INC_BASE_PRIORITY_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_CREATE_PAGEFILE_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_CREATE_PERMANENT_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_BACKUP_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_RESTORE_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_SHUTDOWN_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_DEBUG_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_AUDIT_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_SYSTEM_ENVIRONMENT_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_CHANGE_NOTIFY_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_UNDOCK_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_MANAGE_VOLUME_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_IMPERSONATE_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_CREATE_GLOBAL_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_INCREASE_WORKING_SET_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_TIME_ZONE_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT },
|
|
||||||
{ { SE_CREATE_SYMBOLIC_LINK_PRIVILEGE, 0 },
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static PTOKEN_PRIVILEGES
|
|
||||||
get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
|
|
||||||
size_t &size, cygpsid *mandatory_integrity_sid)
|
|
||||||
{
|
|
||||||
PLSA_UNICODE_STRING privstrs;
|
|
||||||
ULONG cnt;
|
|
||||||
PTOKEN_PRIVILEGES privs = NULL;
|
|
||||||
|
|
||||||
if (usersid == well_known_system_sid)
|
|
||||||
{
|
|
||||||
if (mandatory_integrity_sid)
|
|
||||||
*mandatory_integrity_sid = mandatory_system_integrity_sid;
|
|
||||||
return (PTOKEN_PRIVILEGES) &sys_privs;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mandatory_integrity_sid)
|
|
||||||
*mandatory_integrity_sid = mandatory_medium_integrity_sid;
|
|
||||||
|
|
||||||
for (int grp = -1; grp < grp_list.count (); ++grp)
|
|
||||||
{
|
|
||||||
if (grp == -1)
|
|
||||||
{
|
|
||||||
if (LsaEnumerateAccountRights (lsa, usersid, &privstrs, &cnt)
|
|
||||||
!= STATUS_SUCCESS)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (LsaEnumerateAccountRights (lsa, grp_list.sids[grp],
|
|
||||||
&privstrs, &cnt) != STATUS_SUCCESS)
|
|
||||||
continue;
|
|
||||||
for (ULONG i = 0; i < cnt; ++i)
|
|
||||||
{
|
|
||||||
LUID priv;
|
|
||||||
PTOKEN_PRIVILEGES tmp;
|
|
||||||
DWORD tmp_count;
|
|
||||||
bool high_integrity;
|
|
||||||
|
|
||||||
if (!privilege_luid (privstrs[i].Buffer, priv, high_integrity))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (privs)
|
|
||||||
{
|
|
||||||
DWORD pcnt = privs->PrivilegeCount;
|
|
||||||
LUID_AND_ATTRIBUTES *p = privs->Privileges;
|
|
||||||
for (; pcnt > 0; --pcnt, ++p)
|
|
||||||
if (priv.HighPart == p->Luid.HighPart
|
|
||||||
&& priv.LowPart == p->Luid.LowPart)
|
|
||||||
goto next_account_right;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp_count = privs ? privs->PrivilegeCount : 0;
|
|
||||||
size = sizeof (DWORD)
|
|
||||||
+ (tmp_count + 1) * sizeof (LUID_AND_ATTRIBUTES);
|
|
||||||
tmp = (PTOKEN_PRIVILEGES) realloc (privs, size);
|
|
||||||
if (!tmp)
|
|
||||||
{
|
|
||||||
if (privs)
|
|
||||||
free (privs);
|
|
||||||
LsaFreeMemory (privstrs);
|
|
||||||
debug_printf ("realloc (privs) failed.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
tmp->PrivilegeCount = tmp_count;
|
|
||||||
privs = tmp;
|
|
||||||
privs->Privileges[privs->PrivilegeCount].Luid = priv;
|
|
||||||
privs->Privileges[privs->PrivilegeCount].Attributes =
|
|
||||||
SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;
|
|
||||||
++privs->PrivilegeCount;
|
|
||||||
if (mandatory_integrity_sid && high_integrity)
|
|
||||||
*mandatory_integrity_sid = mandatory_high_integrity_sid;
|
|
||||||
|
|
||||||
next_account_right:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
LsaFreeMemory (privstrs);
|
|
||||||
}
|
|
||||||
return privs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Accept a token if
|
/* Accept a token if
|
||||||
- the requested usersid matches the TokenUser and
|
- the requested usersid matches the TokenUser and
|
||||||
- if setgroups has been called:
|
- if setgroups has been called:
|
||||||
|
@ -654,9 +445,8 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
|
||||||
they match and verify only the primary groups.
|
they match and verify only the primary groups.
|
||||||
The requested primary group must appear in the token.
|
The requested primary group must appear in the token.
|
||||||
The primary group in the token is a group associated with the usersid,
|
The primary group in the token is a group associated with the usersid,
|
||||||
except if the token is internal and the group is in the token SD
|
except if the token is internal and the group is in the token SD. In
|
||||||
(see create_token). In that latter case that group must match the
|
that latter case that group must match the requested primary group. */
|
||||||
requested primary group. */
|
|
||||||
bool
|
bool
|
||||||
verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
|
verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
|
||||||
{
|
{
|
||||||
|
@ -786,160 +576,6 @@ account_restriction (NTSTATUS status)
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE
|
|
||||||
create_token (cygsid &usersid, user_groups &new_groups)
|
|
||||||
{
|
|
||||||
NTSTATUS status;
|
|
||||||
LSA_HANDLE lsa = NULL;
|
|
||||||
|
|
||||||
cygsidlist tmp_gsids (cygsidlist_auto, 12);
|
|
||||||
|
|
||||||
SECURITY_QUALITY_OF_SERVICE sqos =
|
|
||||||
{ sizeof sqos, SecurityImpersonation, SECURITY_STATIC_TRACKING, FALSE };
|
|
||||||
OBJECT_ATTRIBUTES oa = { sizeof oa, 0, 0, 0, 0, &sqos };
|
|
||||||
/* Up to Windows 7, when using an authentication 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;
|
|
||||||
PTOKEN_GROUPS new_tok_gsids = NULL;
|
|
||||||
PTOKEN_PRIVILEGES privs = NULL;
|
|
||||||
TOKEN_OWNER owner;
|
|
||||||
TOKEN_PRIMARY_GROUP pgrp;
|
|
||||||
TOKEN_DEFAULT_DACL dacl = {};
|
|
||||||
TOKEN_SOURCE source;
|
|
||||||
TOKEN_STATISTICS stats;
|
|
||||||
memcpy (source.SourceName, "Cygwin.1", 8);
|
|
||||||
source.SourceIdentifier.HighPart = 0;
|
|
||||||
source.SourceIdentifier.LowPart = 0x0101;
|
|
||||||
|
|
||||||
HANDLE token = NULL;
|
|
||||||
HANDLE primary_token = NULL;
|
|
||||||
|
|
||||||
tmp_pathbuf tp;
|
|
||||||
PTOKEN_GROUPS my_tok_gsids = NULL;
|
|
||||||
cygpsid mandatory_integrity_sid;
|
|
||||||
ULONG size;
|
|
||||||
size_t psize = 0;
|
|
||||||
|
|
||||||
/* SE_CREATE_TOKEN_NAME privilege needed to call NtCreateToken. */
|
|
||||||
push_self_privilege (SE_CREATE_TOKEN_PRIVILEGE, true);
|
|
||||||
|
|
||||||
/* Open policy object. */
|
|
||||||
if (!(lsa = lsa_open_policy (NULL, POLICY_EXECUTE)))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* User, owner, primary group. */
|
|
||||||
user.User.Sid = usersid;
|
|
||||||
user.User.Attributes = 0;
|
|
||||||
owner.Owner = usersid;
|
|
||||||
|
|
||||||
/* Retrieve authentication id and group list from own process. */
|
|
||||||
if (hProcToken)
|
|
||||||
{
|
|
||||||
/* Switching user context to SYSTEM doesn't inherit the authentication
|
|
||||||
id of the user account running current process. */
|
|
||||||
if (usersid == well_known_system_sid)
|
|
||||||
/* nothing to do */;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = NtQueryInformationToken (hProcToken, TokenStatistics,
|
|
||||||
&stats, sizeof stats, &size);
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
debug_printf ("NtQueryInformationToken(hProcToken, "
|
|
||||||
"TokenStatistics), %y", status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Retrieving current processes group list to be able to inherit
|
|
||||||
some important well known group sids. */
|
|
||||||
my_tok_gsids = (PTOKEN_GROUPS) tp.w_get ();
|
|
||||||
status = NtQueryInformationToken (hProcToken, TokenGroups, my_tok_gsids,
|
|
||||||
2 * NT_MAX_PATH, &size);
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
{
|
|
||||||
debug_printf ("NtQueryInformationToken(hProcToken, TokenGroups), "
|
|
||||||
"%y", status);
|
|
||||||
my_tok_gsids = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create list of groups, the user is member in. */
|
|
||||||
if (new_groups.issetgroups ())
|
|
||||||
{
|
|
||||||
if (!get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups))
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
|
|
||||||
my_tok_gsids))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* Primary group. */
|
|
||||||
pgrp.PrimaryGroup = new_groups.pgsid;
|
|
||||||
|
|
||||||
/* Create a TOKEN_GROUPS list from the above retrieved list of sids. */
|
|
||||||
new_tok_gsids = (PTOKEN_GROUPS)
|
|
||||||
alloca (sizeof (DWORD) + (tmp_gsids.count () + 1)
|
|
||||||
* sizeof (SID_AND_ATTRIBUTES));
|
|
||||||
new_tok_gsids->GroupCount = tmp_gsids.count ();
|
|
||||||
for (DWORD i = 0; i < new_tok_gsids->GroupCount; ++i)
|
|
||||||
{
|
|
||||||
new_tok_gsids->Groups[i].Sid = tmp_gsids.sids[i];
|
|
||||||
new_tok_gsids->Groups[i].Attributes = SE_GROUP_MANDATORY
|
|
||||||
| SE_GROUP_ENABLED_BY_DEFAULT
|
|
||||||
| SE_GROUP_ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Retrieve list of privileges of that user. Based on the usersid and
|
|
||||||
the returned privileges, get_priv_list sets the mandatory_integrity_sid
|
|
||||||
pointer to the correct MIC SID for UAC. */
|
|
||||||
if (!(privs = get_priv_list (lsa, usersid, tmp_gsids, psize,
|
|
||||||
&mandatory_integrity_sid)))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
new_tok_gsids->Groups[new_tok_gsids->GroupCount].Attributes =
|
|
||||||
SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED;
|
|
||||||
new_tok_gsids->Groups[new_tok_gsids->GroupCount++].Sid
|
|
||||||
= mandatory_integrity_sid;
|
|
||||||
|
|
||||||
/* Let's be heroic... */
|
|
||||||
status = NtCreateToken (&token, TOKEN_ALL_ACCESS, &oa, TokenImpersonation,
|
|
||||||
&auth_luid, &exp, &user, new_tok_gsids, privs, &owner,
|
|
||||||
&pgrp, &dacl, &source);
|
|
||||||
if (status)
|
|
||||||
__seterrno_from_nt_status (status);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Convert to primary token. */
|
|
||||||
if (!DuplicateTokenEx (token, MAXIMUM_ALLOWED, &sec_none,
|
|
||||||
SecurityImpersonation, TokenPrimary,
|
|
||||||
&primary_token))
|
|
||||||
{
|
|
||||||
__seterrno ();
|
|
||||||
debug_printf ("DuplicateTokenEx %E");
|
|
||||||
primary_token = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
pop_self_privilege ();
|
|
||||||
if (token != INVALID_HANDLE_VALUE)
|
|
||||||
CloseHandle (token);
|
|
||||||
if (privs && privs != (PTOKEN_PRIVILEGES) &sys_privs)
|
|
||||||
free (privs);
|
|
||||||
lsa_close_policy (lsa);
|
|
||||||
|
|
||||||
debug_printf ("%p = create_token ()", primary_token);
|
|
||||||
return primary_token;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SFU_LSA_KEY_SUFFIX L"_microsoft_sfu_utility"
|
#define SFU_LSA_KEY_SUFFIX L"_microsoft_sfu_utility"
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
|
|
|
@ -457,8 +457,6 @@ int setacl (HANDLE, path_conv &, int, struct acl *, bool &);
|
||||||
|
|
||||||
/* Set impersonation or restricted token. */
|
/* Set impersonation or restricted token. */
|
||||||
void set_imp_token (HANDLE token, int type);
|
void set_imp_token (HANDLE token, int type);
|
||||||
/* Function creating a token by calling NtCreateToken. */
|
|
||||||
HANDLE create_token (cygsid &usersid, user_groups &groups);
|
|
||||||
/* LSA private key storage authentication, same as when using service logons. */
|
/* LSA private key storage authentication, same as when using service logons. */
|
||||||
HANDLE lsaprivkeyauth (struct passwd *pw);
|
HANDLE lsaprivkeyauth (struct passwd *pw);
|
||||||
/* Kerberos or MsV1 S4U logon. */
|
/* Kerberos or MsV1 S4U logon. */
|
||||||
|
|
|
@ -752,11 +752,9 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
sa = sec_user ((PSECURITY_ATTRIBUTES) alloca (1024),
|
sa = sec_user ((PSECURITY_ATTRIBUTES) alloca (1024),
|
||||||
::cygheap->user.sid ());
|
::cygheap->user.sid ());
|
||||||
/* We're creating a window station per user, not per logon
|
/* We're creating a window station per user, not per logon
|
||||||
session First of all we might not have a valid logon session
|
session. It doesn't make sense in terms of security to
|
||||||
for the user (logon by create_token), and second, it doesn't
|
create a new window station for every logon of the same user.
|
||||||
make sense in terms of security to create a new window
|
It just fills up the system with window stations. */
|
||||||
station for every logon of the same user. It just fills up
|
|
||||||
the system with window stations for no good reason. */
|
|
||||||
hwst = CreateWindowStationW (::cygheap->user.get_windows_id (sid),
|
hwst = CreateWindowStationW (::cygheap->user.get_windows_id (sid),
|
||||||
0, GENERIC_READ | GENERIC_WRITE, sa);
|
0, GENERIC_READ | GENERIC_WRITE, sa);
|
||||||
if (!hwst)
|
if (!hwst)
|
||||||
|
|
|
@ -3609,8 +3609,7 @@ seteuid32 (uid_t uid)
|
||||||
debug_printf ("Found token %p", new_token);
|
debug_printf ("Found token %p", new_token);
|
||||||
|
|
||||||
/* If no impersonation token is available, try to authenticate using
|
/* If no impersonation token is available, try to authenticate using
|
||||||
LSA private data stored password, LSA authentication using our own
|
LSA private data stored password, or, if that fails, S4U logon. */
|
||||||
LSA module, or, as last chance, NtCreateToken. */
|
|
||||||
if (new_token == NULL)
|
if (new_token == NULL)
|
||||||
{
|
{
|
||||||
if (!(new_token = lsaprivkeyauth (pw_new)))
|
if (!(new_token = lsaprivkeyauth (pw_new)))
|
||||||
|
@ -3622,25 +3621,11 @@ seteuid32 (uid_t uid)
|
||||||
debug_printf ("lsaprivkeyauth failed, try s4uauth.");
|
debug_printf ("lsaprivkeyauth failed, try s4uauth.");
|
||||||
extract_nt_dom_user (pw_new, domain, user);
|
extract_nt_dom_user (pw_new, domain, user);
|
||||||
if (!(new_token = s4uauth (true, domain, user, status)))
|
if (!(new_token = s4uauth (true, domain, user, status)))
|
||||||
{
|
|
||||||
if (status != STATUS_INVALID_PARAMETER)
|
|
||||||
{
|
{
|
||||||
debug_printf ("s4uauth failed, bail out");
|
debug_printf ("s4uauth failed, bail out");
|
||||||
cygheap->user.reimpersonate ();
|
cygheap->user.reimpersonate ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* If s4uauth fails with status code STATUS_INVALID_PARAMETER,
|
|
||||||
we're running on a system not implementing MsV1_0S4ULogon
|
|
||||||
(Windows 7 WOW64). Fall back to create_token in this single
|
|
||||||
case only. */
|
|
||||||
debug_printf ("s4uauth failed, try create_token.");
|
|
||||||
if (!(new_token = create_token (usersid, groups)))
|
|
||||||
{
|
|
||||||
debug_printf ("create_token failed, bail out");
|
|
||||||
cygheap->user.reimpersonate ();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep at most one internal token */
|
/* Keep at most one internal token */
|
||||||
|
|
Loading…
Reference in New Issue