Cygwin: seteuid: use Kerberos/MsV1_0 S4U authentication by default
- This simple and official method replaces cyglsa and "create token" methods. No network share access, same as before. - lsaauth and create_token are disabled now. If problems crop up, they can be easily reactivated. If no problems crop up, they can be removed in a while, together with the lsaauth subdir. - Bump Cygwin version to 3.0. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
84230b71c6
commit
0fb497165f
|
@ -647,6 +647,7 @@ LoadDLLfunc (LsaFreeReturnBuffer, 4, secur32)
|
|||
LoadDLLfunc (LsaLogonUser, 56, secur32)
|
||||
LoadDLLfunc (LsaLookupAuthenticationPackage, 12, secur32)
|
||||
LoadDLLfunc (LsaRegisterLogonProcess, 12, secur32)
|
||||
LoadDLLfunc (TranslateNameW, 20, secur32)
|
||||
|
||||
LoadDLLfunc (SHGetDesktopFolder, 4, shell32)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ details. */
|
|||
the Cygwin shared library". This version is used to track important
|
||||
changes to the DLL and is mainly informative in nature. */
|
||||
|
||||
#define CYGWIN_VERSION_DLL_MAJOR 2012
|
||||
#define CYGWIN_VERSION_DLL_MAJOR 3000
|
||||
#define CYGWIN_VERSION_DLL_MINOR 0
|
||||
|
||||
/* Major numbers before CYGWIN_VERSION_DLL_EPOCH are incompatible. */
|
||||
|
|
|
@ -58,6 +58,9 @@ What changed:
|
|||
|
||||
- Improve uname(2) for newly built applications.
|
||||
|
||||
- Kerberos/MSV1_0 S4U authentication replaces two old methods:
|
||||
Creating a token from scratch and Cygwin LSA authentication package.
|
||||
|
||||
|
||||
Bug Fixes
|
||||
---------
|
|
@ -24,6 +24,8 @@ details. */
|
|||
#include <iptypes.h>
|
||||
#include <wininet.h>
|
||||
#include <userenv.h>
|
||||
#define SECURITY_WIN32
|
||||
#include <secext.h>
|
||||
#include "cyglsa.h"
|
||||
#include "cygserver_setpwd.h"
|
||||
#include <cygwin/version.h>
|
||||
|
@ -872,6 +874,32 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
|
|||
|| groups.pgsid == usersid;
|
||||
}
|
||||
|
||||
const char *
|
||||
account_restriction (NTSTATUS status)
|
||||
{
|
||||
const char *type;
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_INVALID_LOGON_HOURS:
|
||||
type = "Logon outside allowed hours";
|
||||
break;
|
||||
case STATUS_INVALID_WORKSTATION:
|
||||
type = "Logon at this machine not allowed";
|
||||
break;
|
||||
case STATUS_PASSWORD_EXPIRED:
|
||||
type = "Password expired";
|
||||
break;
|
||||
case STATUS_ACCOUNT_DISABLED:
|
||||
type = "Account disabled";
|
||||
break;
|
||||
default:
|
||||
type = "Unknown";
|
||||
break;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
HANDLE
|
||||
create_token (cygsid &usersid, user_groups &new_groups)
|
||||
{
|
||||
|
@ -1229,7 +1257,11 @@ lsaauth (cygsid &usersid, user_groups &new_groups)
|
|||
&sub_status);
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
debug_printf ("LsaLogonUser: %y (sub-status %y)", status, sub_status);
|
||||
if (status == STATUS_ACCOUNT_RESTRICTION)
|
||||
debug_printf ("Cygwin LSA Auth LsaLogonUser failed: %y (%s)",
|
||||
status, account_restriction (sub_status));
|
||||
else
|
||||
debug_printf ("Cygwin LSA Auth LsaLogonUser failed: %y", status);
|
||||
__seterrno_from_nt_status (status);
|
||||
goto out;
|
||||
}
|
||||
|
@ -1338,3 +1370,234 @@ out:
|
|||
pop_self_privilege ();
|
||||
return token;
|
||||
}
|
||||
|
||||
/* The following code is inspired by the generate_s4u_user_token
|
||||
and lookup_principal_name functions from
|
||||
https://github.com/PowerShell/openssh-portable
|
||||
|
||||
Thanks guys! For courtesy here's the original copyright disclaimer: */
|
||||
|
||||
/*
|
||||
* Author: Manoj Ampalam <manoj.ampalam@microsoft.com>
|
||||
* Utilities to generate user tokens
|
||||
*
|
||||
* Author: Bryan Berns <berns@uwalumni.com>
|
||||
* Updated s4u, logon, and profile loading routines to use
|
||||
* normalized login names.
|
||||
*
|
||||
* Copyright (c) 2015 Microsoft Corp.
|
||||
* All rights reserved
|
||||
*
|
||||
* Microsoft openssh win32 port
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* In Mingw-w64, MsV1_0S4ULogon and MSV1_0_S4U_LOGON are only defined
|
||||
in ddk/ntifs.h. We can't inlcude this. */
|
||||
|
||||
#define MsV1_0S4ULogon ((MSV1_0_LOGON_SUBMIT_TYPE) 12)
|
||||
|
||||
typedef struct _MSV1_0_S4U_LOGON
|
||||
{
|
||||
MSV1_0_LOGON_SUBMIT_TYPE MessageType;
|
||||
ULONG Flags;
|
||||
UNICODE_STRING UserPrincipalName;
|
||||
UNICODE_STRING DomainName;
|
||||
} MSV1_0_S4U_LOGON, *PMSV1_0_S4U_LOGON;
|
||||
|
||||
HANDLE
|
||||
s4uauth (struct passwd *pw)
|
||||
{
|
||||
LSA_STRING name;
|
||||
HANDLE lsa_hdl = NULL;
|
||||
LSA_OPERATIONAL_MODE sec_mode;
|
||||
NTSTATUS status, sub_status;
|
||||
WCHAR domain[MAX_DOMAIN_NAME_LEN + 1];
|
||||
WCHAR user[UNLEN + 1];
|
||||
bool try_kerb_auth;
|
||||
ULONG package_id, size;
|
||||
struct {
|
||||
LSA_STRING str;
|
||||
CHAR buf[16];
|
||||
} origin;
|
||||
|
||||
tmp_pathbuf tp;
|
||||
PVOID authinf = NULL;
|
||||
ULONG authinf_size;
|
||||
TOKEN_SOURCE ts;
|
||||
PKERB_INTERACTIVE_PROFILE profile = NULL;
|
||||
LUID luid;
|
||||
QUOTA_LIMITS quota;
|
||||
HANDLE token = NULL;
|
||||
|
||||
push_self_privilege (SE_TCB_PRIVILEGE, true);
|
||||
|
||||
/* Register as logon process. */
|
||||
RtlInitAnsiString (&name, "Cygwin");
|
||||
status = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode);
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
debug_printf ("LsaRegisterLogonProcess: %y", status);
|
||||
__seterrno_from_nt_status (status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Fetch user and domain name and check if this is a domain user.
|
||||
If so, try Kerberos first. */
|
||||
extract_nt_dom_user (pw, domain, user);
|
||||
try_kerb_auth = cygheap->dom.member_machine ()
|
||||
&& wcscasecmp (domain, cygheap->dom.account_flat_name ());
|
||||
RtlInitAnsiString (&name, try_kerb_auth ? MICROSOFT_KERBEROS_NAME_A
|
||||
: MSV1_0_PACKAGE_NAME);
|
||||
status = LsaLookupAuthenticationPackage (lsa_hdl, &name, &package_id);
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
debug_printf ("LsaLookupAuthenticationPackage: %y", status);
|
||||
__seterrno_from_nt_status (status);
|
||||
goto out;
|
||||
}
|
||||
/* Create origin. */
|
||||
stpcpy (origin.buf, "Cygwin");
|
||||
RtlInitAnsiString (&origin.str, origin.buf);
|
||||
|
||||
if (try_kerb_auth)
|
||||
{
|
||||
PWCHAR sam_name = tp.w_get ();
|
||||
PWCHAR upn_name = tp.w_get ();
|
||||
size = NT_MAX_PATH;
|
||||
KERB_S4U_LOGON *s4u_logon;
|
||||
USHORT name_len;
|
||||
|
||||
wcpcpy (wcpcpy (wcpcpy (sam_name, domain), L"\\"), user);
|
||||
if (TranslateNameW (sam_name, NameSamCompatible, NameUserPrincipal,
|
||||
upn_name, &size) == 0)
|
||||
{
|
||||
PWCHAR translated_name = tp.w_get ();
|
||||
PWCHAR p;
|
||||
|
||||
debug_printf ("TranslateNameW(%W, NameUserPrincipal) %E", sam_name);
|
||||
size = NT_MAX_PATH;
|
||||
if (TranslateNameW (sam_name, NameSamCompatible, NameCanonical,
|
||||
translated_name, &size) == 0)
|
||||
{
|
||||
debug_printf ("TranslateNameW(%W, NameCanonical) %E", sam_name);
|
||||
debug_printf ("Fallback to MsV1_0 auth");
|
||||
goto msv1_0_auth; /* Fall through to MSV1_0 authentication */
|
||||
}
|
||||
p = wcschr (translated_name, L'/');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
wcpcpy (wcpcpy (wcpcpy (upn_name, user), L"@"), translated_name);
|
||||
}
|
||||
|
||||
name_len = wcslen (upn_name) * sizeof (WCHAR);
|
||||
authinf_size = sizeof (KERB_S4U_LOGON) + name_len;
|
||||
authinf = tp.c_get ();
|
||||
RtlSecureZeroMemory (authinf, authinf_size);
|
||||
s4u_logon = (KERB_S4U_LOGON *) authinf;
|
||||
s4u_logon->MessageType = KerbS4ULogon;
|
||||
s4u_logon->Flags = 0;
|
||||
/* Append user to login info */
|
||||
RtlInitEmptyUnicodeString (&s4u_logon->ClientUpn,
|
||||
(PWCHAR) (s4u_logon + 1),
|
||||
name_len);
|
||||
RtlAppendUnicodeToString (&s4u_logon->ClientUpn, upn_name);
|
||||
debug_printf ("ClientUpn: <%S>", &s4u_logon->ClientUpn);
|
||||
/* Create token source. */
|
||||
memcpy (ts.SourceName, "Cygwin.1", 8);
|
||||
ts.SourceIdentifier.HighPart = 0;
|
||||
ts.SourceIdentifier.LowPart = 0x0105;
|
||||
status = LsaLogonUser (lsa_hdl, (PLSA_STRING) &origin, Network,
|
||||
package_id, authinf, authinf_size, NULL,
|
||||
&ts, (PVOID *) &profile, &size,
|
||||
&luid, &token, "a, &sub_status);
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_SUCCESS:
|
||||
goto out;
|
||||
/* These failures are fatal */
|
||||
case STATUS_QUOTA_EXCEEDED:
|
||||
case STATUS_LOGON_FAILURE:
|
||||
debug_printf ("Kerberos S4U LsaLogonUser failed: %y", status);
|
||||
goto out;
|
||||
case STATUS_ACCOUNT_RESTRICTION:
|
||||
debug_printf ("Kerberos S4U LsaLogonUser failed: %y (%s)",
|
||||
status, account_restriction (sub_status));
|
||||
goto out;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
debug_printf ("Kerberos S4U LsaLogonUser failed: %y, try MsV1_0", status);
|
||||
/* Fall through to MSV1_0 authentication */
|
||||
}
|
||||
|
||||
msv1_0_auth:
|
||||
MSV1_0_S4U_LOGON *s4u_logon;
|
||||
USHORT user_len, domain_len;
|
||||
|
||||
user_len = wcslen (user) * sizeof (WCHAR);
|
||||
domain_len = wcslen (domain) * sizeof (WCHAR); /* Local machine */
|
||||
authinf_size = sizeof (MSV1_0_S4U_LOGON) + user_len + domain_len;
|
||||
if (!authinf)
|
||||
authinf = tp.c_get ();
|
||||
RtlSecureZeroMemory (authinf, authinf_size);
|
||||
s4u_logon = (MSV1_0_S4U_LOGON *) authinf;
|
||||
s4u_logon->MessageType = MsV1_0S4ULogon;
|
||||
s4u_logon->Flags = 0;
|
||||
/* Append user and domain to login info */
|
||||
RtlInitEmptyUnicodeString (&s4u_logon->UserPrincipalName,
|
||||
(PWCHAR) (s4u_logon + 1),
|
||||
user_len);
|
||||
RtlInitEmptyUnicodeString (&s4u_logon->DomainName,
|
||||
(PWCHAR) ((PBYTE) (s4u_logon + 1) + user_len),
|
||||
domain_len);
|
||||
RtlAppendUnicodeToString (&s4u_logon->UserPrincipalName, user);
|
||||
RtlAppendUnicodeToString (&s4u_logon->DomainName, domain);
|
||||
debug_printf ("DomainName: <%S> UserPrincipalName: <%S>",
|
||||
&s4u_logon->DomainName, &s4u_logon->UserPrincipalName);
|
||||
/* Create token source. */
|
||||
memcpy (ts.SourceName, "Cygwin.1", 8);
|
||||
ts.SourceIdentifier.HighPart = 0;
|
||||
ts.SourceIdentifier.LowPart = 0x0106;
|
||||
if ((status = LsaLogonUser (lsa_hdl, (PLSA_STRING) &origin, Network,
|
||||
package_id, authinf, authinf_size, NULL,
|
||||
&ts, (PVOID *) &profile, &size,
|
||||
&luid, &token, "a, &sub_status))
|
||||
!= STATUS_SUCCESS)
|
||||
{
|
||||
if (status == STATUS_ACCOUNT_RESTRICTION)
|
||||
debug_printf ("MSV1_0 S4U LsaLogonUser failed: %y (%s)",
|
||||
status, account_restriction (sub_status));
|
||||
else
|
||||
debug_printf ("MSV1_0 S4U LsaLogonUser failed: %y", status);
|
||||
}
|
||||
|
||||
out:
|
||||
if (lsa_hdl)
|
||||
LsaDeregisterLogonProcess (lsa_hdl);
|
||||
if (profile)
|
||||
LsaFreeReturnBuffer (profile);
|
||||
|
||||
pop_self_privilege ();
|
||||
return token;
|
||||
}
|
||||
|
|
|
@ -479,6 +479,8 @@ HANDLE create_token (cygsid &usersid, user_groups &groups);
|
|||
HANDLE lsaauth (cygsid &, user_groups &);
|
||||
/* LSA private key storage authentication, same as when using service logons. */
|
||||
HANDLE lsaprivkeyauth (struct passwd *pw);
|
||||
/* Kerberos or MsV1 S4U logon. */
|
||||
HANDLE s4uauth (struct passwd *pw);
|
||||
/* Verify an existing token */
|
||||
bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL);
|
||||
/* Get groups of a user */
|
||||
|
|
|
@ -3494,7 +3494,7 @@ seteuid32 (uid_t uid)
|
|||
order, the setgroups group list is still active when calling seteuid
|
||||
and verify_token treats the original token of the privileged user as
|
||||
insufficient. This in turn results in creating a new user token for
|
||||
the privileged user instead of using the orignal token. This can have
|
||||
the privileged user instead of using the original token. This can have
|
||||
unfortunate side effects. The created token has different group
|
||||
memberships, different user rights, and misses possible network
|
||||
credentials.
|
||||
|
@ -3542,10 +3542,22 @@ seteuid32 (uid_t uid)
|
|||
}
|
||||
if (!new_token)
|
||||
{
|
||||
#if 1
|
||||
debug_printf ("lsaprivkeyauth failed, try s4uauth.");
|
||||
if (!(new_token = s4uauth (pw_new)))
|
||||
{
|
||||
debug_printf ("s4uauth failed, bail out");
|
||||
cygheap->user.reimpersonate ();
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
debug_printf ("lsaprivkeyauth failed, try lsaauth.");
|
||||
if (!(new_token = lsaauth (usersid, groups)))
|
||||
{
|
||||
debug_printf ("lsaauth failed, try create_token.");
|
||||
debug_printf ("lsaauth failed, try s4uauth.");
|
||||
if (!(new_token = s4uauth (pw_new)))
|
||||
{
|
||||
debug_printf ("s4uauth failed, try create_token.");
|
||||
if (!(new_token = create_token (usersid, groups)))
|
||||
{
|
||||
debug_printf ("create_token failed, bail out");
|
||||
|
@ -3554,6 +3566,8 @@ seteuid32 (uid_t uid)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Keep at most one internal token */
|
||||
if (cygheap->user.internal_token != NO_IMPERSONATION)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<sect1 id="ov-new"><title>What's new and what changed in Cygwin</title>
|
||||
|
||||
<sect2 id="ov-new2.12"><title>What's new and what changed in 2.12</title>
|
||||
<sect2 id="ov-new3.0"><title>What's new and what changed in 3.0</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -86,15 +86,20 @@ to free the parent directory.
|
|||
Wctype functions updated to Unicode 11.0.
|
||||
</para></listitem>
|
||||
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Remove matherr, and SVID and X/Open math library configurations.
|
||||
Default math library configuration is now IEEE.
|
||||
<listitem><para>
|
||||
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Improve uname(2) for newly built applications.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Kerberos/MSV1_0 S4U authentication replaces two old methods:
|
||||
Creating a token from scratch and Cygwin LSA authentication package.
|
||||
</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
</sect2>
|
||||
|
|
|
@ -2326,35 +2326,56 @@ example:</para>
|
|||
|
||||
</sect3>
|
||||
|
||||
<sect3 id="ntsec-nopasswd1"><title id="ntsec-nopasswd1.title">Switching the user context without password, Method 1: Create a token from scratch</title>
|
||||
<sect3 id="ntsec-nopasswd1"><title id="ntsec-nopasswd1.title">Switching the user context without password, Method 1: Kerberos/MsV1_0 S4U authentication</title>
|
||||
|
||||
<para>An unfortunate aspect of the implementation of
|
||||
<command>set(e)uid</command> is the fact that the calling process
|
||||
requires the password of the user to which to switch. Applications such as
|
||||
requires the password of the user to switch to. Applications such as
|
||||
<command>sshd</command> wishing to switch the user context after a
|
||||
successful public key authentication, or the <command>cron</command>
|
||||
application which, again, wants to switch the user without any authentication
|
||||
are stuck here. But there are other ways to get new user tokens.</para>
|
||||
|
||||
<para>One way is just to create a user token from scratch. This is
|
||||
accomplished by using an (officially undocumented) function on the NT
|
||||
function level. The NT function level is used to implement the Win32
|
||||
level, and, as such is closer to the kernel than the Win32 level. The
|
||||
function of interest, <command>NtCreateToken</command>, allows you to
|
||||
specify user, groups, permissions and almost everything you need to
|
||||
create a user token, without the need to specify the user password. The
|
||||
only restriction for using this function is that the calling process
|
||||
needs the "Create a token object" user right, which only the SYSTEM user
|
||||
account has by default, and which is considered the most dangerous right
|
||||
a user can have on Windows systems.</para>
|
||||
<para>Starting with Cygwin 3.0, Cygwin tries to create a token by using
|
||||
<literal>Windows S4U authentication</literal> by default. For a quick
|
||||
description, see
|
||||
<ulink url="https://blogs.msdn.microsoft.com/winsdk/2015/08/28/logon-as-a-user-without-a-password/">this blog posting</ulink>. Cygwin versions prior
|
||||
to 3.0 tried to creat a user token from scratch using an officially
|
||||
undocumented function <command>NtCreateToken</command> which
|
||||
is now disabled.</para>
|
||||
|
||||
<para>That sounds good. We just start the servers which have to switch
|
||||
the user context (<command>sshd</command>, <command>inetd</command>,
|
||||
<command>cron</command>, ...) as Windows services under the SYSTEM
|
||||
(or LocalSystem in the GUI) account and everything just works.
|
||||
Unfortunately that's too simple. Using <command>NtCreateToken</command>
|
||||
has a few drawbacks.</para>
|
||||
<para>So we just start the servers which have to switch the user context
|
||||
(<command>sshd</command>, <command>inetd</command>, <command>cron</command>,
|
||||
...) as Windows services under the SYSTEM (or LocalSystem in the GUI)
|
||||
account and everything just works. Unfortunately that's too simple.
|
||||
Using <literal>S4U</literal> has a drawback.</para>
|
||||
|
||||
<para>Annoyingly, you don't have the usual comfortable access
|
||||
to network shares. The reason is that the token has been created
|
||||
without knowing the password. The password are your credentials
|
||||
necessary for network access. Thus, if you logon with a password, the
|
||||
password is stored hidden as "token credentials" within the access token
|
||||
and used as default logon to access network resources. Since these
|
||||
credentials are missing from the token created with <literal>S4U</literal>
|
||||
or <command>NtCreateToken</command>, you only can access network shares
|
||||
from the new user's process tree by using explicit authentication, on
|
||||
the command line for instance:</para>
|
||||
|
||||
<screen>
|
||||
bash$ net use '\\server\share' /user:DOMAIN\my_user my_users_password
|
||||
</screen>
|
||||
|
||||
<para>Note that, on some systems, you can't even define a drive letter
|
||||
to access the share, and under some circumstances the drive letter you
|
||||
choose collides with a drive letter already used in another session.
|
||||
Therefore it's better to get used to accessing these shares using the UNC
|
||||
path as in</para>
|
||||
|
||||
<screen>
|
||||
bash$ grep foo //server/share/foofile
|
||||
</screen>
|
||||
|
||||
<!--
|
||||
<para>First of all, the permission "Create a token object" gets explicitly
|
||||
removed from the SYSTEM user's access token, when starting services under that
|
||||
account. That requires us to create a new account with this specific
|
||||
|
@ -2388,31 +2409,6 @@ is more complicated. Some native, non-Cygwin Windows applications will
|
|||
misbehave badly in this situation. A well-known example are certain versions
|
||||
of Visual-C++.</para>
|
||||
|
||||
<para>Last but not least, you don't have the usual comfortable access
|
||||
to network shares. The reason is that the token has been created
|
||||
without knowing the password. The password are your credentials
|
||||
necessary for network access. Thus, if you logon with a password, the
|
||||
password is stored hidden as "token credentials" within the access token
|
||||
and used as default logon to access network resources. Since these
|
||||
credentials are missing from the token created with
|
||||
<command>NtCreateToken</command>, you only can access network shares
|
||||
from the new user's process tree by using explicit authentication, on
|
||||
the command line for instance:</para>
|
||||
|
||||
<screen>
|
||||
bash$ net use '\\server\share' /user:DOMAIN\my_user my_users_password
|
||||
</screen>
|
||||
|
||||
<para>Note that, on some systems, you can't even define a drive letter
|
||||
to access the share, and under some circumstances the drive letter you
|
||||
choose collides with a drive letter already used in another session.
|
||||
Therefore it's better to get used to accessing these shares using the UNC
|
||||
path as in</para>
|
||||
|
||||
<screen>
|
||||
bash$ grep foo //server/share/foofile
|
||||
</screen>
|
||||
|
||||
</sect3>
|
||||
|
||||
<sect3 id="ntsec-nopasswd2"><title id="ntsec-nopasswd2.title">Switching the user context without password, Method 2: LSA authentication package</title>
|
||||
|
@ -2439,9 +2435,6 @@ rebooting the system, the LSA authentication package is used by Cygwin
|
|||
when <command>set(e)uid</command> is called by an application. The
|
||||
created access token using this method has its own logon session.</para>
|
||||
|
||||
<para>This method has two advantages over the <command>NtCreateToken</command>
|
||||
method.</para>
|
||||
|
||||
<para>The very special and very dangerous "Create a token object" user
|
||||
right is not required by a user using this method. Other privileged
|
||||
user rights are still necessary, especially the "Act as part of the
|
||||
|
@ -2459,16 +2452,15 @@ inconvenience compared to that...</para>
|
|||
|
||||
<para>Nevertheless, this is already a lot better than what we get by
|
||||
using <command>NtCreateToken</command>, isn't it?</para>
|
||||
-->
|
||||
|
||||
</sect3>
|
||||
|
||||
<sect3 id="ntsec-nopasswd3"><title id="ntsec-nopasswd3.title">Switching the user context without password, Method 3: With password</title>
|
||||
<sect3 id="ntsec-nopasswd3"><title id="ntsec-nopasswd3.title">Switching the user context without password, Method 2: With password</title>
|
||||
|
||||
<para>Ok, so we have solved almost any problem, except for the network
|
||||
access problem. Not being able to access network shares without
|
||||
having to specify a cleartext password on the command line or in a
|
||||
script is a harsh problem for automated logons for testing purposes
|
||||
and similar stuff.</para>
|
||||
<para>Not being able to access network shares without having to specify
|
||||
a cleartext password on the command line or in a script is a harsh problem
|
||||
for automated logons for testing purposes and similar stuff.</para>
|
||||
|
||||
<para>Fortunately there is a solution, but it has its own drawbacks.
|
||||
But, first things first, how does it work? The title of this section
|
||||
|
@ -2512,13 +2504,7 @@ as normal, non-privileged user as well.</para>
|
|||
hidden, obfuscated registry area. Only SYSTEM has access to this area
|
||||
for listing purposes, so, even as an administrator, you can't examine
|
||||
this area with regedit. Right? No. Every administrator can start
|
||||
regedit as SYSTEM user:</para>
|
||||
|
||||
<screen>
|
||||
bash$ date
|
||||
Tue Dec 2 16:28:03 CET 2008
|
||||
bash$ at 16:29 /interactive regedit.exe
|
||||
</screen>
|
||||
regedit as SYSTEM user, the Internet is your friend here.</para>
|
||||
|
||||
<para>Additionally, if an administrator knows under which name
|
||||
the private key is stored (which is well-known since the algorithms
|
||||
|
@ -2539,12 +2525,12 @@ safely use this method.</para>
|
|||
|
||||
<sect3 id="ntsec-setuid-impl"><title id="ntsec-setuid-impl.title">Switching the user context, how does it all fit together?</title>
|
||||
|
||||
<para>Now we learned about four different ways to switch the user
|
||||
<para>Now we learned about three different ways to switch the user
|
||||
context using the <command>set(e)uid</command> system call, but
|
||||
how does <command>set(e)uid</command> really work? Which method does it
|
||||
use now?</para>
|
||||
|
||||
<para>The answer is, all four of them. So here's a brief overview
|
||||
<para>The answer is, all three of them. So here's a brief overview
|
||||
what <command>set(e)uid</command> does under the hood:</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
@ -2575,17 +2561,17 @@ private registry area, either under a Cygwin key, or under a SFU key.
|
|||
If so, use this to call <command>LogonUser</command>. If this
|
||||
succeeds, we use the resulting token for the user context switch.</para>
|
||||
</listitem>
|
||||
|
||||
<!--
|
||||
<listitem>
|
||||
<para>Otherwise, check if the Cygwin-specifc LSA authentication package
|
||||
has been installed and is functional. If so, use the appropriate LSA
|
||||
calls to communicate with the Cygwin LSA authentication package and
|
||||
use the returned token.</para>
|
||||
</listitem>
|
||||
|
||||
-->
|
||||
<listitem>
|
||||
<para>Last chance, try to use the <command>NtCreateToken</command> call
|
||||
to create a token. If that works, use this token.</para>
|
||||
<para>Otherwise, use the default <literal>S4U</literal> authentication
|
||||
to create a token.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
|
|
Loading…
Reference in New Issue