Re: krb_match_realm - Mailing list pgsql-patches

From Henry B. Hotz
Subject Re: krb_match_realm
Date
Msg-id 27A632E8-B57E-4654-AD28-E9F9049A424B@jpl.nasa.gov
Whole thread Raw
In response to Re: krb_match_realm  (Magnus Hagander <magnus@hagander.net>)
Responses Re: krb_match_realm
List pgsql-patches
On Nov 2, 2007, at 8:38 AM, Magnus Hagander wrote:

> Henry B. Hotz wrote:
>>
>> On Nov 1, 2007, at 1:40 PM, Magnus Hagander wrote:
>>
>>> Henry B. Hotz wrote:
>>>> Thank you very much.  This helps, but I'm still evaluating how
>>>> much.
>>>>
>>>> I *can* point at one problem though:  you do a strchr
>>>> (gbuf.value, '@')
>>>> and then error out if there isn't a Kerberos realm there.  In
>>>> fact that
>>>> is exactly the default username of at least one of the GSSAPI
>>>> implementations I've tested if the realm is the same as the local
>>>> default realm.
>>>
>>> Eh, so how do we then determine the difference between local
>>> realm and
>>> no realm given?
>>
>> Well, what I've seen is:  no realm given if and only if the default
>> local realm matches the realm for the GSSAPI username.  I don't think
>> that's guaranteed.
>
> Irrk. Very much irrk.
>
>
>>>> 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.

> 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.

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.

>> 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).

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.

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.

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.

I'm actually trying to write some Kerberos principal to X500 name
translation code for mod_auth_kerb right now, and I'm not happy with
my options.  I'm probably going to wind up doing something that I
would tell you is improper, not general purpose, fragile, and
shouldn't be done.  |-P  At least it's completely legitimate for me
to assume that the only mechanism in use is the Kerberos one (since
SPNEGO will have negotiated to kerberos before I need to worry about
it).  This is part of building up an example SAPP server (Solaris
Apache Postgres Perl, you've heard of LAMP servers I assume).

>> Well, it's not a high priority for me, but there is a GSSAPI
>> mechanism
>> called SPKM which uses X500-syle names (X509 certificate subject
>> names
>> to be precise).  If we use gss_name_compare() properly then it should
>> "just work".
>
> I'm unsure if PostgreSQL in general is prepared to deal with such
> usernames. You'd certainly have to verify that stuff before anything
> would "just work".
>
> //Magnus

Well it might be nice if we could use the same logic and conventions
to support TLS client identities as SPKM ones.  Shouldn't be hard.
(Famous last words.)

------------------------------------------------------------------------
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: "Pavel Stehule"
Date:
Subject: Re: V0.1 patch for TODO Item: SQL-language reference parameters by name.
Next
From: "Henry B. Hotz"
Date:
Subject: Re: krb_match_realm