Subject: RE: Incompatibilities between Microsoft W2K3 and Kerberos 5

From: Tim Alsop <[email-masked]>
Date: Thu, 11 Mar 2004 18:57:42 -0000

Martin,

I think this problem only occurs if the Win2k workstation is used and DES keys are used. If you change the account to support the default cipher (e.g. RC4) the problem does not occur.

Please see attached matrix showing the outcome of my tests with Win2k KDC and Win2k or XP workstations. 

Admitedly I haven't yet completed the same tests with Win2k3 KDC, so it is possible that something else is broken as you suggest. Do the results in my attached spreadsheet match your findings ?

Thanks, Tim. 

-----Original Message-----
From: Martin Rex [mailto:[email-masked]] 
Sent: 11 March 2004 18:37
To: [email-masked]
Subject: Incompatibilities between Microsoft W2K3 and Kerberos 5

Did anyone else notice changes that went into Microsoft W2K3 Kerberos that are breaking Kerberos interoperability?

After Tim Alsop's message on the ietf-krb-wg mailing list and several custumer problem messages in the past couple of days with Windows 2003 machines I checked what is actually going on.

The results appear devastating:

A Windows 2003 KDC will perform a case-insensitive match of the requested kerberos principal name against the account database and issue tickets in exactly the case-format that was in the request.

The Winlogon of Windows 2003 will not canonicalize the username that was entered in the logon screen either.

This is an extremely severe interoperability problem, since Kerberos principal names are CASE-SENSITIVE and have always been.  This is required by both, the Kerberos specs and rfc1964.

So if "joeuser" logs on as "JoeUser" today he will authenticate to servers with the kerberos principal name "JoeUser", and if he logs on with "Joeuser" tomorrow, he will authenticate to servers with the Kerberos principal name "Joeuser".  That is going to break all Kerberos-based applications.

Right now, I can only issue a strong warning to our customers to
**NOT** use or upgrade to W2K3 if they want to use Kerberos-based Single Sign-On with our application, but to remain on Windows 2000 (I haven't checked XP, but this particular problem appears to be a bug of the W2K3 KDCs).

Did I miss the discussion on how case-independent account-naming could be done in Kerberos?  Certainly it must NOT be done using arbitrary-cased kerberos principal names in tickets, breaking all the installed base of kerberized or gssapi based apps.

-Martin

---

From: Martin Rex <[email-masked]>
Date: Thu, 11 Mar 2004 20:52:45 +0100 (MET)

Tim,

Tim Alsop wrote:
> 
> I think this problem only occurs if the Win2k workstation is used
> and DES keys are used. If you change the account to support the
> default cipher (e.g. RC4) the problem does not occur.

Well, I just created a fresh account "KerbTest" in a W2k->W2K3 upgraded domain
in W2K mixed mode and the account has the "DES keys" in the account
properties greyed out.

Now I log on to a W2K3 IA64-server (using TerminalServer) typing
the username "kerbtest" into the logon screen.  From the CMD command
shell I start my sspit2k test program (which is an extended version of
KB-Article 180548 "Validate User Credentials on Microsoft Operating Systems"
  
  Y:\>debug\sspit2k
  AcquireCredentialsHandle(pszPrincipal="", pAuthIdentity=00000000)
  QueryCredentialsAttribute(NAMES) returns "NT5\KerbTest"
  Name from Server Credentials "NT5\KerbTest"
  Client authenticated to Server with Name "NT5\KerbTest".
    ( NATIVE_NAMES attribute not available -- not using Kerberos!)
  
  *** User Credentials are valid ***
  
  Y:\>debug\sspit2k -p Kerberos
  AcquireCredentialsHandle(pszPrincipal="", pAuthIdentity=00000000)
  QueryCredentialsAttribute(NAMES) returns "[email-masked]"
  Name from Server Credentials "[email-masked]"
  Client authenticated to Server with Name "NT5\KerbTest".
  Client authenticated to Server with native Name "[email-masked]".
  
  *** User Credentials are valid ***
  
Then I log off and relogon, typing the user name "KerbTest" into the
logon screen this time:
  
  Y:\>debug\sspit2k
  AcquireCredentialsHandle(pszPrincipal="", pAuthIdentity=00000000)
  QueryCredentialsAttribute(NAMES) returns "NT5\KerbTest"
  Name from Server Credentials "NT5\KerbTest"
  Client authenticated to Server with Name "NT5\KerbTest".
    ( NATIVE_NAMES attribute not available -- not using Kerberos!)
  
  *** User Credentials are valid ***
  
  Y:\>debug\sspit2k -p Kerberos
  AcquireCredentialsHandle(pszPrincipal="", pAuthIdentity=00000000)
  QueryCredentialsAttribute(NAMES) returns "[email-masked]"
  Name from Server Credentials "[email-masked]"
  Client authenticated to Server with Name "NT5\KerbTest".
  Client authenticated to Server with native Name "[email-masked]".
  
  *** User Credentials are valid ***

Repeating the same in a domain with W2K domain controllers on a W2K terminal
server (account name = "d019080", entered "D019080" at logon screen)
I get the correct result (at least from the authentication):
  
  Y:\>debug\sspit2k
  AcquireCredentialsHandle(pszPrincipal="", pAuthIdentity=00000000)
  QueryCredentialsAttribute(NAMES) returns "SAP_ALL\d019080"
  Name from Server Credentials "SAP_ALL\d019080"
  Client authenticated to Server with Name "SAP_ALL\d019080".
    ( NATIVE_NAMES attribute not available -- not using Kerberos!)
  
  *** User Credentials are valid ***
  
  Y:\>debug\sspit2k -p Kerberos
  AcquireCredentialsHandle(pszPrincipal="", pAuthIdentity=00000000)
  QueryCredentialsAttribute(NAMES) returns "[email-masked]"
  Name from Server Credentials "[email-masked]"
  Client authenticated to Server with Name "SAP_ALL\d019080".
  Client authenticated to Server with native Name "[email-masked]".
  
  *** User Credentials are valid ***

Mixed scenarios: user "d019080" from W2K-domain with W2K DCs on
a machine from Domain NT5 (using W2K3 DCs in W2k mixed mode and external
non-transitive trust to the domain of d019080):
  
  Y:\>debug\sspit2k
  AcquireCredentialsHandle(pszPrincipal="", pAuthIdentity=00000000)
  QueryCredentialsAttribute(NAMES) returns "SAP_ALL\d019080"
  Name from Server Credentials "SAP_ALL\d019080"
  Client authenticated to Server with Name "SAP_ALL\d019080".
    ( NATIVE_NAMES attribute not available -- not using Kerberos!)
  
  *** User Credentials are valid ***
  
  Y:\>debug\sspit2k -p Kerberos
  AcquireCredentialsHandle(pszPrincipal="", pAuthIdentity=00000000)
  QueryCredentialsAttribute(NAMES) returns "[email-masked]"
  Name from Server Credentials "[email-masked]"
  Client authenticated to Server with Name "SAP.CORP\d019080".
  Client authenticated to Server with native Name "[email-masked]".
  
  *** User Credentials are valid ***

trying to use "d019080" on a W2K3 member server of NT5 results
in a Kerberos SSPI error (still an unresolved mystery bug of W2K3
-- a tool provided by Microsoft support shows that the bug is already
visible on W2K member servers in Domain NT5 at the LSA level, however
it doesn't cause Kerberos SSP authentication failures on W2K...):
  
  Y:\>debug\sspit2k
  AcquireCredentialsHandle(pszPrincipal="", pAuthIdentity=00000000)
  QueryCredentialsAttribute(NAMES) returns "SAP_ALL\d019080"
  Name from Server Credentials "SAP_ALL\d019080"
  Client authenticated to Server with Name "SAP_ALL\d019080".
    ( NATIVE_NAMES attribute not available -- not using Kerberos!)
  
  *** User Credentials are valid ***
  
  Y:\>debug\sspit2k -p Kerberos
  AcquireCredentialsHandle(pszPrincipal="", pAuthIdentity=00000000)
  QueryCredentialsAttribute(NAMES) returns "[email-masked]"
  Name from Server Credentials "[email-masked]"
  AcceptSecurityContext failed with 80090306
  
  !!! FAILED to verify User Credentials !!!
  
Windows 2003 seems be a little on the green side...

-Martin

---

From: Sam Hartman <[email-masked]>
Date: Thu, 11 Mar 2004 17:25:26 -0500

From a Kerberos spec standpoint, Microsoft can return whatever name
they want in the AS reply provided that the name in the reply is the
same as the name in the request.

This may not be what GSSAPI wants, but it is how RFC 1510 and
clarifications work.  If you want a specific citation I'll be happy to
give one for why the KDC cannot change the requested name.

If the client enables name canonicalization, which is currently not
part of IETF Kerberos, then the KDC may have more options.

Hope this helps,

--Sam

---

From: Martin Rex <[email-masked]>
Date: Fri, 12 Mar 2004 00:55:45 +0100 (MET)

Pleaaase.

I refered to Microsoft flawed implementation of account name to
Kerberos principal name mapping.

> same as the name in the request.

I understand quite well what they're doing,
Just that they seem to be creating hundreds of virtual distinct
Kerberos Principals for a single entry in the KDC database that way.

i.e. a user account create as JoeUser will receive tickets
for   [email-masked]
      [email-masked]

   all in all 128 distinct Kerberos principals.
And that is the result of how a user enters his case-insensitive
NT-account name on the logon screen.

For gss-api based or traditional kerberized apps these are
128 distinct users.  I see this as a severe usability problem.

> give one for why the KDC cannot change the requested name.

Again and again and again.

With GSS-API it is perfectly fine that the name that was passed
to gss_import_name() is internally mapped to something else.

MIT Kerberos on the other had would barf if the name in the ticket
would not match *EXACLTY* the name in the ticket request.

A problem with GSS-API arises only when this name transformation
is *NOT* also performed inside gss_compare_name() and somewhere
between gss_import_name()+gss_canonicalize_name()+gss_export_name()

> part of IETF Kerberos, then the KDC may have more options.

Requiring a new request type for the KDC for making the name-translation
available for clients outside of Ticket exchanges (it still leaves the
situation somewhat dangling where someone wants to maintain an ACL
but doesn't have a TGT...  A situation that e.g. Microsoft tries to
prevent by caching the logon password in the LSA ...

-Martin

---

From: Sam Hartman <[email-masked]>
Date: Thu, 11 Mar 2004 19:04:21 -0500

>>>>> "Martin" == Martin Rex <[email-masked]> writes:

[Reordering things a bit]

    Martin> account name to Kerberos principal name mapping.

    Martin> Sam Hartman wrote:
    >>  From a Kerberos spec standpoint, Microsoft can return whatever
    >> name they want in the AS reply provided that the name in the
    >> reply is the same as the name in the request.

    >> clarifications work.  If you want a specific citation I'll be
    >> happy to give one for why the KDC cannot change the requested
    >> name.

    Martin> Again and again and again.

    Martin> With GSS-API it is perfectly fine that the name that was
    Martin> passed to gss_import_name() is internally mapped to
    Martin> something else.

Understood.  But for Kerberos it is not OK if the KDC changes the name
in the AS Reply to be different than what was presented in the AS
Request.

I.E.  the client may perform cannonicalization, possibly by consulting
some external directory.  But in the IETF Kerberos world, the KDC must
either return what the client requested or return an error.

    Martin> I understand quite well what they're doing, Just that they
    Martin> seem to be creating hundreds of virtual distinct Kerberos
    Martin> Principals for a single entry in the KDC database that
    Martin> way.

    Martin> i.e. a user account create as JoeUser will receive tickets
    Martin> for [email-masked] [email-masked]

    Martin>    all in all 128 distinct Kerberos principals.  And that
    Martin> is the result of how a user enters his case-insensitive
    Martin> NT-account name on the logon screen.

    Martin> For gss-api based or traditional kerberized apps these are
    Martin> 128 distinct users.  I see this as a severe usability
    Martin> problem.

What would you have them do instead?

The options I see are to return an error if the user does not type in
the correct name.  That also sounds like a usability problem.

The other option is to have the KDC return a different principal than
is requested.  That's a violation of the current Kerberos
specification.  That would be an interoperability problem.

--Sam

---

From: Martin Rex <[email-masked]>
Date: Fri, 12 Mar 2004 01:20:39 +0100 (MET)

> in the AS Reply to be different than what was presented in the AS

I know, I mentioned that.

> either return what the client requested or return an error.

Great--that's what I've been asking for all along!

DCE is Kerberos-based, it has a directory service for translating
names (e.g. service names of a distributed service into a host-specific
service principal along with network address of that service instance).

A seperate name translation API to perform the name translation on
the client side.  Microsoft's added "TranslateName()" to SSPI in W2K,
and it contains all the necessary function parameters.  It works
for NameUserPrincipal->NameSamCompatible however it fails miserably
on NameSamCompatible->NameUserPrincipal
and NameUserPrincipal->NameUserPrincipal.

> What would you have them do instead?

Canonicalize the NT account name which the user typed in locally and use
that to request tickets from the KDC.  That seems to work well on W2K,
so I really don't understand why they broke it in W2K3.

Look at the Email that I sent to the krb list with the outputs of sspit2k
-- they do have the canonical account name right there in the NTLM SSP, and
NTLM SSP and Kerberos SSP both use the LSA to talk to the Domain or
ActiveDirectory to do lookup/translations, so the information about
a users canonical name should be readily available in a local LSA cache.

-Martin

---

From: Sam Hartman <[email-masked]>
Date: Thu, 11 Mar 2004 19:31:00 -0500

>>  I.E.  the client may perform cannonicalization, possibly by
    >> consulting some external directory.  But in the IETF Kerberos
    >> world, the KDC must either return what the client requested or
    >> return an error.

    Martin> Great--that's what I've been asking for all along!
I may be getting this a bit wrong so I'd appreciate it if Microsoft
people would join in.

They don't want to make the mapping from what the user types in to the
canonical name public.  IN particular, they want to require that the
user authenticate before they get access to this mapping.

They also don't want the host to be authorized to do this mapping without user credentials.

Their model doesn't allow them to ACL things this way in the
directory.

    Martin> all in all 128 distinct Kerberos principals.  And that is
    Martin> the result of how a user enters his case-insensitive
    Martin> NT-account name on the logon screen.
    >>  What would you have them do instead?

    Martin> Canonicalize the NT account name which the user typed in
    Martin> locally and use that to request tickets from the KDC.
    Martin> That seems to work well on W2K, so I really don't
    Martin> understand why they broke it in W2K3.

If it can be made to work I agree it would be an improvement.

---

From: Martin Rex <[email-masked]>
Date: Fri, 12 Mar 2004 02:05:15 +0100 (MET)

> user authenticate before they get access to this mapping.

Huh?  public?  They only need to acquire a ticket with the canonical name
instead of the arbitrary case user input--I really don't care when they
do this without telling me unless the authentication succeeds.

> mapping without user credentials.

Double-plus-huh?

For domain authentications to work with a Windows NT workstation
the workstation must already be a member of that domain (or another,
trusted domain).  In that case the machine has a machine account
which is already used for a lot of other domain-related communication
like verifying authenticity of NTLM challenge-response pairs and
transfering SAM information for account information caching.

> Their model doesn't allow them to ACL things this way in the

I lost you completely.  What does this have to do with ACLs in
the directory?

A Workstation that offer NT domain logons already has a workstation
account in a domain that provides a secure channel, even when no user
is currently logged on to the machine.

And if there is really something badly broken, then they should lookup
the canonical name using the non-canonical issued TGT, check whether
the name is already canonical and if not request another TGT with the
correct canonical name replacing the initial one in order to provide
interoperability the applications that are then launched afterwards.

-Martin

---

From: Sam Hartman <[email-masked]>
Date: Thu, 11 Mar 2004 20:32:41 -0500

Martin> Sam Hartman wrote:
    >>  They don't want to make the mapping from what the user types
    >> in to the canonical name public.  IN particular, they want to
    >> require that the user authenticate before they get access to
    >> this mapping.

    Martin> Huh?  public?  They only need to acquire a ticket with the
    Martin> canonical name instead of the arbitrary case user input--I
    Martin> really don't care when they do this without telling me
    Martin> unless the authentication succeeds.

They do not want to make that information in the directory public.

so, the issue is that you type in fOo to your workstation.  The
principal is actually foo.

Somehow, your workstation needs to look up that mapping and get you
credentials.

Microsoft wants to design the set of protocols between the client and
domain controller such that you cannot find out that mapping without
also proving that you are actually foo.

So in cases where they do not use name canonicalization, they cannot
perform this mapping.  (By name canonicalization I mean the Kerberos
extension, not some arbitrary directory-based mapping like DCE).

The DCE model required that anyone be able to look up the mapping in
the directory between principal and account.

---

From: Luke Howard <[email-masked]>
Date: Fri, 12 Mar 2004 12:45:41 +1100

>in the AS Reply to be different than what was presented in the AS

But that is exactly the behaviour that the referrals draft describes,
and the Windows clients depend on. When the name canonicalize bit is
set in an AS-REQ, the name in the response can be different and it IS
different.

If you do a UPN logon (user@domain), then the AS-REQ contains:

	Client Name: [email-masked]
		Type: Enterprise Principal
		Name: [email-masked]
	Realm: DSG.PADL.COM

where Realm is the workstation's default realm (I believe MS would
like to omit this in a future version). There is no requirement that
the realm be the same as the RHS of the enterprise principal name,
or indeed that the RHS be a Kerberos realm.

If you do not do a UPN-style logon (by not entering an @ symbol in
the logon dialog), then the AS-REQ contains:

	Client Name: lukeh
		Type: Principal
		Name: lukeh
	Realm: PADL-DSG

where the realm is the NetBIOS domain selected from the object picker.

In either case the name returned in the AS-REQ is the canonical name,
which is the client's SamAccountName. The realm is the canonical realm
of the domain in which the account exists.

In the following example directory entry:

	dn: CN=Martin Rex,CN=Users,DC=sap,DC=com
	objectClass: user
	sAMAccountName: martin
	userPrincipalName: [email-masked]

Martin can login as [email-masked] or martin, and the canonical
principal name returned in the AS-REP will be [email-masked].

As was recently pointed out in this mailing list, the returned client
name is not protected and so Windows actually extracts the canonical
client name from the authorization data.

In any case, the real question is: why does the LSA appear to store
the name that you entered at logon rather than the canonical name?

-- Luke

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 11 Mar 2004 19:42:04 -0600

> principal is actually foo.

I feel some sympathy for Martin here -- just what is wrong with users
having to know the proper capitalization of their names?  :)

> Somehow, your workstation needs to look up that mapping and get you

Technically, once they have the TGT they could do the lookup and then
get another TGT with the right capitalization.

> also proving that you are actually foo.

See above.

Nico
--

---

From: Martin Rex <[email-masked]>
Date: Fri, 12 Mar 2004 03:31:57 +0100 (MET)

> set in an AS-REQ, the name in the response can be different and it IS

As long as the KDC can reliably distinguish requests of "traditional"
clients from requests of clients that can handle, and as long as
"traditional" KDCs will not get confused by that bit if it is set
in an AS-REQ, then it should be possible to update the protocol
in a fully backward compatible fashion if that new feature is deemed
useful.

There are "soft" protocol violations that although not conform with
the current spec do it in a fashion that doesn't break anything and
are therefore one possible approach to enhance a spec with new features.

"Hard" protocol violations will cause severe interoperability problems
and break code or programs.

If you ask me whether a "soft" protocol violation should be permissible
to address/solve a severe usability problem, then such an proposal is
definitely worth a closer look and discussion.

-Martin

---

From: "Douglas E. Engert" <[email-masked]>
Date: Fri, 12 Mar 2004 11:12:09 -0600

Are you sure you are not seeing problems with Kerbtray? Have you loked a the
actual AS_REQ, AS_REP, TGS_REQ and TGS_REP?  I have seen problems with
the routines used by kerbtray. 

In PKERB_RETRIEVE_TKT_RESPONSE  they talk about "ServiceName", TargetName" and "ClientName"
and these are translated to unicode. It is also not clear if ClientName came from the
ticket although it says it did. 

> So if "joeuser" logs on as "JoeUser" today he will authenticate to servers with the kerberos principal name "JoeUser", and if he logs on with "Joeuser" tomorrow, he will authenticate to servers with the Kerberos principal name "Joeuser".  That is going
> to break all Kerberos-based applications.
> 
>                               Name: AD and SAP Tests v2.xls
>    AD and SAP Tests v2.xls    Type: Microsoft Excel Worksheet (application/vnd.ms-excel)
>                           Encoding: base64

-- 

 Douglas E. Engert  <[email-masked]>
 Argonne National Laboratory
 9700 South Cass Avenue
 Argonne, Illinois  60439 
 (630) 252-5444