Обсуждение: BUG #9337: SSPI/GSSAPI with mismatched user names

Поиск
Список
Период
Сортировка

BUG #9337: SSPI/GSSAPI with mismatched user names

От
brian@fluggo.com
Дата:
The following bug has been logged on the website:

Bug reference:      9337
Logged by:          Brian Crowell
Email address:      brian@fluggo.com
PostgreSQL version: 9.3.3
Operating system:   Linux
Description:

Hello. I posted this to the general discussion group, but I think it's
worthwhile to call it a bug, too.

I'm working with the Npgsql group on getting integrated security to "just
work" in the same way SQL Server's does. I wrote a workaround for one issue,
only to find out that I need more workarounds, and I finally realized that
this a problem with the way Postgres handles GSSAPI/SSPI logins. You can
read my full description here:

https://github.com/npgsql/Npgsql/issues/162#issuecomment-35916650

The short version is that Postgres requires two user names when using
GSSAPI/SSPI: one from the startup packet, and one from the Kerberos ticket,
and if these don't match exactly, the login fails. It's generally impossible
to determine the correct user name to send in the startup packet.

I think Postgres should either not require or ignore the user name in the
startup packet for these two login types.

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Tom Lane
Дата:
brian@fluggo.com writes:
> The short version is that Postgres requires two user names when using
> GSSAPI/SSPI: one from the startup packet, and one from the Kerberos ticket,
> and if these don't match exactly, the login fails. It's generally impossible
> to determine the correct user name to send in the startup packet.

> I think Postgres should either not require or ignore the user name in the
> startup packet for these two login types.

If we did that, wouldn't it mean that anyone with a working Kerberos login
could log in as *any* database user?  Even a superuser?

I'm prepared to grant that we might need to change the behavior somehow,
but it seems like not requiring any connection at all between the Kerberos
principal name and the database user name would be entirely unsafe.

            regards, tom lane

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Brian Crowell
Дата:
On Mon, Feb 24, 2014 at 12:44 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> If we did that, wouldn't it mean that anyone with a working Kerberos login
> could log in as *any* database user?  Even a superuser?
>
> I'm prepared to grant that we might need to change the behavior somehow,
> but it seems like not requiring any connection at all between the Kerberos
> principal name and the database user name would be entirely unsafe.

I don't think I'm suggesting what you're thinking. I'm saying that if
the Postgres user name *has* to match the Kerberos principal name
anyways, why not just take the Kerberos principal name and save us the
trouble of sending a Postgres user name?

Right now, I'm seeing log entries like this:

  2014-02-24 11:30:40 CST LOG:  provided user name (Brian) and
authenticated user name (BCrowell@REALM.COM) do not match

But the Kerberos ticket is perfectly valid, and matches a Postgres
user. In this case, the program attempting to log in is incapable of
determining the correct Postgres user name to send (see Npgsql bug for
the dirty details), so why not just accept the Kerberos principal
name?

--Brian

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Brian Crowell
Дата:
On Mon, Feb 24, 2014 at 12:50 PM, Brian Crowell <brian@fluggo.com> wrote:
>   2014-02-24 11:30:40 CST LOG:  provided user name (Brian) and
> authenticated user name (BCrowell@REALM.COM) do not match
>
> But the Kerberos ticket is perfectly valid, and matches a Postgres
> user. In this case, the program attempting to log in is incapable of
> determining the correct Postgres user name to send (see Npgsql bug for
> the dirty details), so why not just accept the Kerberos principal
> name?

Or in other words, I'm trying to log in as the Postgres user
"BCrowell@REALM.COM" (which is in the Kerberos ticket), and not as
"Brian" (which is in the startup packet, because Npgsql doesn't know
what else to do).

--Brian

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Stephen Frost
Дата:
* Brian Crowell (brian@fluggo.com) wrote:
> Right now, I'm seeing log entries like this:
>=20
>   2014-02-24 11:30:40 CST LOG:  provided user name (Brian) and
> authenticated user name (BCrowell@REALM.COM) do not match
>=20
> But the Kerberos ticket is perfectly valid, and matches a Postgres
> user. In this case, the program attempting to log in is incapable of
> determining the correct Postgres user name to send (see Npgsql bug for
> the dirty details), so why not just accept the Kerberos principal
> name?

This is what the mapping logic in pg_ident was written to address...

    Thanks,

        Stephen

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Magnus Hagander
Дата:
On Mon, Feb 24, 2014 at 7:56 PM, Stephen Frost <sfrost@snowman.net> wrote:

> * Brian Crowell (brian@fluggo.com) wrote:
> > Right now, I'm seeing log entries like this:
> >
> >   2014-02-24 11:30:40 CST LOG:  provided user name (Brian) and
> > authenticated user name (BCrowell@REALM.COM) do not match
> >
> > But the Kerberos ticket is perfectly valid, and matches a Postgres
> > user. In this case, the program attempting to log in is incapable of
> > determining the correct Postgres user name to send (see Npgsql bug for
> > the dirty details), so why not just accept the Kerberos principal
> > name?
>
> This is what the mapping logic in pg_ident was written to address...
>

There is also a parameter called  include_realm, specifically for Kerberos,
which will remove the @REALM.COM part. But I believe it does that by
default.

Specifically see
http://www.postgresql.org/docs/9.3/static/auth-methods.html#GSSAPI-AUTH,
which deals with both those.

--
 Magnus Hagander
 Me: http://www.hagander.net/
 Work: http://www.redpill-linpro.com/

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Stephen Frost
Дата:
* Brian Crowell (brian@fluggo.com) wrote:
> On Mon, Feb 24, 2014 at 12:50 PM, Brian Crowell <brian@fluggo.com> wrote:
> >   2014-02-24 11:30:40 CST LOG:  provided user name (Brian) and
> > authenticated user name (BCrowell@REALM.COM) do not match
> >
> > But the Kerberos ticket is perfectly valid, and matches a Postgres
> > user. In this case, the program attempting to log in is incapable of
> > determining the correct Postgres user name to send (see Npgsql bug for
> > the dirty details), so why not just accept the Kerberos principal
> > name?
>=20
> Or in other words, I'm trying to log in as the Postgres user
> "BCrowell@REALM.COM" (which is in the Kerberos ticket), and not as
> "Brian" (which is in the startup packet, because Npgsql doesn't know
> what else to do).

To PG, you're trying to log in as PG user 'Brian' and there's no mapping
which allows the kerb princ "BCrowell@REALM.COM" to log in as that user.
Also, is the PG user really "BCrowell@REALM.COM", or is it actually
'bcrowell', in which case you need a mapping for that (unless you tell
PG to just strip the realm off, but I generally recommend against such
since you can end up with cross-realm issues if you ever define a trust
relationship to another realm with different users who might have the
same princs as your local users).

    Thanks,

        Stephen

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Tom Lane
Дата:
Brian Crowell <brian@fluggo.com> writes:
> Right now, I'm seeing log entries like this:

>   2014-02-24 11:30:40 CST LOG:  provided user name (Brian) and
> authenticated user name (BCrowell@REALM.COM) do not match

> But the Kerberos ticket is perfectly valid, and matches a Postgres
> user. In this case, the program attempting to log in is incapable of
> determining the correct Postgres user name to send (see Npgsql bug for
> the dirty details), so why not just accept the Kerberos principal
> name?

Why exactly doesn't Npgsql know what the Kerberos principal name is?
How did it obtain the ticket without knowing that?

            regards, tom lane

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Brian Crowell
Дата:
On Mon, Feb 24, 2014 at 1:10 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Why exactly doesn't Npgsql know what the Kerberos principal name is?
> How did it obtain the ticket without knowing that?

Windows obtained the ticket, not Npgsql. It's attached to my logon
token without Npgsql's help. If I'm on the domain, I _might_ have
access to that information through a call to LsaGetLogonSessionData or
similar. If I'm not on the domain, I definitely don't.

Npgsql is just asking Windows to do GSSAPI auth on its behalf, so it
never really touches that info.

--Brian

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Tom Lane
Дата:
Brian Crowell <brian@fluggo.com> writes:
> On Mon, Feb 24, 2014 at 1:10 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> Why exactly doesn't Npgsql know what the Kerberos principal name is?
>> How did it obtain the ticket without knowing that?

> Windows obtained the ticket, not Npgsql. It's attached to my logon
> token without Npgsql's help. If I'm on the domain, I _might_ have
> access to that information through a call to LsaGetLogonSessionData or
> similar. If I'm not on the domain, I definitely don't.

Hm, so how did Windows know what ticket to get?  *Somewhere* there's
got to be a mapping from "Brian" to "BCrowell".  It might not be
readily accessible to you though :-(

As noted upthread, we can't really do what you're suggesting without
a fundamental rearchitecting of our authentication scheme, which aside
from being a lot of work would probably break at least as many use-cases
as it improves.  To take one example, it's not unreasonable at all that
people might want database superusers to have to use a different auth
method from ordinary users --- so just taking the username out of the
auth method selection process doesn't sound workable.

It's unfortunate that this doesn't fit well with the architecture you
find yourself dealing with on the client side, but I doubt we can do
anything to help you.

            regards, tom lane

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Stephen Frost
Дата:
* Brian Crowell (brian@fluggo.com) wrote:
> On Mon, Feb 24, 2014 at 1:10 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> > Why exactly doesn't Npgsql know what the Kerberos principal name is?
> > How did it obtain the ticket without knowing that?
>=20
> Windows obtained the ticket, not Npgsql. It's attached to my logon
> token without Npgsql's help. If I'm on the domain, I _might_ have
> access to that information through a call to LsaGetLogonSessionData or
> similar. If I'm not on the domain, I definitely don't.
>=20
> Npgsql is just asking Windows to do GSSAPI auth on its behalf, so it
> never really touches that info.

I seem to recall that, at one point, we actually we doing this
automatically in libpq- that is, grabbing the Kerberos princ and then
using it to auth.  That was too constrained though, as we wanted to be
able to have users with names other than their princs, but perhaps we
should have just made it optional instead, perhaps using an environment
variable.  Would that work for you and the general users?  I'm on the
fence about making that the default again since it's possible we would
break things for existing users...

    Thanks,

        Stephen

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Brian Crowell
Дата:
On Mon, Feb 24, 2014 at 1:01 PM, Stephen Frost <sfrost@snowman.net> wrote:
> To PG, you're trying to log in as PG user 'Brian' and there's no mapping
> which allows the kerb princ "BCrowell@REALM.COM" to log in as that user.

Yes, that's the problem. There will not be a mapping.


> Also, is the PG user really "BCrowell@REALM.COM", or is it actually
> 'bcrowell', in which case you need a mapping for that (unless you tell
> PG to just strip the realm off, but I generally recommend against such
> since you can end up with cross-realm issues if you ever define a trust
> relationship to another realm with different users who might have the
> same princs as your local users).

The PG user is "BCrowell@REALM.COM". include_realm is on because we
have a forest, and I don't want any crossed wires between domains.

Really, this is all what I want to happen, and everything about it
works. The only problem is that PG wants a user name that, in a few
cases, I just don't have.

I'm starting to see that this appears very differently to Postgres
people. I'm coming here from SQL Server, where in our company we've
now got it set up that each user's SQL Server login _is_ their domain
login. Not just named the same--SQL Server understands the domain, and
each user is coming in as their Windows identity.

However, to Postgres, Kerberos is not about identities at all, it's
just a fancy password mechanism. Really you just want to know a
Postgres user, and it's never been a problem for users to specify
that. I guess what I'm asking is if Kerberos can be used to specify my
Postgres username as well.

--Brian

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Brian Crowell
Дата:
On Mon, Feb 24, 2014 at 1:25 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Hm, so how did Windows know what ticket to get?  *Somewhere* there's
> got to be a mapping from "Brian" to "BCrowell".  It might not be
> readily accessible to you though :-(

Yes. These are tied together on the user's login token, but I can't
get to the tied information. It can even be specified before my
program starts (via runas /netonly).


> As noted upthread, we can't really do what you're suggesting without
> a fundamental rearchitecting of our authentication scheme, which aside
> from being a lot of work would probably break at least as many use-cases
> as it improves.  To take one example, it's not unreasonable at all that
> people might want database superusers to have to use a different auth
> method from ordinary users --- so just taking the username out of the
> auth method selection process doesn't sound workable.

Well rats. I can see that would require a change at the protocol
level. You'd need to accept a ticket or password from me without
knowing beforehand if that matches the auth method specified for that
user.


> It's unfortunate that this doesn't fit well with the architecture you
> find yourself dealing with on the client side, but I doubt we can do
> anything to help you.

Luckily, I know we can architect a workaround for our organization,
but I was trying to get it as clean as I could for future Npgsql
users.

Thanks for taking the time to talk it over with me anyhow  :P

--Brian

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Brian Crowell
Дата:
On Mon, Feb 24, 2014 at 1:35 PM, Brian Crowell <brian@fluggo.com> wrote:
> Well rats. I can see that would require a change at the protocol
> level. You'd need to accept a ticket or password from me without
> knowing beforehand if that matches the auth method specified for that
> user.

Er, well, one last comment, and I promise I'll leave. You could accept
these in the startup packet.

--Brian

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Stephen Frost
Дата:
* Brian Crowell (brian@fluggo.com) wrote:
> > Also, is the PG user really "BCrowell@REALM.COM", or is it actually
> > 'bcrowell', in which case you need a mapping for that (unless you tell
> > PG to just strip the realm off, but I generally recommend against such
> > since you can end up with cross-realm issues if you ever define a trust
> > relationship to another realm with different users who might have the
> > same princs as your local users).
>=20
> The PG user is "BCrowell@REALM.COM". include_realm is on because we
> have a forest, and I don't want any crossed wires between domains.

Ah, makes sense.  Again, you could have different usernames in PG if you
wanted to keep things simpler, by using pg_ident.conf, but if useing the
full princ works for you then that's certainly fine too.

> Really, this is all what I want to happen, and everything about it
> works. The only problem is that PG wants a user name that, in a few
> cases, I just don't have.

It really should be possible for you to get it.  I'm in flight at the
moment and so the interwebs are a bit lagged or I'd go figure out what
the right GSSAPI calls are, though I can understand if you'd rather just
be able to ask libpq to handle that or maybe pass back what the princ
is, so you don't have to deal with the Kerberos calls directly.

> I'm starting to see that this appears very differently to Postgres
> people. I'm coming here from SQL Server, where in our company we've
> now got it set up that each user's SQL Server login _is_ their domain
> login. Not just named the same--SQL Server understands the domain, and
> each user is coming in as their Windows identity.

I'm familiar with SQL Server and how it works there and in a lot of ways
it's very similar to what happens in PG, and it has similar options for
doing mapping too, as I recall, and if you want to be able to have such
a mapping then you have to have both the log-me-in-as username and the
Kerberos princ.

> However, to Postgres, Kerberos is not about identities at all, it's
> just a fancy password mechanism. Really you just want to know a
> Postgres user, and it's never been a problem for users to specify
> that. I guess what I'm asking is if Kerberos can be used to specify my
> Postgres username as well.

This is overstating it, imv.  The exact same issue happens if, for
example, you want to ssh to a server- you have to provide the Unix
username that you want to log into the system as, along with the
Kerberos ticket.  Those can then be different too, by using a .k5login
file.  If you'd like to complain about something in this regard, it
would be that we don't have any way to link PG users in directly with
LDAP in the way that AD does, where the group membership is doing
through LDAP.  That would certainly be accurate but would be quite a bit
of work to allow ad we don't get many requests for such capability.

    Thanks,

        Stephen

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Tom Lane
Дата:
Brian Crowell <brian@fluggo.com> writes:
> I'm starting to see that this appears very differently to Postgres
> people. I'm coming here from SQL Server, where in our company we've
> now got it set up that each user's SQL Server login _is_ their domain
> login. Not just named the same--SQL Server understands the domain, and
> each user is coming in as their Windows identity.

> However, to Postgres, Kerberos is not about identities at all, it's
> just a fancy password mechanism. Really you just want to know a
> Postgres user, and it's never been a problem for users to specify
> that. I guess what I'm asking is if Kerberos can be used to specify my
> Postgres username as well.

Hm.  That's an interesting way of putting it, and you're right --- we
don't expect Kerberos to be a source of identity.  Which is not the
world view Kerberos users have.

I wonder whether there would be any value in an option for SSPI (and
maybe other auth methods) to say "after authentication is complete,
substitute the authenticated principal name for the database user
name" (possibly after realm-stripping, case-folding, etc).

The usage pattern would be that you'd pass say "use_kerberos_username"
as the user name in the startup packet, and that would select a
pg_hba.conf entry along the lines of

host  use_kerberos_username  all  samenet  sspi  use_principal=without_realm

I'm not sure if that'd solve Npgsql's problem or not, though.  As sketched
here, the existence of such an auth entry, as well as the spelling of the
magic username, would be at the whim of the Postgres installation's DBA.
That might not be stable enough for you; I'm betting you're wishing you
could hard-wire a dummy name.  On the other hand, you weren't complaining
about the fact that you can't use Kerberos at all without a suitable
pg_hba entry; so maybe some additional constraints on its form would be OK
for your use-case.

            regards, tom lane

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Brian Crowell
Дата:
On Mon, Feb 24, 2014 at 1:47 PM, Stephen Frost <sfrost@snowman.net> wrote:
>> The PG user is "BCrowell@REALM.COM". include_realm is on because we
>> have a forest, and I don't want any crossed wires between domains.
>
> Ah, makes sense.  Again, you could have different usernames in PG if you
> wanted to keep things simpler, by using pg_ident.conf, but if useing the
> full princ works for you then that's certainly fine too.

We'd be mapping several dozen users. I'd rather keep things simple  :P


> It really should be possible for you to get it.  I'm in flight at the
> moment and so the interwebs are a bit lagged or I'd go figure out what
> the right GSSAPI calls are, though I can understand if you'd rather just
> be able to ask libpq to handle that or maybe pass back what the princ
> is, so you don't have to deal with the Kerberos calls directly.

If it is possible, I'd be happy to find out. Note that I'm trying to
solve the LOGON32_LOGON_NEW_CREDENTIALS case, which ADO.NET handles
just fine. This discussion does not give me much hope:

https://groups.google.com/forum/#!topic/microsoft.public.platformsdk.security/5L7ugO0Fc90


> I'm familiar with SQL Server and how it works there and in a lot of ways
> it's very similar to what happens in PG, and it has similar options for
> doing mapping too, as I recall, and if you want to be able to have such
> a mapping then you have to have both the log-me-in-as username and the
> Kerberos princ.

I'm not sure what you mean. Our connection strings look like this:

server=productiondb.realm.com;Integrated
Security=SSPI;database=OURDB;Connect Timeout=500;Application Name=w00t

Most of our users do not even have SQL Server logins. They get in by
group permissions. They're mapped to application data by their SID.


> This is overstating it, imv.  The exact same issue happens if, for
> example, you want to ssh to a server- you have to provide the Unix
> username that you want to log into the system as, along with the
> Kerberos ticket.  Those can then be different too, by using a .k5login
> file.  If you'd like to complain about something in this regard, it
> would be that we don't have any way to link PG users in directly with
> LDAP in the way that AD does, where the group membership is doing
> through LDAP.  That would certainly be accurate but would be quite a bit
> of work to allow ad we don't get many requests for such capability.

Sorry, I didn't mean for it to sound like a complaint.

But yes, I am looking for the Postgres account to be "tied" to the
Kerberos account. It doesn't have to be through LDAP; the supplied
Kerberos user name is enough. I realize I will still have to set up a
mapping for each user, but that's small potatoes.

--Brian

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Brian Crowell
Дата:
On Mon, Feb 24, 2014 at 1:58 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> I wonder whether there would be any value in an option for SSPI (and
> maybe other auth methods) to say "after authentication is complete,
> substitute the authenticated principal name for the database user
> name" (possibly after realm-stripping, case-folding, etc).

I humbly resubmit my ticket-in-the-startup-packet suggestion, which
I'd hope would be easier, especially since any program not supplying
it would fall back to the standard challenge auth mechanism.

Like:

1. client -> server startup packet + GSSAPI="here's my ticket"
2. server -> client AuthenticationGSSContinue
3. client -> server password packet
4. server -> client AuthenticationOK

But then I don't know what I'm talking about really   :P

(goes to read the protocol specs)

--Brian

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Brian Crowell
Дата:
On Mon, Feb 24, 2014 at 2:09 PM, Brian Crowell <brian@fluggo.com> wrote:
> I humbly resubmit my ticket-in-the-startup-packet suggestion, which
> I'd hope would be easier, especially since any program not supplying
> it would fall back to the standard challenge auth mechanism.

Tell you what.

Our company is not to the point of needing anything like this, I was
just helping out the Npgsql people. But if we should get to the point
that we'd want it, would you accept patches that implemented this sort
of shortcut authentication?

--Brian

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Tom Lane
Дата:
Brian Crowell <brian@fluggo.com> writes:
> On Mon, Feb 24, 2014 at 2:09 PM, Brian Crowell <brian@fluggo.com> wrote:
>> I humbly resubmit my ticket-in-the-startup-packet suggestion, which
>> I'd hope would be easier, especially since any program not supplying
>> it would fall back to the standard challenge auth mechanism.

> Tell you what.

> Our company is not to the point of needing anything like this, I was
> just helping out the Npgsql people. But if we should get to the point
> that we'd want it, would you accept patches that implemented this sort
> of shortcut authentication?

As a new feature it would need discussion, and I'm not real sure that
it's sensible even in theory.  In our model, until you've identified the
relevant pg_hba.conf entry you don't know which Kerberos server to talk to
to validate the ticket.

If it's possible to extract a principal name from a ticket without
contacting the server, then that objection fails ... but if that were
the case then I suppose you'd not be here looking for a solution.

I suppose you could propose some additional configuration settings
that would be looked at in advance of the pg_hba.conf lookup to allow
extraction of a user name from a supplied ticket.  However, that would
greatly expand the potential for DOS attacks based on launching bogus
startup packets at a postmaster (since the computation needed before
rejecting a packet is greatly increased if we have to contact some
Kerberos server).  Not sure if that objection is fatal or not.

            regards, tom lane

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Brian Crowell
Дата:
On Mon, Feb 24, 2014 at 2:56 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> If it's possible to extract a principal name from a ticket without
> contacting the server, then that objection fails ... but if that were
> the case then I suppose you'd not be here looking for a solution.

You've got a point. I do believe the principal name is in the ticket
in clear text. I could generate a ticket in anticipation of needing
it, extract the name, and send that. I have no idea how to get it, but
I'll look into it.

I still think this would be useful in the server. If I'm right, and
the principal name is in clear text, the server would look at it this
way:

PSEUDOCODE

// (server receives packet without user, but
// ticket="my ticket for User@REALM.COM")

if(!user_name) {
  if(ticket)
    user_name = extract_user_name(ticket)
}

if(!user_name)
  return NO_USER_NAME;

auth_type = lookup_pg_hba(user_name, database, etc.)

if(ticket) {
  if(auth_type != GSSAPI)
    return BAD_AUTH;

  accept_gssapi_packet(ticket);
}
else {
  // Do what you would normally do
  challenge(auth_type);
}

/PSEUDOCODE

Something like that.

--Brian

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Tom Lane
Дата:
Brian Crowell <brian@fluggo.com> writes:
> On Mon, Feb 24, 2014 at 2:56 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> If it's possible to extract a principal name from a ticket without
>> contacting the server, then that objection fails ... but if that were
>> the case then I suppose you'd not be here looking for a solution.

> You've got a point. I do believe the principal name is in the ticket
> in clear text. I could generate a ticket in anticipation of needing
> it, extract the name, and send that. I have no idea how to get it, but
> I'll look into it.

> I still think this would be useful in the server.

If it's possible to get a name out of a ticket without contacting a
realm server, I think what you're talking about would likely be all right.
IIUC this approach would also save one round trip to the client to get
the ticket once we've decided to use SSPI auth, so that seems like a
potential benefit independently of where the username is coming from.

I'm not really the house expert on Kerberos-style auth though, so I'd
defer to Stephen and some other people on whether there are hidden
gotchas.

One question worth asking is whether exposing the ticket in the startup
packet is problematic if the startup packet is unencrypted and can be
snooped by third parties.

            regards, tom lane

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Brian Crowell
Дата:
On Mon, Feb 24, 2014 at 3:40 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> If it's possible to get a name out of a ticket without contacting a
> realm server, I think what you're talking about would likely be all right.
> IIUC this approach would also save one round trip to the client to get
> the ticket once we've decided to use SSPI auth, so that seems like a
> potential benefit independently of where the username is coming from.

Well, for starters, it turns out I'm wrong about the principal. Only
the target principal (that of the Postgres server) is in clear text.
The source principal (my user name) is in the encrypted part of the
request, so that can _only_ be decrypted by the server. However, if I
remember right, the server will be in direct possession of the
decryption key (IIRC, its own password), and therefore should be able
to determine the user name without contacting a third server.

This will require more research.


> One question worth asking is whether exposing the ticket in the startup
> packet is problematic if the startup packet is unencrypted and can be
> snooped by third parties.

Kerberos takes care of encryption of the ticket. It's really just the
same mechanism that's already in place, and with the same encryption,
just pushed to Postgres instead of Postgres asking for it.

MD5 passwords, on the other hand, have to wait for a salt from the
server before they can be sent, so they can't take advantage of this
shortcut.

--Brian

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Tom Lane
Дата:
Brian Crowell <brian@fluggo.com> writes:
> On Mon, Feb 24, 2014 at 3:40 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> If it's possible to get a name out of a ticket without contacting a
>> realm server, I think what you're talking about would likely be all right.

> Well, for starters, it turns out I'm wrong about the principal. Only
> the target principal (that of the Postgres server) is in clear text.
> The source principal (my user name) is in the encrypted part of the
> request, so that can _only_ be decrypted by the server. However, if I
> remember right, the server will be in direct possession of the
> decryption key (IIRC, its own password), and therefore should be able
> to determine the user name without contacting a third server.

Um.  I spoke imprecisely, I see.  The objection to involving a Kerberos
server in determining the username is not solely about the cycles
involved; it's that it requires identifying a specific Kerberos server
to do it.  Don't we lose multi-realm support if we have to know the
server's password in advance of examining pg_hba.conf?

I looked at our docs again and notice that there is no authentication
server specification option for the GSSAPI auth method.  I guess that
that information is buried within the "server key file" or someplace;
this goes beyond my knowledge of Kerberos internals I fear.  I do see
that there isn't any visible specification of a server password either,
so even absent the multi-realm issue it's not clear to me that what
you propose is practical for code outside the Kerberos libraries.

            regards, tom lane

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Stephen Frost
Дата:
All,

I'll fill in more on this tomorrow, but the actual service ticket is not
going to be useful on the client side, no. There is a ticket cache on the
client though, normally, which should have info about the princ the cache
is for. That's what klist operates against (on Windows and Linux..).

Thanks,

Stephen

On Monday, February 24, 2014, Tom Lane <tgl@sss.pgh.pa.us> wrote:

> Brian Crowell <brian@fluggo.com <javascript:;>> writes:
> > On Mon, Feb 24, 2014 at 3:40 PM, Tom Lane <tgl@sss.pgh.pa.us<javascript:;>>
> wrote:
> >> If it's possible to get a name out of a ticket without contacting a
> >> realm server, I think what you're talking about would likely be all
> right.
>
> > Well, for starters, it turns out I'm wrong about the principal. Only
> > the target principal (that of the Postgres server) is in clear text.
> > The source principal (my user name) is in the encrypted part of the
> > request, so that can _only_ be decrypted by the server. However, if I
> > remember right, the server will be in direct possession of the
> > decryption key (IIRC, its own password), and therefore should be able
> > to determine the user name without contacting a third server.
>
> Um.  I spoke imprecisely, I see.  The objection to involving a Kerberos
> server in determining the username is not solely about the cycles
> involved; it's that it requires identifying a specific Kerberos server
> to do it.  Don't we lose multi-realm support if we have to know the
> server's password in advance of examining pg_hba.conf?
>
> I looked at our docs again and notice that there is no authentication
> server specification option for the GSSAPI auth method.  I guess that
> that information is buried within the "server key file" or someplace;
> this goes beyond my knowledge of Kerberos internals I fear.  I do see
> that there isn't any visible specification of a server password either,
> so even absent the multi-realm issue it's not clear to me that what
> you propose is practical for code outside the Kerberos libraries.
>
>                         regards, tom lane
>
>

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Brian Crowell
Дата:
On Mon, Feb 24, 2014 at 6:30 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Um.  I spoke imprecisely, I see.  The objection to involving a Kerberos
> server in determining the username is not solely about the cycles
> involved; it's that it requires identifying a specific Kerberos server
> to do it.  Don't we lose multi-realm support if we have to know the
> server's password in advance of examining pg_hba.conf?

Not as far as I know. For GSSAPI, the server determines which password
to use based on the ticket, which includes the server's principal
name, and it looks it up in its own key file (PG's krb_server_keyfile
option). (For SSPI, I don't think you can use multiple passwords; if
coming from another domain, you'd need Active Directory's assistance
to cross the domain correctly.)

I also went back and checked, and the server does not have to contact
a Kerberos server to authenticate the client or determine its user
name. So long as the ticket is encrypted with the correct password
(Postgres's password), Postgres can decrypt it and know who the client
is and that they're really who they say they are.

The picture on this page will help:

http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/default.htm?turl=WordDocuments%2Fintroductiontokerberosauthentication.htm

Steps 1 and 2 in that graph are the client authenticating to the KDC.
Step 3 is the client telling the KDC it wants to talk to a Postgres
server, and it gives Postgres's principal name (such as
"POSTGRES/mymachine.realm.com@REALM.COM"). In step 4, the KDC returns
a ticket encrypted with Postgres's password.

In step 5, Postgres receives the client's ticket, and decrypts it with
its own password. If it decrypts properly and checks out, Postgres
knows it's legit, because only the KDC should know Postgres's
password. Inside will be the user's name.


> I looked at our docs again and notice that there is no authentication
> server specification option for the GSSAPI auth method.  I guess that
> that information is buried within the "server key file" or someplace;
> this goes beyond my knowledge of Kerberos internals I fear.  I do see
> that there isn't any visible specification of a server password either,
> so even absent the multi-realm issue it's not clear to me that what
> you propose is practical for code outside the Kerberos libraries.

Yes, the password is in the key file.

Since this request has turned out to be a little more complicated than
I thought, I'd like to volunteer to research it further and maybe
bring it along. It's not part of my job duties right now, so I'll have
to come back and visit it later, but so far I don't see anything
obvious that would make it unfeasible. The GSSAPI/Kerberos case looks
the easiest. SSPI/Negotiate will be harder because that requires
passing data back and forth; you couldn't finish in one packet.

Interesting problem.

--Brian

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Stephen Frost
Дата:
* Brian Crowell (brian@fluggo.com) wrote:
> On Mon, Feb 24, 2014 at 6:30 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> > Um.  I spoke imprecisely, I see.  The objection to involving a Kerberos
> > server in determining the username is not solely about the cycles
> > involved; it's that it requires identifying a specific Kerberos server
> > to do it.  Don't we lose multi-realm support if we have to know the
> > server's password in advance of examining pg_hba.conf?
>=20
> Not as far as I know. For GSSAPI, the server determines which password
> to use based on the ticket, which includes the server's principal
> name, and it looks it up in its own key file (PG's krb_server_keyfile
> option). (For SSPI, I don't think you can use multiple passwords; if
> coming from another domain, you'd need Active Directory's assistance
> to cross the domain correctly.)

There's two different things here- multi-realm (as in, a given server
can live in multiple, independent, realms) and cross-realm (where the
realms trust each other).  For cross-realm, the server exists only in
one realm and there's only one key for it; users from other realms will
get a cross-realm ticket-granting-ticket which can then be used to
request a service ticket for the server.  For multi-realm, there's
multiple keys because the server actually exists in multiple realms.
I've not gone back to look at why we added multi-realm support, but I
wonder if it might have specifically been to allow a PG server to be in
both an AD realm and a Unix realm at the same time, without a cross
realm trust between the two (which was problematic until AD got AES
support since the only compatible encryption was quite weak).

While I've seen discussion about it in the past, my recollection is that
we *do* need to decide which entry in the keytab to use to decrypt the
ticket first and to figure that out we need to know what we're going to
use for krb_realm, krb_srvname and krb_server_hostname.  Since those can
be set in pg_hba.conf based on the information we're provided in the
startup packet, we would be giving up some flexability in this case. =20

On the other hand, Magnus removing the krb5 auth method also removed
krb_server_hostname..  I'll ask him about that because we should
probably make that available under 'gss' or we may end up leaving some
of our users out in the cold when 9.4 comes out and that'd be quite
unfortuante.

Regarding getting the username from the local credential cache, in the
(recently removed) krb5 support, we were extracting the username in
libpq from the credentials cache, but only needed it to pass back to
the krb5 calls.  Still, that is example code of how to do it using the
Kerberos libraries, while you can use gss_inquire_cred() with GSSAPI.

If we decide to allow an option where we use the 'default cred' in
GSSAPI to also determine the PG username we are authenticating to, we'll
want to think about how we support that in libpq and psql and consider
what to do about the limitations of not being able to specify different
krb_server_hostname depending on the user which is attempting to
authenicate.

> I also went back and checked, and the server does not have to contact
> a Kerberos server to authenticate the client or determine its user
> name. So long as the ticket is encrypted with the correct password
> (Postgres's password), Postgres can decrypt it and know who the client
> is and that they're really who they say they are.

That's correct- a server in a Kerberos realm never directly communicates
(as part of Kerberos) with the KDCs.

> Since this request has turned out to be a little more complicated than
> I thought, I'd like to volunteer to research it further and maybe
> bring it along. It's not part of my job duties right now, so I'll have
> to come back and visit it later, but so far I don't see anything
> obvious that would make it unfeasible. The GSSAPI/Kerberos case looks
> the easiest. SSPI/Negotiate will be harder because that requires
> passing data back and forth; you couldn't finish in one packet.

No complaints here, just a word of caution that we don't want to break
existing setups and should consider what other systems do in this regard
to avoid surprising behavior for users who are used to SSH or other
Kerberos-enabled systems.

    Thanks,

        Stephen

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Brian Crowell
Дата:
On Tue, Feb 25, 2014 at 11:07 AM, Stephen Frost <sfrost@snowman.net> wrote:
> I've not gone back to look at why we added multi-realm support, but I
> wonder if it might have specifically been to allow a PG server to be in
> both an AD realm and a Unix realm at the same time, without a cross
> realm trust between the two (which was problematic until AD got AES
> support since the only compatible encryption was quite weak).

What a wacky world   :P


> On the other hand, Magnus removing the krb5 auth method also removed
> krb_server_hostname..  I'll ask him about that because we should
> probably make that available under 'gss' or we may end up leaving some
> of our users out in the cold when 9.4 comes out and that'd be quite
> unfortuante.

I'd be interested in why the principal needs to be specified ahead of
time, since it arrives in the ticket. Is it a limitation of the
Kerberos APIs? Or maybe it's to prevent using a different key from the
key file?


> If we decide to allow an option where we use the 'default cred' in
> GSSAPI to also determine the PG username we are authenticating to, we'll
> want to think about how we support that in libpq and psql and consider
> what to do about the limitations of not being able to specify different
> krb_server_hostname depending on the user which is attempting to
> authenicate.

I figured this would be an optional extension, something you could
request in the initial packet. You would explicitly ask for it using
some special invocation of psql, like "psql -K" the way ssh does. As
such, if there are going to be limitations, you could just choose to
authenticate the normal way.


> No complaints here, just a word of caution that we don't want to break
> existing setups and should consider what other systems do in this regard
> to avoid surprising behavior for users who are used to SSH or other
> Kerberos-enabled systems.

Agreed. I looked around, and I thought I saw setups where you could
authenticate using "ssh -K hostname" without having to specify a user.
I couldn't find any more details on it, though, so I'd have to
research that when the time comes.

--Brian

Re: BUG #9337: SSPI/GSSAPI with mismatched user names

От
Stephen Frost
Дата:
* Brian Crowell (brian@fluggo.com) wrote:
> On Tue, Feb 25, 2014 at 11:07 AM, Stephen Frost <sfrost@snowman.net> wrot=
e:
> > On the other hand, Magnus removing the krb5 auth method also removed
> > krb_server_hostname..  I'll ask him about that because we should
> > probably make that available under 'gss' or we may end up leaving some
> > of our users out in the cold when 9.4 comes out and that'd be quite
> > unfortuante.
>=20
> I'd be interested in why the principal needs to be specified ahead of
> time, since it arrives in the ticket. Is it a limitation of the
> Kerberos APIs? Or maybe it's to prevent using a different key from the
> key file?

Yeah, I'm pretty sure you have to set up the server-side stuff before
you can actually pass control to GSSAPI (really, the whole thing
is insane because GSSAPI actually wants to control the socket on both
ends to do whatever communication it needs to with it, so that's why
you set everything up, pass control of the socket to the GSSAPI library
on both sides, and then check what answer you get back from it at the
end).  Note that the princ we're talking about here is the *server-side*
princ, not the client-side one.

> > If we decide to allow an option where we use the 'default cred' in
> > GSSAPI to also determine the PG username we are authenticating to, we'll
> > want to think about how we support that in libpq and psql and consider
> > what to do about the limitations of not being able to specify different
> > krb_server_hostname depending on the user which is attempting to
> > authenicate.
>=20
> I figured this would be an optional extension, something you could
> request in the initial packet. You would explicitly ask for it using
> some special invocation of psql, like "psql -K" the way ssh does. As
> such, if there are going to be limitations, you could just choose to
> authenticate the normal way.

That sounds reasonable to me.

    Thanks!

        Stephen