Re: krb_match_realm - Mailing list pgsql-patches

From Henry B. Hotz
Subject Re: krb_match_realm
Date
Msg-id F615387E-FEC1-40C2-8219-276F1AF5D61E@jpl.nasa.gov
Whole thread Raw
In response to Re: krb_match_realm  (Magnus Hagander <magnus@hagander.net>)
Responses Re: krb_match_realm  (Magnus Hagander <magnus@hagander.net>)
List pgsql-patches
On Nov 6, 2007, at 6:27 AM, Magnus Hagander wrote:

> On Fri, Nov 02, 2007 at 11:23:30AM -0700, Henry B. Hotz wrote:
>>>>>> I'm not entirely sure what the intended semantics of
>>>>>> krb_match_realm
>>>>>> are, but if you're trying to match the GSSAPI-authenticated name
>>>>>> against
>>>>>> "value_of(PGUSER)@value_of(krb_match_realm)" then you need to
>>>>>> construct
>>>>>> that string, gss_import_name() it, and then gss_compare_name()
>>>>>> the
>>>>>> imported name with the authenticated name that GSSAPI already
>>>>>> gave you.
>>>>>> I know the API overhead of doing that is a PITA, but that's
>>>>>> what's going
>>>>>> to work.
>>>>>
>>>>> Why?
>>>>
>>>> Because if we're using the GSSAPI then we need to use the
>>>> properties
>>>> defined by the GSSAPI, and not depend on observed behavior of
>>>> specific
>>>> implementations of specific mechanisms.  Otherwise things will be
>>>> non-portable or unreliable in ways that may be non-obvious.
>>>>
>>>> In particular gss_display_name() produces a character string
>>>> intended
>>>> for display to a human being.  It is *NOT* intended for access
>>>> control.
>>>> As another example, Heimdal gss_display_name() puts '\' escapes in
>>>> front
>>>> of special characters in the username.  I don't think it's worth
>>>> writing
>>>> special case code for that either.
>>>
>>> Ok. I can see that point. However, if you have those characters in
>>> your
>>> username, you may have other problems as well :-)
>>
>> Yeah.  Not many people put spaces inside usernames.
>
> I think we can easily get away with not covering that case.

*sigh*  Yeah, maybe we have to live with it.

>>> Is there some other way to actually get the username from gss? I
>>> mean,
>>> if we *didn't* get it from the startup packet, how would we ever be
>>> able
>>> to determine what user logged in?
>>
>> gss_export_name(), but what it returns is supposed to be an opaque
>> binary blob.
>>
>> It's guaranteed to produce a unique, canonicalized name based on the
>> specific mechanism in use.  It is suitable for memcmp().  The
>> exported name will re-import.  Section 3.10 of rfc 2744 describes all
>> this, and appears to be clearer than the Sun document I pointed you
>> at.  Certainly it's more concise.  YMMV.
>
> Hmm. But it doesn't serve our purpose.

Well, it *might* work to do a memcmp() of tolower() of the blobs.

>> memcmp() on exported names will only be true if everyone uses the
>> same gss mechanism.  (OK, the only one we care about is kerberos.)
>> In contrast it's possible that gss_compare_name() would say that
>> "uid=smith,ou=People,dc=example,dc=com" is the same as
>> smith@EXAMPLE.COM.
>
> No, memcmp()ing two separate strings (userid + match realm) with an
> opaque
> binary blob certainly won't help us at all.
>
>
>>>> The standard defines two ways to do comparisons for access
>>>> control.  We
>>>> should use one of them.  Anything else is going to be more work
>>>> and less
>>>> reliable.
>>>
>>> What's the other way then?
>>>
>>> Last I checked there was no way to do case insensitive matching on
>>> gss_compare_name() but I could be on the wrong docs? Finding any
>>> kind of
>>> consistent docs for this stuff isn't exactly easy.
>>> Because we *must* have the ability to do case insensitive
>>> matching, or
>>> it *will* break on Windows.
>>
>> No gss_compare_name() is case sensitive.  I think the way to do it is
>> to know what case Microsoft is going to use and pre-map everything to
>> that case (before you do a gss_import_name()).  I *think* Microsoft
>> will use upper case for the service name so we will need to change
>> from "postgres" to "POSTGRES" as the default name in service
>> principals.  I've seen places where they may be using lower case
>> realm names (which makes *NO* sense to me).
>
> No. Microsoft will send you whatever case the user put into the
> login box
> when he logged into windows. It's case-*preserving*, but case-
> insensitive.

That can't be entirely true.  Maybe it's true for Microsoft's RC4
enctype, but it can't be true for the des-cbc-md5 enctype.  The
protocol runs with some case, and the question is what case it uses
when it matters.

> However, AD itself requires uppercase service name, but that's a
> different
> thing.

OK.

>> Absent an environment where I can actually look at all these things,
>> my only point of reference is mod_auth_kerb, and the issues reported
>> with it.  I know an upper case "HTTP" is needed to interoperate with
>> windows clients.  An upper case realm name seems to be OK, as is a
>> lower case server name in the second component.  The actual usernames
>> seem to be lower case, but that's not the concern of the
>> mod_auth_kerb developers since the deployer just needs to put in
>> whatever matches.
>
> The usernames depend on what the client puts in. It's generally a big
> problem because a lot of krb-aware applications can't deal with it.

I'd bet that the authenticated username in the service ticket is
always a specific case.  I'd also bet that it's whatever case the
username was created with, e.g. "Smith".  Without being able to
inspect packets myself I'm only guessing though.

>> I assume in AD you can't create both "smith" and "Smith", but can you
>> create the latter at all?  If you do, does AD remember the case for
>> display purposes?  Here at JPL usernames are lower case, and I don't
>> think we allow anything special but hyphens in them, so I'm not
>> likely to see a lot of the possible corner cases.
>
> You can and it remembers. But it has no effect on what is sent ni the
> kerberos packets - what's sent there is what the user typed in.
> Yes, that
> sucks bad, but that's how it is.

Hmmm.  See above.  It isn't possible to make it irrelevant
everywhere, unless you only use RC4.  Vista uses AES so it looses
that loophole though.

Expanding a bit:  I can believe that the client uses the entered case
in the AS_REQ.  It's even possible that the DC follows suit for parts
of the AS_REP.  However I doubt that a non-Windows Kerberos client
can do even that initial exchange unless the case of the username
matches properly because the username is part of the salt used to
convert passwords to keys.

For a non-windows client I think you can assume the case will always
match.

The question is what does the DC put in the service ticket as the
authenticated username.  (A secondary question is if it's different
if the original authentication was to a non-Windows Kerberos
server.)  I would bet that it puts the originally defined case in the
service ticket (at least in the secondary case).

I wonder if case conversion is the right way to create compatibility
with GSSAPI though.  If the user always comes in with a specific case
then shouldn't we instead find a way to make sure the PG user is
created with the corresponding case?  There are several ways you can
test for the existence of a user in a Kerberos service, for example
kinit with a garbage password will give different errors.

If you think a hook in the add user code is in scope I can
investigate if there is a way to verify the existence of a username
with the GSSAPI instead of the Kerberos API.

It would be really easy to inspect what happens with tcpdump/snoop
and Ethereal, but that's the only way I can see to really answer
these questions.

>> I think you can upper case the service name, lower case the server
>> name, upper case the realm name, and lower case the user name.  If
>> you can create "Smith" in AD and the user gets authenticated as
>> "Smith@EXAMPLE.COM" at the protocol level then that won't work
>> though.
>
> Which is how it is :-(

I can only

> From what I can tell, the least bad way to do it is still the patch
> that
> sits in the queue now (pending changes based on Stephens comments, but
> those are a differnt thing)
>
> //Magnus

------------------------------------------------------------------------
The opinions expressed in this message are mine,
not those of Caltech, JPL, NASA, or the US Government.
Henry.B.Hotz@jpl.nasa.gov, or hbhotz@oxy.edu



pgsql-patches by date:

Previous
From: Alvaro Herrera
Date:
Subject: Re: Fix pg_dump dependency on postgres.h
Next
From: "Pavel Stehule"
Date:
Subject: tsearch2api .. wrapper for integrated fultext