Cygwin: s4uauth: drop fallback to MsV1_0 if Kerberos fails
This never really worked. While at it, restructure code to do common stuff only in one spot. Improve debug output. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
379598dd67
commit
f18a161cff
|
@ -1509,7 +1509,7 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status)
|
||||||
HANDLE lsa_hdl = NULL;
|
HANDLE lsa_hdl = NULL;
|
||||||
LSA_OPERATIONAL_MODE sec_mode;
|
LSA_OPERATIONAL_MODE sec_mode;
|
||||||
NTSTATUS status, sub_status;
|
NTSTATUS status, sub_status;
|
||||||
bool try_kerb_auth;
|
bool kerberos_auth;
|
||||||
ULONG package_id, size;
|
ULONG package_id, size;
|
||||||
struct {
|
struct {
|
||||||
LSA_STRING str;
|
LSA_STRING str;
|
||||||
|
@ -1530,11 +1530,16 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status)
|
||||||
if (logon)
|
if (logon)
|
||||||
{
|
{
|
||||||
/* Register as logon process. */
|
/* Register as logon process. */
|
||||||
|
debug_printf ("Impersonation requested");
|
||||||
RtlInitAnsiString (&name, "Cygwin");
|
RtlInitAnsiString (&name, "Cygwin");
|
||||||
status = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode);
|
status = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
/* Connect untrusted to just create a identification token */
|
||||||
|
debug_printf ("Identification requested");
|
||||||
status = LsaConnectUntrusted (&lsa_hdl);
|
status = LsaConnectUntrusted (&lsa_hdl);
|
||||||
|
}
|
||||||
if (status != STATUS_SUCCESS)
|
if (status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
debug_printf ("%s: %y", logon ? "LsaRegisterLogonProcess"
|
debug_printf ("%s: %y", logon ? "LsaRegisterLogonProcess"
|
||||||
|
@ -1543,22 +1548,16 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if this is a domain user. If so, try Kerberos first. */
|
/* Check if this is a domain user. If so, use Kerberos. */
|
||||||
try_kerb_auth = cygheap->dom.member_machine ()
|
kerberos_auth = cygheap->dom.member_machine ()
|
||||||
&& wcscasecmp (domain, cygheap->dom.account_flat_name ());
|
&& wcscasecmp (domain, cygheap->dom.account_flat_name ());
|
||||||
/* Create origin. */
|
debug_printf ("kerb %d, domain member %d, user domain <%W>, machine <%W>",
|
||||||
stpcpy (origin.buf, "Cygwin");
|
kerberos_auth, cygheap->dom.member_machine (), domain,
|
||||||
RtlInitAnsiString (&origin.str, origin.buf);
|
cygheap->dom.account_flat_name ());
|
||||||
|
|
||||||
if (try_kerb_auth)
|
/* Connect to authentication package. */
|
||||||
{
|
RtlInitAnsiString (&name, kerberos_auth ? MICROSOFT_KERBEROS_NAME_A
|
||||||
PWCHAR sam_name = tp.w_get ();
|
: MSV1_0_PACKAGE_NAME);
|
||||||
PWCHAR upn_name = tp.w_get ();
|
|
||||||
size = NT_MAX_PATH;
|
|
||||||
KERB_S4U_LOGON *s4u_logon;
|
|
||||||
USHORT name_len;
|
|
||||||
|
|
||||||
RtlInitAnsiString (&name, MICROSOFT_KERBEROS_NAME_A);
|
|
||||||
status = LsaLookupAuthenticationPackage (lsa_hdl, &name, &package_id);
|
status = LsaLookupAuthenticationPackage (lsa_hdl, &name, &package_id);
|
||||||
if (status != STATUS_SUCCESS)
|
if (status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -1566,6 +1565,24 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status)
|
||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create origin. */
|
||||||
|
stpcpy (origin.buf, "Cygwin");
|
||||||
|
RtlInitAnsiString (&origin.str, origin.buf);
|
||||||
|
|
||||||
|
/* Create token source. */
|
||||||
|
memcpy (ts.SourceName, "Cygwin.1", 8);
|
||||||
|
ts.SourceIdentifier.HighPart = 0;
|
||||||
|
ts.SourceIdentifier.LowPart = kerberos_auth ? 0x0105 : 0x0106;
|
||||||
|
|
||||||
|
if (kerberos_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);
|
wcpcpy (wcpcpy (wcpcpy (sam_name, domain), L"\\"), user);
|
||||||
if (TranslateNameW (sam_name, NameSamCompatible, NameUserPrincipal,
|
if (TranslateNameW (sam_name, NameSamCompatible, NameUserPrincipal,
|
||||||
upn_name, &size) == 0)
|
upn_name, &size) == 0)
|
||||||
|
@ -1579,8 +1596,7 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status)
|
||||||
translated_name, &size) == 0)
|
translated_name, &size) == 0)
|
||||||
{
|
{
|
||||||
debug_printf ("TranslateNameW(%W, NameCanonical) %E", sam_name);
|
debug_printf ("TranslateNameW(%W, NameCanonical) %E", sam_name);
|
||||||
debug_printf ("Fallback to MsV1_0 auth");
|
goto out;
|
||||||
goto msv1_0_auth; /* Fall through to MSV1_0 authentication */
|
|
||||||
}
|
}
|
||||||
p = wcschr (translated_name, L'/');
|
p = wcschr (translated_name, L'/');
|
||||||
if (p)
|
if (p)
|
||||||
|
@ -1600,49 +1616,15 @@ s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status)
|
||||||
(PWCHAR) (s4u_logon + 1),
|
(PWCHAR) (s4u_logon + 1),
|
||||||
name_len);
|
name_len);
|
||||||
RtlAppendUnicodeToString (&s4u_logon->ClientUpn, upn_name);
|
RtlAppendUnicodeToString (&s4u_logon->ClientUpn, upn_name);
|
||||||
debug_printf ("ClientUpn: <%S>", &s4u_logon->ClientUpn);
|
debug_printf ("KerbS4ULogon: ClientUpn: <%S>", &s4u_logon->ClientUpn);
|
||||||
/* Create token source. */
|
}
|
||||||
memcpy (ts.SourceName, "Cygwin.1", 8);
|
else
|
||||||
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:
|
/* Per MSDN MsV1_0S4ULogon is not implemented on Vista, but surprisingly
|
||||||
goto out;
|
it works. */
|
||||||
/* 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;
|
MSV1_0_S4U_LOGON *s4u_logon;
|
||||||
USHORT user_len, domain_len;
|
USHORT user_len, domain_len;
|
||||||
|
|
||||||
/* Per MSDN MsV1_0S4ULogon is not implemented on Vista, but surprisingly
|
|
||||||
it works. */
|
|
||||||
RtlInitAnsiString (&name, 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;
|
|
||||||
}
|
|
||||||
user_len = wcslen (user) * sizeof (WCHAR);
|
user_len = wcslen (user) * sizeof (WCHAR);
|
||||||
domain_len = wcslen (domain) * sizeof (WCHAR); /* Local machine */
|
domain_len = wcslen (domain) * sizeof (WCHAR); /* Local machine */
|
||||||
authinf_size = sizeof (MSV1_0_S4U_LOGON) + user_len + domain_len;
|
authinf_size = sizeof (MSV1_0_S4U_LOGON) + user_len + domain_len;
|
||||||
|
@ -1661,23 +1643,27 @@ msv1_0_auth:
|
||||||
domain_len);
|
domain_len);
|
||||||
RtlAppendUnicodeToString (&s4u_logon->UserPrincipalName, user);
|
RtlAppendUnicodeToString (&s4u_logon->UserPrincipalName, user);
|
||||||
RtlAppendUnicodeToString (&s4u_logon->DomainName, domain);
|
RtlAppendUnicodeToString (&s4u_logon->DomainName, domain);
|
||||||
debug_printf ("DomainName: <%S> UserPrincipalName: <%S>",
|
debug_printf ("MsV1_0S4ULogon: DomainName: <%S> UserPrincipalName: <%S>",
|
||||||
&s4u_logon->DomainName, &s4u_logon->UserPrincipalName);
|
&s4u_logon->DomainName, &s4u_logon->UserPrincipalName);
|
||||||
/* Create token source. */
|
}
|
||||||
memcpy (ts.SourceName, "Cygwin.1", 8);
|
|
||||||
ts.SourceIdentifier.HighPart = 0;
|
/* Try to logon. */
|
||||||
ts.SourceIdentifier.LowPart = 0x0106;
|
status = LsaLogonUser (lsa_hdl, (PLSA_STRING) &origin, Network, package_id,
|
||||||
if ((status = LsaLogonUser (lsa_hdl, (PLSA_STRING) &origin, Network,
|
authinf, authinf_size, NULL, &ts, (PVOID *) &profile,
|
||||||
package_id, authinf, authinf_size, NULL,
|
&size, &luid, &token, "a, &sub_status);
|
||||||
&ts, (PVOID *) &profile, &size,
|
switch (status)
|
||||||
&luid, &token, "a, &sub_status))
|
|
||||||
!= STATUS_SUCCESS)
|
|
||||||
{
|
{
|
||||||
if (status == STATUS_ACCOUNT_RESTRICTION)
|
case STATUS_SUCCESS:
|
||||||
debug_printf ("MSV1_0 S4U LsaLogonUser failed: %y (%s)",
|
break;
|
||||||
status, account_restriction (sub_status));
|
case STATUS_ACCOUNT_RESTRICTION:
|
||||||
else
|
debug_printf ("%s S4U LsaLogonUser failed: %y (%s)",
|
||||||
debug_printf ("MSV1_0 S4U LsaLogonUser failed: %y", status);
|
kerberos_auth ? "Kerberos" : "MsV1_0", status,
|
||||||
|
account_restriction (sub_status));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
debug_printf ("%s S4U LsaLogonUser failed: %y",
|
||||||
|
kerberos_auth ? "Kerberos" : "MsV1_0", status);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
Loading…
Reference in New Issue