* sec_auth.cc (get_full_privileged_inheritable_token): New function
to fetch token with full privileges from logon token in Vista and later, and to make token inheritable. Add lengthy comments to explain the function's job. (cygwin_logon_user): Drop calling SetHandleInformation. Enable TCB privilege and call get_full_privileged_inheritable_token. (lsaauth): Don't fetch linked token and don't make handle inheritable here, just call get_full_privileged_inheritable_token instead. (lsaprivkeyauth): Ditto.
This commit is contained in:
parent
ff348d86cc
commit
b96600ef91
|
@ -1,3 +1,15 @@
|
||||||
|
2010-02-06 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* sec_auth.cc (get_full_privileged_inheritable_token): New function
|
||||||
|
to fetch token with full privileges from logon token in Vista and
|
||||||
|
later, and to make token inheritable. Add lengthy comments to explain
|
||||||
|
the function's job.
|
||||||
|
(cygwin_logon_user): Drop calling SetHandleInformation. Enable TCB
|
||||||
|
privilege and call get_full_privileged_inheritable_token.
|
||||||
|
(lsaauth): Don't fetch linked token and don't make handle inheritable
|
||||||
|
here, just call get_full_privileged_inheritable_token instead.
|
||||||
|
(lsaprivkeyauth): Ditto.
|
||||||
|
|
||||||
2010-02-05 Corinna Vinschen <corinna@vinschen.de>
|
2010-02-05 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* nlsfuncs.cc (__set_charset_from_locale): Set default locale for
|
* nlsfuncs.cc (__set_charset_from_locale): Set default locale for
|
||||||
|
|
|
@ -30,6 +30,58 @@ details. */
|
||||||
#include "cygserver_setpwd.h"
|
#include "cygserver_setpwd.h"
|
||||||
#include <cygwin/version.h>
|
#include <cygwin/version.h>
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
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. */
|
||||||
|
static HANDLE
|
||||||
|
get_full_privileged_inheritable_token (HANDLE token)
|
||||||
|
{
|
||||||
|
if (wincap.has_mandatory_integrity_control ())
|
||||||
|
{
|
||||||
|
TOKEN_LINKED_TOKEN linked;
|
||||||
|
DWORD size;
|
||||||
|
|
||||||
|
/* When fetching the linked token without TCB privs, then the linked
|
||||||
|
token is not a primary token, only an impersonation token, which is
|
||||||
|
not suitable for CreateProcessAsUser. Converting it to a primary
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
debug_printf ("Linked Token: %p", linked.LinkedToken);
|
||||||
|
if (linked.LinkedToken)
|
||||||
|
{
|
||||||
|
TOKEN_TYPE type;
|
||||||
|
|
||||||
|
/* 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 (token, TokenType, (PVOID) &type,
|
||||||
|
sizeof type, &size)
|
||||||
|
&& type != TokenPrimary)
|
||||||
|
debug_printf ("Linked Token is not a primary token!");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CloseHandle (token);
|
||||||
|
token = linked.LinkedToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!SetHandleInformation (token, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
|
||||||
|
{
|
||||||
|
__seterrno ();
|
||||||
|
CloseHandle (token);
|
||||||
|
token = NULL;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set_imp_token (HANDLE token, int type)
|
set_imp_token (HANDLE token, int type)
|
||||||
{
|
{
|
||||||
|
@ -104,12 +156,14 @@ cygwin_logon_user (const struct passwd *pw, const char *password)
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
hToken = INVALID_HANDLE_VALUE;
|
hToken = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
else if (!SetHandleInformation (hToken,
|
else
|
||||||
HANDLE_FLAG_INHERIT,
|
|
||||||
HANDLE_FLAG_INHERIT))
|
|
||||||
{
|
{
|
||||||
__seterrno ();
|
/* See the comment in get_full_privileged_inheritable_token for a
|
||||||
CloseHandle (hToken);
|
description why we enable TCB privileges here. */
|
||||||
|
push_self_privilege (SE_TCB_PRIVILEGE, true);
|
||||||
|
hToken = get_full_privileged_inheritable_token (hToken);
|
||||||
|
pop_self_privilege ();
|
||||||
|
if (!hToken)
|
||||||
hToken = INVALID_HANDLE_VALUE;
|
hToken = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
cygheap->user.reimpersonate ();
|
cygheap->user.reimpersonate ();
|
||||||
|
@ -1086,27 +1140,7 @@ lsaauth (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
|
||||||
#endif /* JUST_ANOTHER_NONWORKING_SOLUTION */
|
#endif /* JUST_ANOTHER_NONWORKING_SOLUTION */
|
||||||
LsaFreeReturnBuffer (profile);
|
LsaFreeReturnBuffer (profile);
|
||||||
}
|
}
|
||||||
|
user_token = get_full_privileged_inheritable_token (user_token);
|
||||||
if (wincap.has_mandatory_integrity_control ())
|
|
||||||
{
|
|
||||||
TOKEN_LINKED_TOKEN linked;
|
|
||||||
|
|
||||||
if (GetTokenInformation (user_token, TokenLinkedToken,
|
|
||||||
(PVOID) &linked, sizeof linked, &size))
|
|
||||||
{
|
|
||||||
debug_printf ("Linked Token: %p", linked.LinkedToken);
|
|
||||||
if (linked.LinkedToken)
|
|
||||||
{
|
|
||||||
CloseHandle (user_token);
|
|
||||||
user_token = linked.LinkedToken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The token returned by LsaLogonUser is not inheritable. Make it so. */
|
|
||||||
if (!SetHandleInformation (user_token, HANDLE_FLAG_INHERIT,
|
|
||||||
HANDLE_FLAG_INHERIT))
|
|
||||||
system_printf ("SetHandleInformation %E");
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (privs)
|
if (privs)
|
||||||
|
@ -1179,31 +1213,7 @@ lsaprivkeyauth (struct passwd *pw)
|
||||||
token = NULL;
|
token = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
token = get_full_privileged_inheritable_token (token);
|
||||||
if (wincap.has_mandatory_integrity_control ())
|
|
||||||
{
|
|
||||||
TOKEN_LINKED_TOKEN linked;
|
|
||||||
DWORD size;
|
|
||||||
|
|
||||||
if (GetTokenInformation (token, TokenLinkedToken,
|
|
||||||
(PVOID) &linked, sizeof linked, &size))
|
|
||||||
{
|
|
||||||
debug_printf ("Linked Token: %p", linked.LinkedToken);
|
|
||||||
if (linked.LinkedToken)
|
|
||||||
{
|
|
||||||
CloseHandle (token);
|
|
||||||
token = linked.LinkedToken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!SetHandleInformation (token, HANDLE_FLAG_INHERIT,
|
|
||||||
HANDLE_FLAG_INHERIT))
|
|
||||||
{
|
|
||||||
__seterrno ();
|
|
||||||
CloseHandle (token);
|
|
||||||
token = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
close_local_policy (lsa);
|
close_local_policy (lsa);
|
||||||
|
|
Loading…
Reference in New Issue