Indent authentication overloading

Started by Magnus Haganderabout 15 years ago37 messages
#1Magnus Hagander
magnus@hagander.net

Currently, we overload "indent" meaning both "unix socket
authentication" and "ident over tcp", depending on what type of
connection it is. This is quite unfortunate - one of them being one of
the most secure options we have, the other one being one of the most
*insecure* ones (really? ident over tcp? does *anybody* use that
intentionally today?)

Should we not consider naming those two different things?

If not now, then at least put it on the TODO of things to do the next
time we need to break backwards compatibility with the format of
pg_hba.conf? Though if we're going to break backwards compatibility
anywhere, pg_hba is probably one of the least bad places to do it...

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

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#1)
Re: Indent authentication overloading

Magnus Hagander <magnus@hagander.net> writes:

Currently, we overload "indent" meaning both "unix socket
authentication" and "ident over tcp", depending on what type of
connection it is. This is quite unfortunate - one of them being one of
the most secure options we have, the other one being one of the most
*insecure* ones (really? ident over tcp? does *anybody* use that
intentionally today?)

Should we not consider naming those two different things?

Maybe, but it seems like the time to raise the objection was six or
eight years ago :-(. Renaming now will do little except to introduce
even more confusion.

regards, tom lane

#3Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#2)
Re: Indent authentication overloading

On Wed, Nov 17, 2010 at 16:39, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Magnus Hagander <magnus@hagander.net> writes:

Currently, we overload "indent" meaning both "unix socket
authentication" and "ident over tcp", depending on what type of
connection it is. This is quite unfortunate - one of them being one of
the most secure options we have, the other one being one of the most
*insecure* ones (really? ident over tcp? does *anybody* use that
intentionally today?)

Should we not consider naming those two different things?

Maybe, but it seems like the time to raise the objection was six or
eight years ago :-(.  Renaming now will do little except to introduce
even more confusion.

For existing users, yes.
For new users, no.

I certainly get comments on it pretty much every time I do training
that includes explaining pg_hba options.

The question is if it's worth confusing our existing users a little,
at the advantage of not confusing new users. We could of course also
just drop ident-over-tcp completely, but there might be some poor guy
out there who actually *uses* it :-)

And I agree it would've been much better to do it years ago. That
doesn't mean we shouldn't at least *consider* doing it at some point.

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

#4David Fetter
david@fetter.org
In reply to: Magnus Hagander (#3)
Re: Indent authentication overloading

On Wed, Nov 17, 2010 at 04:43:00PM +0100, Magnus Hagander wrote:

On Wed, Nov 17, 2010 at 16:39, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Magnus Hagander <magnus@hagander.net> writes:

Currently, we overload "indent" meaning both "unix socket
authentication" and "ident over tcp", depending on what type of
connection it is. This is quite unfortunate - one of them being
one of the most secure options we have, the other one being one
of the most *insecure* ones (really? ident over tcp? does
*anybody* use that intentionally today?)

Should we not consider naming those two different things?

Maybe, but it seems like the time to raise the objection was six
or eight years ago :-(. �Renaming now will do little except to
introduce even more confusion.

For existing users, yes. For new users, no.

Yep. If we're to be a successful project, the vast majority of our
users are future users, not current or past ones.

I certainly get comments on it pretty much every time I do training
that includes explaining pg_hba options.

The question is if it's worth confusing our existing users a little,
at the advantage of not confusing new users. We could of course also
just drop ident-over-tcp completely, but there might be some poor
guy out there who actually *uses* it :-)

+1 for dropping it completely. We have dropped features--automatic
cast to TEXT, for example--that a good deal more of our user base
relied on, for reasons less compelling than this.

And I agree it would've been much better to do it years ago. That
doesn't mean we shouldn't at least *consider* doing it at some
point.

The sooner, the better, IMHO.

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david.fetter@gmail.com
iCal: webcal://www.tripit.com/feed/ical/people/david74/tripit.ics

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

#5Jeroen Vermeulen
jtv@xs4all.nl
In reply to: Magnus Hagander (#3)
Re: Indent authentication overloading

On 2010-11-17 22:43, Magnus Hagander wrote:

at the advantage of not confusing new users. We could of course also
just drop ident-over-tcp completely, but there might be some poor guy
out there who actually *uses* it :-)

As far as I know, companies do use it in their internal networks where
they do have a reasonable shot at full control over ident connections.
I don't know how easy it would be for them to switch to other methods.

Jeroen

#6Peter Eisentraut
peter_e@gmx.net
In reply to: Magnus Hagander (#1)
Re: Indent authentication overloading

On ons, 2010-11-17 at 16:35 +0100, Magnus Hagander wrote:

Currently, we overload "indent" meaning both "unix socket
authentication" and "ident over tcp", depending on what type of
connection it is. This is quite unfortunate - one of them being one of
the most secure options we have, the other one being one of the most
*insecure* ones (really? ident over tcp? does *anybody* use that
intentionally today?)

Should we not consider naming those two different things?

The original patch called the Unix domain socket version "peer" (whereas
the name "ident" comes from the official name of the TCP/IP protocol
used). You can look it up in the archives, but I believe the argument
for using the name "ident" for both was because "ident" was established
and the new feature would provide the same functionality.

That said, I completely agree with you. Every time I look through a
pg_hba.conf I think, that's a terrible name, we should rename this.

We could perhaps introduce an alternative name and slowly deprecate the
original one.

#7Magnus Hagander
magnus@hagander.net
In reply to: Jeroen Vermeulen (#5)
Re: Indent authentication overloading

On Wed, Nov 17, 2010 at 17:10, Jeroen Vermeulen <jtv@xs4all.nl> wrote:

On 2010-11-17 22:43, Magnus Hagander wrote:

at the advantage of not confusing new users. We could of course also
just drop ident-over-tcp completely, but there might be some poor guy
out there who actually *uses* it :-)

As far as I know, companies do use it in their internal networks where they
do have a reasonable shot at full control over ident connections. I don't
know how easy it would be for them to switch to other methods.

Yea, I think deleting it is going a bit overboard.

If it was a matter of changing it for those who use ident over tcp, I
really wouldn't hesitate - they're few :-) But the problem is that
it's the ident-over-tcp that's correctly named, not the other one...

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

#8Magnus Hagander
magnus@hagander.net
In reply to: Peter Eisentraut (#6)
Re: Indent authentication overloading

On Wed, Nov 17, 2010 at 17:31, Peter Eisentraut <peter_e@gmx.net> wrote:

On ons, 2010-11-17 at 16:35 +0100, Magnus Hagander wrote:

Currently, we overload "indent" meaning both "unix socket
authentication" and "ident over tcp", depending on what type of
connection it is. This is quite unfortunate - one of them being one of
the most secure options we have, the other one being one of the most
*insecure* ones (really? ident over tcp? does *anybody* use that
intentionally today?)

Should we not consider naming those two different things?

The original patch called the Unix domain socket version "peer" (whereas
the name "ident" comes from the official name of the TCP/IP protocol
used).  You can look it up in the archives, but I believe the argument
for using the name "ident" for both was because "ident" was established
and the new feature would provide the same functionality.

Yeah, I vaguely recall that discussion - too lazy to actually look it
up :-) I think the argument was definitely wrong, but it didn't seem
so at the time...

That said, I completely agree with you.  Every time I look through a
pg_hba.conf I think, that's a terrible name, we should rename this.

We could perhaps introduce an alternative name and slowly deprecate the
original one.

That seems reasonable. Maybe even have the server emit a warning when
it sees it (since we now read/parse pg_hba.conf on server start, it
would only show up once per server reload, not on every connect). Or
maybe just doc-deprecate in 9.1, warning in 9.2, drop in 9.3 or
something?

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

#9Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#7)
Re: Indent authentication overloading

Magnus Hagander <magnus@hagander.net> writes:

If it was a matter of changing it for those who use ident over tcp, I
really wouldn't hesitate - they're few :-) But the problem is that
it's the ident-over-tcp that's correctly named, not the other one...

Yeah, renaming the TCP version would be quite wrong. If we're going to
do something about this, I agree with Peter's suggestion: add "peer" as
the preferred name for the Unix-socket method, and deprecate but don't
remove "ident".

regards, tom lane

#10Jeroen Vermeulen
jtv@xs4all.nl
In reply to: Magnus Hagander (#7)
Re: Indent authentication overloading

On 2010-11-18 00:14, Magnus Hagander wrote:

If it was a matter of changing it for those who use ident over tcp, I
really wouldn't hesitate - they're few :-) But the problem is that
it's the ident-over-tcp that's correctly named, not the other one...

True.

By the way ISTR we don't fall back to identd for TCP connections alone.
I saw it documented somewhere that we also talk to identd on operating
systems that won't tell us who's on the other end of the socket. Are
those still out there?

Jeroen

#11Stuart Bishop
stuart@stuartbishop.net
In reply to: Magnus Hagander (#1)
Re: Indent authentication overloading

On Wed, Nov 17, 2010 at 10:35 PM, Magnus Hagander <magnus@hagander.net> wrote:

Currently, we overload "indent" meaning both "unix socket
authentication" and "ident over tcp", depending on what type of
connection it is. This is quite unfortunate - one of them being one of
the most secure options we have, the other one being one of the most
*insecure* ones (really? ident over tcp? does *anybody* use that
intentionally today?)

We use it. Do you have an alternative that doesn't lower security
besides Kerberos? Anti-ident arguments are straw man arguments - "If
you setup identd badly or don't trust remote root or your network,
ident sucks as an authentication mechanism".

Ident is great as you don't have to lower security by dealing with
keys on the client system (more management headaches == lower
security), or worry about those keys being reused by accounts that
shouldn't be reusing them. Please don't deprecate it unless there is
an alternative. And if you are a pg_pool or pgbouncer maintainer,
please consider adding support :)

--
Stuart Bishop <stuart@stuartbishop.net>
http://www.stuartbishop.net/

#12Josh Berkus
josh@agliodbs.com
In reply to: Stuart Bishop (#11)
Re: Indent authentication overloading

We use it. Do you have an alternative that doesn't lower security
besides Kerberos? Anti-ident arguments are straw man arguments - "If
you setup identd badly or don't trust remote root or your network,
ident sucks as an authentication mechanism".

Actually, you're trusting that nobody can add their own machine as a
node on your network. All someone has to do is plug their linux laptop
into a network cable in your office and they have free access to the
database.

Ident is great as you don't have to lower security by dealing with
keys on the client system (more management headaches == lower
security), or worry about those keys being reused by accounts that
shouldn't be reusing them. Please don't deprecate it unless there is
an alternative. And if you are a pg_pool or pgbouncer maintainer,
please consider adding support :)

I don't think anyone is talking about eliminating it, just
distinguishing ident-over-TCP from unix-socket-same-user, which are
really two different authentication mechanisms.

HOWEVER, I can't see any way of doing this which wouldn't cause a
significant amount of backwards-compatibility confusion. Given that
users can distinguish between local and TCP ident in pg_hba.conf already
(and the default pg_hba.conf does) it is worth the confusion it will cause?

--
-- Josh Berkus
PostgreSQL Experts Inc.
http://www.pgexperts.com

#13Aidan Van Dyk
aidan@highrise.ca
In reply to: Josh Berkus (#12)
Re: Indent authentication overloading

On Thu, Nov 18, 2010 at 1:01 PM, Josh Berkus <josh@agliodbs.com> wrote:

We use it. Do you have an alternative that doesn't lower security
besides Kerberos? Anti-ident arguments are straw man arguments - "If
you setup identd badly or don't trust remote root or your network,
ident sucks as an authentication mechanism".

Actually, you're trusting that nobody can add their own machine as a node on
your network.  All someone has to do is plug their linux laptop into a
network cable in your office and they have free access to the database.

I think you need to give him a little more credit than that... From
the description he gave, I wouldn't be surprised if the networks he's
using ident on, he's got switch ports locked, limited server access,
etc...

His whole point was that in his locked down network, ident is *better*
that giving everybody "yet another password" they have to manage, have
users not mis-manage, and make sure users don't mis-use...

So, yes, ident is only as secure as the *network and machines* it's
used on. Passwords are only as secure as the users managing them, and
the machines/filesystems containing .pgpass ;-)

a.

--
Aidan Van Dyk                                             Create like a god,
aidan@highrise.ca                                       command like a king,
http://www.highrise.ca/                                   work like a slave.

#14Tom Lane
tgl@sss.pgh.pa.us
In reply to: Josh Berkus (#12)
Re: Indent authentication overloading

Josh Berkus <josh@agliodbs.com> writes:

We use it. Do you have an alternative that doesn't lower security
besides Kerberos? Anti-ident arguments are straw man arguments - "If
you setup identd badly or don't trust remote root or your network,
ident sucks as an authentication mechanism".

Actually, you're trusting that nobody can add their own machine as a
node on your network. All someone has to do is plug their linux laptop
into a network cable in your office and they have free access to the
database.

You're assuming the OP is using ident for wild-card IP ranges rather
than specific IP addresses. I agree that ident is *hard* to set up
securely, but that doesn't mean it's entirely insecure.

I don't think anyone is talking about eliminating it, just
distinguishing ident-over-TCP from unix-socket-same-user, which are
really two different authentication mechanisms.

HOWEVER, I can't see any way of doing this which wouldn't cause a
significant amount of backwards-compatibility confusion.

I thought the proposal on the table was to add "peer" (or some other
name) to refer to the unix-socket auth method, and use that term
preferentially in the docs, while continuing to accept "ident" as an
old name for it. Is that really too confusing?

regards, tom lane

#15Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#14)
Re: Indent authentication overloading

On Thu, Nov 18, 2010 at 19:21, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Josh Berkus <josh@agliodbs.com> writes:

We use it. Do you have an alternative that doesn't lower security
besides Kerberos? Anti-ident arguments are straw man arguments - "If
you setup identd badly or don't trust remote root or your network,
ident sucks as an authentication mechanism".

Actually, you're trusting that nobody can add their own machine as a
node on your network.  All someone has to do is plug their linux laptop
into a network cable in your office and they have free access to the
database.

You're assuming the OP is using ident for wild-card IP ranges rather
than specific IP addresses.  I agree that ident is *hard* to set up
securely, but that doesn't mean it's entirely insecure.

If you can get on the network, you can take out that single IP as
well, in most networks. (Yes, you can protect against that, but it's
not the default by any means). It takes a little bit more work, but
it's really not that hard.

OTOH, if you can get on the network in *that* way, you should be using
SSL or ipsec.

But I definitely agree that it can be used in secure ways, depending
on the circumstances. If it wans't clear, my "suggestion" to remove it
completely really wasn't serious.

I don't think anyone is talking about eliminating it, just
distinguishing ident-over-TCP from unix-socket-same-user, which are
really two different authentication mechanisms.

HOWEVER, I can't see any way of doing this which wouldn't cause a
significant amount of backwards-compatibility confusion.

I thought the proposal on the table was to add "peer" (or some other
name) to refer to the unix-socket auth method, and use that term
preferentially in the docs, while continuing to accept "ident" as an
old name for it.  Is that really too confusing?

Yes, that's the current proposal - and also have the system log that
"ident is deprecated, use peer" when it's found in the files.

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

#16Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#15)
Re: Indent authentication overloading

Magnus Hagander <magnus@hagander.net> writes:

On Thu, Nov 18, 2010 at 19:21, Tom Lane <tgl@sss.pgh.pa.us> wrote:

I thought the proposal on the table was to add "peer" (or some other
name) to refer to the unix-socket auth method, and use that term
preferentially in the docs, while continuing to accept "ident" as an
old name for it. �Is that really too confusing?

Yes, that's the current proposal - and also have the system log that
"ident is deprecated, use peer" when it's found in the files.

Personally I could do without that little frammish. We don't issue
wrist-slaps for other obsolete usages; why single out this one?

It's also warning about the wrong thing. IMO the real subtext to this
discussion is that we're afraid people are using ident-over-TCP
insecurely because they've confused it with ident-over-socket.
Which is a legitimate concern, but issuing warnings about
ident-over-socket configurations will accomplish nothing whatsoever
to wake up the guy at risk, because he's not using one. It will only
make us look like pedantic nannies annoying people whose configurations
are perfectly fine.

regards, tom lane

#17Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#14)
Re: Indent authentication overloading

On 11/18/2010 01:21 PM, Tom Lane wrote:

I thought the proposal on the table was to add "peer" (or some other
name) to refer to the unix-socket auth method, and use that term
preferentially in the docs, while continuing to accept "ident" as an
old name for it. Is that really too confusing?

Not to me. And I think that's a good proposal.

cheers

andrew

#18Josh Berkus
josh@agliodbs.com
In reply to: Magnus Hagander (#15)
Re: Indent authentication overloading

I thought the proposal on the table was to add "peer" (or some other
name) to refer to the unix-socket auth method, and use that term
preferentially in the docs, while continuing to accept "ident" as an
old name for it. Is that really too confusing?

What about the pg_ident file? Are we going to rename it? Are we
(better) going to have separate files for pg_peer and pg_ident?

--
-- Josh Berkus
PostgreSQL Experts Inc.
http://www.pgexperts.com

#19Magnus Hagander
magnus@hagander.net
In reply to: Josh Berkus (#18)
Re: Indent authentication overloading

On Thu, Nov 18, 2010 at 19:41, Josh Berkus <josh@agliodbs.com> wrote:

I thought the proposal on the table was to add "peer" (or some other
name) to refer to the unix-socket auth method, and use that term
preferentially in the docs, while continuing to accept "ident" as an
old name for it.  Is that really too confusing?

What about the pg_ident file?  Are we going to rename it?  Are we

We should've done that long ago - it's already used for things that
aren't ident. If anything, it should be pg_usermap.conf.

(better) going to have separate files for pg_peer and pg_ident?

Why? It already supports multiple maps...

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

#20Josh Berkus
josh@agliodbs.com
In reply to: Magnus Hagander (#19)
Re: Indent authentication overloading

We should've done that long ago - it's already used for things that
aren't ident. If anything, it should be pg_usermap.conf.

That would be nice. How would we handle the backwards compatibility?
Accept pg_ident files also for 2 versions with a warning in the logs,
and then stop reading them?

--
-- Josh Berkus
PostgreSQL Experts Inc.
http://www.pgexperts.com

#21Greg Stark
gsstark@mit.edu
In reply to: Tom Lane (#16)
Re: Indent authentication overloading

On Thu, Nov 18, 2010 at 6:36 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

It's also warning about the wrong thing.  IMO the real subtext to this
discussion is that we're afraid people are using ident-over-TCP
insecurely because they've confused it with ident-over-socket.
Which is a legitimate concern, but issuing warnings about
ident-over-socket configurations will accomplish nothing whatsoever
to wake up the guy at risk, because he's not using one.  It will only
make us look like pedantic nannies annoying people whose configurations
are perfectly fine.

Perhaps we should rename both then? Then we could warn if someone is
using ident to refer to identd authentication but not if they're using
it to refer to peer authentication.

--
greg

#22Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#16)
Re: Indent authentication overloading

On Thu, Nov 18, 2010 at 19:36, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Magnus Hagander <magnus@hagander.net> writes:

On Thu, Nov 18, 2010 at 19:21, Tom Lane <tgl@sss.pgh.pa.us> wrote:

I thought the proposal on the table was to add "peer" (or some other
name) to refer to the unix-socket auth method, and use that term
preferentially in the docs, while continuing to accept "ident" as an
old name for it.  Is that really too confusing?

Yes, that's the current proposal - and also have the system log that
"ident is deprecated, use peer" when it's found in the files.

Personally I could do without that little frammish.  We don't issue
wrist-slaps for other obsolete usages; why single out this one?

Fair enough. I may be guilty of thinking we should do it more often
;), but I agree that being consistent is more important.

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

#23Bruce Momjian
bruce@momjian.us
In reply to: Magnus Hagander (#1)
Re: Indent authentication overloading

Added to TODO:

Rename unix domain socket 'ident' connections to 'peer', to avoid
confusion with TCP 'ident'

* http://archives.postgresql.org/pgsql-hackers/2010-11/msg01053.php

---------------------------------------------------------------------------

Magnus Hagander wrote:

Currently, we overload "indent" meaning both "unix socket
authentication" and "ident over tcp", depending on what type of
connection it is. This is quite unfortunate - one of them being one of
the most secure options we have, the other one being one of the most
*insecure* ones (really? ident over tcp? does *anybody* use that
intentionally today?)

Should we not consider naming those two different things?

If not now, then at least put it on the TODO of things to do the next
time we need to break backwards compatibility with the format of
pg_hba.conf? Though if we're going to break backwards compatibility
anywhere, pg_hba is probably one of the least bad places to do it...

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

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +

#24Magnus Hagander
magnus@hagander.net
In reply to: Bruce Momjian (#23)
Re: Indent authentication overloading

On Thu, Mar 10, 2011 at 22:22, Bruce Momjian <bruce@momjian.us> wrote:

Added to TODO:

       Rename unix domain socket 'ident' connections to 'peer', to avoid
       confusion with TCP 'ident'

Should we consider adding "peer" as an alias for "ident" already in
9.1 (and change the default pg_hba.conf template), and then deprecate
ident for 9.2 and remove it in 9.3 or something? By adding the alias
now (yes, I know it's not in the last CF :P), we can move what's going
to be a long process up one release...

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

#25Bruce Momjian
bruce@momjian.us
In reply to: Magnus Hagander (#24)
Re: Indent authentication overloading

Magnus Hagander wrote:

On Thu, Mar 10, 2011 at 22:22, Bruce Momjian <bruce@momjian.us> wrote:

Added to TODO:

? ? ? ?Rename unix domain socket 'ident' connections to 'peer', to avoid
? ? ? ?confusion with TCP 'ident'

Should we consider adding "peer" as an alias for "ident" already in
9.1 (and change the default pg_hba.conf template), and then deprecate
ident for 9.2 and remove it in 9.3 or something? By adding the alias
now (yes, I know it's not in the last CF :P), we can move what's going
to be a long process up one release...

Well, we can certainly do that.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +

#26Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#24)
Re: Indent authentication overloading

Magnus Hagander <magnus@hagander.net> writes:

On Thu, Mar 10, 2011 at 22:22, Bruce Momjian <bruce@momjian.us> wrote:

Added to TODO:

� � � �Rename unix domain socket 'ident' connections to 'peer', to avoid
� � � �confusion with TCP 'ident'

Should we consider adding "peer" as an alias for "ident" already in
9.1 (and change the default pg_hba.conf template), and then deprecate
ident for 9.2 and remove it in 9.3 or something? By adding the alias
now (yes, I know it's not in the last CF :P), we can move what's going
to be a long process up one release...

It doesn't strike me as urgent enough to be worth pushing through in a
hurry. We have got plenty to do to get 9.1 out the door already ...

regards, tom lane

#27Peter Eisentraut
peter_e@gmx.net
In reply to: Magnus Hagander (#24)
Re: Indent authentication overloading

On tor, 2011-03-10 at 22:45 +0100, Magnus Hagander wrote:

On Thu, Mar 10, 2011 at 22:22, Bruce Momjian <bruce@momjian.us> wrote:

Added to TODO:

Rename unix domain socket 'ident' connections to 'peer', to avoid
confusion with TCP 'ident'

Should we consider adding "peer" as an alias for "ident" already in
9.1 (and change the default pg_hba.conf template), and then deprecate
ident for 9.2 and remove it in 9.3 or something? By adding the alias
now (yes, I know it's not in the last CF :P), we can move what's going
to be a long process up one release...

Might as well, if you can get it done soon. The documentation might
need more extensive adjustments.

#28Magnus Hagander
magnus@hagander.net
In reply to: Peter Eisentraut (#27)
1 attachment(s)
Re: Indent authentication overloading

On Fri, Mar 11, 2011 at 15:36, Peter Eisentraut <peter_e@gmx.net> wrote:

On tor, 2011-03-10 at 22:45 +0100, Magnus Hagander wrote:

On Thu, Mar 10, 2011 at 22:22, Bruce Momjian <bruce@momjian.us> wrote:

Added to TODO:

       Rename unix domain socket 'ident' connections to 'peer', to avoid
       confusion with TCP 'ident'

Should we consider adding "peer" as an alias for "ident" already in
9.1 (and change the default pg_hba.conf template), and then deprecate
ident for 9.2 and remove it in 9.3 or something? By adding the alias
now (yes, I know it's not in the last CF :P), we can move what's going
to be a long process up one release...

Might as well, if you can get it done soon.  The documentation might
need more extensive adjustments.

The code itself is pretty easy and localized, AFAICT. Attached is a
patch taht implements "peer" for local connections, and automatically
maps "ident" on local sockets to that (with a log message saying it
did).

If people want this to go in, I'll go over the documentation as well -
as you say, that might need some more changes, but we're not as
time-critical on that (meaning we can keep polishing it through beta).

Also, I'd like to get around to making "initdb -A ident" automatically
put "peer" for local sockets as well, which is not included in this
patch but should be a very simple change.

So. Thoughts?

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

Attachments:

peer_auth.patchtext/x-patch; charset=US-ASCII; name=peer_auth.patchDownload
*** a/src/backend/libpq/auth.c
--- b/src/backend/libpq/auth.c
***************
*** 60,66 **** static int	recv_and_check_password_packet(Port *port);
  /* Standard TCP port number for Ident service.	Assigned by IANA */
  #define IDENT_PORT 113
  
! static int	authident(hbaPort *port);
  
  
  /*----------------------------------------------------------------
--- 60,67 ----
  /* Standard TCP port number for Ident service.	Assigned by IANA */
  #define IDENT_PORT 113
  
! static int ident_inet(hbaPort *port);
! static int auth_peer(hbaPort *port);
  
  
  /*----------------------------------------------------------------
***************
*** 269,274 **** auth_failed(Port *port, int status)
--- 270,278 ----
  		case uaIdent:
  			errstr = gettext_noop("Ident authentication failed for user \"%s\"");
  			break;
+ 		case uaPeer:
+ 			errstr = gettext_noop("Peer authentication failed for user \"%s\"");
+ 			break;
  		case uaPassword:
  		case uaMD5:
  			errstr = gettext_noop("password authentication failed for user \"%s\"");
***************
*** 506,515 **** ClientAuthentication(Port *port)
  #endif
  			break;
  
! 		case uaIdent:
  
  			/*
! 			 * If we are doing ident on unix-domain sockets, use SCM_CREDS
  			 * only if it is defined and SO_PEERCRED isn't.
  			 */
  #if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && \
--- 510,519 ----
  #endif
  			break;
  
! 		case uaPeer:
  
  			/*
! 			 * If we are doing peer on unix-domain sockets, use SCM_CREDS
  			 * only if it is defined and SO_PEERCRED isn't.
  			 */
  #if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && \
***************
*** 535,541 **** ClientAuthentication(Port *port)
  				sendAuthRequest(port, AUTH_REQ_SCM_CREDS);
  			}
  #endif
! 			status = authident(port);
  			break;
  
  		case uaMD5:
--- 539,549 ----
  				sendAuthRequest(port, AUTH_REQ_SCM_CREDS);
  			}
  #endif
! 			status = auth_peer(port);
! 			break;
! 
! 		case uaIdent:
! 			status = ident_inet(port);
  			break;
  
  		case uaMD5:
***************
*** 1599,1609 **** interpret_ident_response(const char *ident_response,
   *
   *	But iff we're unable to get the information from ident, return false.
   */
! static bool
! ident_inet(const SockAddr remote_addr,
! 		   const SockAddr local_addr,
! 		   char *ident_user)
  {
  	pgsocket	sock_fd,		/* File descriptor for socket on which we talk
  								 * to Ident */
  				rc;				/* Return code from a locally called function */
--- 1607,1618 ----
   *
   *	But iff we're unable to get the information from ident, return false.
   */
! static int
! ident_inet(hbaPort *port)
  {
+ 	const		SockAddr remote_addr = port->raddr;
+ 	const		SockAddr local_addr = port->laddr;
+ 	char		ident_user[IDENT_USERNAME_MAX + 1];
  	pgsocket	sock_fd,		/* File descriptor for socket on which we talk
  								 * to Ident */
  				rc;				/* Return code from a locally called function */
***************
*** 1646,1652 **** ident_inet(const SockAddr remote_addr,
  	{
  		if (ident_serv)
  			pg_freeaddrinfo_all(hints.ai_family, ident_serv);
! 		return false;			/* we don't expect this to happen */
  	}
  
  	hints.ai_flags = AI_NUMERICHOST;
--- 1655,1661 ----
  	{
  		if (ident_serv)
  			pg_freeaddrinfo_all(hints.ai_family, ident_serv);
! 		return STATUS_ERROR;			/* we don't expect this to happen */
  	}
  
  	hints.ai_flags = AI_NUMERICHOST;
***************
*** 1662,1668 **** ident_inet(const SockAddr remote_addr,
  	{
  		if (la)
  			pg_freeaddrinfo_all(hints.ai_family, la);
! 		return false;			/* we don't expect this to happen */
  	}
  
  	sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
--- 1671,1677 ----
  	{
  		if (la)
  			pg_freeaddrinfo_all(hints.ai_family, la);
! 		return STATUS_ERROR;			/* we don't expect this to happen */
  	}
  
  	sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
***************
*** 1751,1757 **** ident_inet_done:
  		closesocket(sock_fd);
  	pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
  	pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
! 	return ident_return;
  }
  
  /*
--- 1760,1770 ----
  		closesocket(sock_fd);
  	pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
  	pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
! 
! 	if (ident_return)
! 		/* Success! Check the usermap */
! 		return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
! 	return STATUS_ERROR;
  }
  
  /*
***************
*** 1763,1771 **** ident_inet_done:
   */
  #ifdef HAVE_UNIX_SOCKETS
  
! static bool
! ident_unix(int sock, char *ident_user)
  {
  #if defined(HAVE_GETPEEREID)
  	/* OpenBSD style:  */
  	uid_t		uid;
--- 1776,1787 ----
   */
  #ifdef HAVE_UNIX_SOCKETS
  
! static int
! auth_peer(hbaPort *port)
  {
+ 	int			sock = port->sock;
+ 	char		ident_user[IDENT_USERNAME_MAX + 1];
+ 
  #if defined(HAVE_GETPEEREID)
  	/* OpenBSD style:  */
  	uid_t		uid;
***************
*** 1779,1785 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return false;
  	}
  
  	pass = getpwuid(uid);
--- 1795,1801 ----
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return STATUS_ERROR;
  	}
  
  	pass = getpwuid(uid);
***************
*** 1789,1800 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) uid)));
! 		return false;
  	}
  
  	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
  
- 	return true;
  #elif defined(SO_PEERCRED)
  	/* Linux style: use getsockopt(SO_PEERCRED) */
  	struct ucred peercred;
--- 1805,1815 ----
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) uid)));
! 		return STATUS_ERROR;
  	}
  
  	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
  
  #elif defined(SO_PEERCRED)
  	/* Linux style: use getsockopt(SO_PEERCRED) */
  	struct ucred peercred;
***************
*** 1809,1815 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return false;
  	}
  
  	pass = getpwuid(peercred.uid);
--- 1824,1830 ----
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return STATUS_ERROR;
  	}
  
  	pass = getpwuid(peercred.uid);
***************
*** 1819,1830 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) peercred.uid)));
! 		return false;
  	}
  
  	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
  
- 	return true;
  #elif defined(HAVE_GETPEERUCRED)
  	/* Solaris > 10 */
  	uid_t		uid;
--- 1834,1844 ----
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) peercred.uid)));
! 		return STATUS_ERROR;
  	}
  
  	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
  
  #elif defined(HAVE_GETPEERUCRED)
  	/* Solaris > 10 */
  	uid_t		uid;
***************
*** 1837,1843 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return false;
  	}
  
  	if ((uid = ucred_geteuid(ucred)) == -1)
--- 1851,1857 ----
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return STATUS_ERROR;
  	}
  
  	if ((uid = ucred_geteuid(ucred)) == -1)
***************
*** 1845,1851 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errcode_for_socket_access(),
  		   errmsg("could not get effective UID from peer credentials: %m")));
! 		return false;
  	}
  
  	ucred_free(ucred);
--- 1859,1865 ----
  		ereport(LOG,
  				(errcode_for_socket_access(),
  		   errmsg("could not get effective UID from peer credentials: %m")));
! 		return STATUS_ERROR;
  	}
  
  	ucred_free(ucred);
***************
*** 1856,1867 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) uid)));
! 		return false;
  	}
  
  	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
  
- 	return true;
  #elif defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS))
  	struct msghdr msg;
  
--- 1870,1880 ----
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) uid)));
! 		return STATUS_ERROR;
  	}
  
  	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
  
  #elif defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS))
  	struct msghdr msg;
  
***************
*** 1913,1919 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return false;
  	}
  
  	cred = (Cred *) CMSG_DATA(cmsg);
--- 1926,1932 ----
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return STATUS_ERROR;
  	}
  
  	cred = (Cred *) CMSG_DATA(cmsg);
***************
*** 1925,1983 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) cred->cruid)));
! 		return false;
  	}
  
  	strlcpy(ident_user, pw->pw_name, IDENT_USERNAME_MAX + 1);
  
- 	return true;
  #else
  	ereport(LOG,
  			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  			 errmsg("Ident authentication is not supported on local connections on this platform")));
  
! 	return false;
! #endif
! }
! #endif   /* HAVE_UNIX_SOCKETS */
! 
! 
! /*
!  *	Determine the username of the initiator of the connection described
!  *	by "port".	Then look in the usermap file under the usermap
!  *	port->hba->usermap and see if that user is equivalent to Postgres user
!  *	port->user.
!  *
!  *	Return STATUS_OK if yes, STATUS_ERROR if no match (or couldn't get info).
!  */
! static int
! authident(hbaPort *port)
! {
! 	char		ident_user[IDENT_USERNAME_MAX + 1];
! 
! 	switch (port->raddr.addr.ss_family)
! 	{
! 		case AF_INET:
! #ifdef	HAVE_IPV6
! 		case AF_INET6:
! #endif
! 			if (!ident_inet(port->raddr, port->laddr, ident_user))
! 				return STATUS_ERROR;
! 			break;
! 
! #ifdef HAVE_UNIX_SOCKETS
! 		case AF_UNIX:
! 			if (!ident_unix(port->sock, ident_user))
! 				return STATUS_ERROR;
! 			break;
  #endif
  
- 		default:
- 			return STATUS_ERROR;
- 	}
- 
  	return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
  }
  
  
  /*----------------------------------------------------------------
--- 1938,1959 ----
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) cred->cruid)));
! 		return STATUS_ERROR;
  	}
  
  	strlcpy(ident_user, pw->pw_name, IDENT_USERNAME_MAX + 1);
  
  #else
  	ereport(LOG,
  			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  			 errmsg("Ident authentication is not supported on local connections on this platform")));
  
! 	return STATUS_ERROR;
  #endif
  
  	return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
  }
+ #endif   /* HAVE_UNIX_SOCKETS */
  
  
  /*----------------------------------------------------------------
*** a/src/backend/libpq/hba.c
--- b/src/backend/libpq/hba.c
***************
*** 1060,1065 **** parse_hba_line(List *line, int line_num, HbaLine *parsedline)
--- 1060,1067 ----
  		parsedline->auth_method = uaTrust;
  	else if (strcmp(token, "ident") == 0)
  		parsedline->auth_method = uaIdent;
+ 	else if (strcmp(token, "peer") == 0)
+ 		parsedline->auth_method = uaPeer;
  	else if (strcmp(token, "password") == 0)
  		parsedline->auth_method = uaPassword;
  	else if (strcmp(token, "krb5") == 0)
***************
*** 1137,1142 **** parse_hba_line(List *line, int line_num, HbaLine *parsedline)
--- 1139,1158 ----
  		return false;
  	}
  
+ 	/*
+ 	 * XXX: When using ident on local connections, change it to peer,
+ 	 * for backwards compatibility.
+ 	 */
+ 	if (parsedline->conntype == ctLocal &&
+ 		parsedline->auth_method == uaIdent)
+ 	{
+ 		ereport(LOG,
+ 				(errmsg("\"ident\" authentication on local socket automatically changed to \"peer\""),
+ 				 errcontext("line %d of configuration file \"%s\"",
+ 							line_num, HbaFileName)));
+ 		parsedline->auth_method = uaPeer;
+ 	}
+ 
  	/* Invalid authentication combinations */
  	if (parsedline->conntype == ctLocal &&
  		parsedline->auth_method == uaKrb5)
***************
*** 1160,1165 **** parse_hba_line(List *line, int line_num, HbaLine *parsedline)
--- 1176,1192 ----
  		return false;
  	}
  
+ 	if (parsedline->conntype != ctLocal &&
+ 		parsedline->auth_method == uaPeer)
+ 	{
+ 		ereport(LOG,
+ 				(errcode(ERRCODE_CONFIG_FILE_ERROR),
+ 				 errmsg("peer authentication is only supported on local sockets"),
+ 				 errcontext("line %d of configuration file \"%s\"",
+ 							line_num, HbaFileName)));
+ 		return false;
+ 	}
+ 
  	/*
  	 * SSPI authentication can never be enabled on ctLocal connections,
  	 * because it's only supported on Windows, where ctLocal isn't supported.
***************
*** 1203,1213 **** parse_hba_line(List *line, int line_num, HbaLine *parsedline)
  			if (strcmp(token, "map") == 0)
  			{
  				if (parsedline->auth_method != uaIdent &&
  					parsedline->auth_method != uaKrb5 &&
  					parsedline->auth_method != uaGSS &&
  					parsedline->auth_method != uaSSPI &&
  					parsedline->auth_method != uaCert)
! 					INVALID_AUTH_OPTION("map", gettext_noop("ident, krb5, gssapi, sspi and cert"));
  				parsedline->usermap = pstrdup(c);
  			}
  			else if (strcmp(token, "clientcert") == 0)
--- 1230,1241 ----
  			if (strcmp(token, "map") == 0)
  			{
  				if (parsedline->auth_method != uaIdent &&
+ 					parsedline->auth_method != uaPeer &&
  					parsedline->auth_method != uaKrb5 &&
  					parsedline->auth_method != uaGSS &&
  					parsedline->auth_method != uaSSPI &&
  					parsedline->auth_method != uaCert)
! 					INVALID_AUTH_OPTION("map", gettext_noop("ident, peer, krb5, gssapi, sspi and cert"));
  				parsedline->usermap = pstrdup(c);
  			}
  			else if (strcmp(token, "clientcert") == 0)
*** a/src/backend/libpq/pg_hba.conf.sample
--- b/src/backend/libpq/pg_hba.conf.sample
***************
*** 41,47 ****
  # directly connected to.
  #
  # METHOD can be "trust", "reject", "md5", "password", "gss", "sspi",
! # "krb5", "ident", "pam", "ldap", "radius" or "cert".  Note that
  # "password" sends passwords in clear text; "md5" is preferred since
  # it sends encrypted passwords.
  #
--- 41,47 ----
  # directly connected to.
  #
  # METHOD can be "trust", "reject", "md5", "password", "gss", "sspi",
! # "krb5", "ident", "peer", "pam", "ldap", "radius" or "cert".  Note that
  # "password" sends passwords in clear text; "md5" is preferred since
  # it sends encrypted passwords.
  #
*** a/src/include/libpq/hba.h
--- b/src/include/libpq/hba.h
***************
*** 29,35 **** typedef enum UserAuth
  	uaPAM,
  	uaLDAP,
  	uaCert,
! 	uaRADIUS
  } UserAuth;
  
  typedef enum IPCompareMethod
--- 29,36 ----
  	uaPAM,
  	uaLDAP,
  	uaCert,
! 	uaRADIUS,
! 	uaPeer
  } UserAuth;
  
  typedef enum IPCompareMethod
#29Robert Haas
robertmhaas@gmail.com
In reply to: Magnus Hagander (#28)
Re: Indent authentication overloading

On Mon, Mar 14, 2011 at 5:18 AM, Magnus Hagander <magnus@hagander.net> wrote:

On Fri, Mar 11, 2011 at 15:36, Peter Eisentraut <peter_e@gmx.net> wrote:

On tor, 2011-03-10 at 22:45 +0100, Magnus Hagander wrote:

On Thu, Mar 10, 2011 at 22:22, Bruce Momjian <bruce@momjian.us> wrote:

Added to TODO:

       Rename unix domain socket 'ident' connections to 'peer', to avoid
       confusion with TCP 'ident'

Should we consider adding "peer" as an alias for "ident" already in
9.1 (and change the default pg_hba.conf template), and then deprecate
ident for 9.2 and remove it in 9.3 or something? By adding the alias
now (yes, I know it's not in the last CF :P), we can move what's going
to be a long process up one release...

Might as well, if you can get it done soon.  The documentation might
need more extensive adjustments.

The code itself is pretty easy and localized, AFAICT. Attached is a
patch taht implements "peer" for local connections, and automatically
maps "ident" on local sockets to that (with a log message saying it
did).

If people want this to go in, I'll go over the documentation as well -
as you say, that might need some more changes, but we're not as
time-critical on that (meaning we can keep polishing it through beta).

Also, I'd like to get around to making "initdb -A ident" automatically
put "peer" for local sockets as well, which is not included in this
patch but should be a very simple change.

So. Thoughts?

The log message is an absolute non-starter. You're going to get that
on every backend startup on Windows, I believe.

Also, the text is not accurate: nothing has been automatically changed
to anything. The pg_hba.conf file is just as it was. You could say
something like "ident" authentication on local socket treated as
"peer", but I think a better idea would be to just remove this message
altogether. I see zero reason to force someone who has a pg_hba.conf
file that they have been using for years and are happy with to make
trivial changes to it on our account, and I'd be perfectly happy to
silently treat ident on a local socket as peer forever, while gently
encouraging the use of the newer term in our documentation.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#30Magnus Hagander
magnus@hagander.net
In reply to: Robert Haas (#29)
Re: Indent authentication overloading

On Mon, Mar 14, 2011 at 14:43, Robert Haas <robertmhaas@gmail.com> wrote:

On Mon, Mar 14, 2011 at 5:18 AM, Magnus Hagander <magnus@hagander.net> wrote:

On Fri, Mar 11, 2011 at 15:36, Peter Eisentraut <peter_e@gmx.net> wrote:

On tor, 2011-03-10 at 22:45 +0100, Magnus Hagander wrote:

On Thu, Mar 10, 2011 at 22:22, Bruce Momjian <bruce@momjian.us> wrote:

Added to TODO:

       Rename unix domain socket 'ident' connections to 'peer', to avoid
       confusion with TCP 'ident'

Should we consider adding "peer" as an alias for "ident" already in
9.1 (and change the default pg_hba.conf template), and then deprecate
ident for 9.2 and remove it in 9.3 or something? By adding the alias
now (yes, I know it's not in the last CF :P), we can move what's going
to be a long process up one release...

Might as well, if you can get it done soon.  The documentation might
need more extensive adjustments.

The code itself is pretty easy and localized, AFAICT. Attached is a
patch taht implements "peer" for local connections, and automatically
maps "ident" on local sockets to that (with a log message saying it
did).

If people want this to go in, I'll go over the documentation as well -
as you say, that might need some more changes, but we're not as
time-critical on that (meaning we can keep polishing it through beta).

Also, I'd like to get around to making "initdb -A ident" automatically
put "peer" for local sockets as well, which is not included in this
patch but should be a very simple change.

So. Thoughts?

The log message is an absolute non-starter.  You're going to get that
on every backend startup on Windows, I believe.

No, you're not. Because we don't do unix sockets on windows, for
obvious reasons.

You *would* get it on all RPM based installations, or DEB based
installations, on *unix*, unless the patch to initdb is done (which it
is now actually, just wasn't when I posted)

That said, it can easily be removed.

Also, the text is not accurate: nothing has been automatically changed
to anything.  The pg_hba.conf file is just as it was.  You could say
something like "ident" authentication on local socket treated as
"peer", but I think a better idea would be to just remove this message
altogether.  I see zero reason to force someone who has a pg_hba.conf
file that they have been using for years and are happy with to make
trivial changes to it on our account, and I'd be perfectly happy to
silently treat ident on a local socket as peer forever, while gently
encouraging the use of the newer term in our documentation.

The idea being to let people know it's been deprecated, nothing else.
But sure, we can just remove the message - at elast for now, and maybe
add it $n releases down the road when people are expected to have
changed over.

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

#31Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#30)
Re: Indent authentication overloading

Magnus Hagander <magnus@hagander.net> writes:

On Mon, Mar 14, 2011 at 14:43, Robert Haas <robertmhaas@gmail.com> wrote:

Also, the text is not accurate: nothing has been automatically changed
to anything. �The pg_hba.conf file is just as it was. �You could say
something like "ident" authentication on local socket treated as
"peer", but I think a better idea would be to just remove this message
altogether.

The idea being to let people know it's been deprecated, nothing else.
But sure, we can just remove the message - at elast for now, and maybe
add it $n releases down the road when people are expected to have
changed over.

I'm with Robert on this one --- the first reaction I had to your
description of the patch was "why do we need a log message for that?"
If there were some real reason to push people away from use of the
non-preferred term, maybe it'd be worth nagging them to change; but
there isn't.

regards, tom lane

#32Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#31)
Re: Indent authentication overloading

On Mon, Mar 14, 2011 at 16:17, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Magnus Hagander <magnus@hagander.net> writes:

On Mon, Mar 14, 2011 at 14:43, Robert Haas <robertmhaas@gmail.com> wrote:

Also, the text is not accurate: nothing has been automatically changed
to anything.  The pg_hba.conf file is just as it was.  You could say
something like "ident" authentication on local socket treated as
"peer", but I think a better idea would be to just remove this message
altogether.

The idea being to let people know it's been deprecated, nothing else.
But sure, we can just remove the message - at elast for now, and maybe
add it $n releases down the road when people are expected to have
changed over.

I'm with Robert on this one --- the first reaction I had to your
description of the patch was "why do we need a log message for that?"
If there were some real reason to push people away from use of the
non-preferred term, maybe it'd be worth nagging them to change; but
there isn't.

Ok. fair enough, I'll take that part out.

Are people in general in favor of making the change provided I do that, then?

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

#33Magnus Hagander
magnus@hagander.net
In reply to: Magnus Hagander (#32)
1 attachment(s)
Re: Indent authentication overloading

On Mon, Mar 14, 2011 at 16:26, Magnus Hagander <magnus@hagander.net> wrote:

On Mon, Mar 14, 2011 at 16:17, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Magnus Hagander <magnus@hagander.net> writes:

On Mon, Mar 14, 2011 at 14:43, Robert Haas <robertmhaas@gmail.com> wrote:

Also, the text is not accurate: nothing has been automatically changed
to anything.  The pg_hba.conf file is just as it was.  You could say
something like "ident" authentication on local socket treated as
"peer", but I think a better idea would be to just remove this message
altogether.

The idea being to let people know it's been deprecated, nothing else.
But sure, we can just remove the message - at elast for now, and maybe
add it $n releases down the road when people are expected to have
changed over.

I'm with Robert on this one --- the first reaction I had to your
description of the patch was "why do we need a log message for that?"
If there were some real reason to push people away from use of the
non-preferred term, maybe it'd be worth nagging them to change; but
there isn't.

Ok. fair enough, I'll take that part out.

Here's an updated patch that removes this log message, and adds a few
lines to initdb to create a combination of ident/peer rows. And
finally, adds docs.

Are people in general in favor of making the change provided I do that, then?

Comments?

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

Attachments:

ident2peer.patchtext/x-patch; charset=US-ASCII; name=ident2peer.patchDownload
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml
index c05805b..3f4631e 100644
--- a/doc/src/sgml/client-auth.sgml
+++ b/doc/src/sgml/client-auth.sgml
@@ -457,17 +457,28 @@ hostnossl  <replaceable>database</replaceable>  <replaceable>user</replaceable>
         <term><literal>ident</></term>
         <listitem>
          <para>
-          Obtain the operating system user name of the client (for
-          TCP/IP connections by contacting the ident server on the
-          client, for local connections by getting it from the
-          operating system) and check if it matches the requested
-          database user name.
+          Obtain the operating system user name of the client
+          by contacting the ident server on the client
+          and check if it matches the requested database user name.
+          This is only available for TCP/IP connections.
           See <xref linkend="auth-ident"> for details.
          </para>
         </listitem>
        </varlistentry>
 
        <varlistentry>
+        <term><literal>peer</></term>
+        <listitem>
+         <para>
+          Obtain the operating system user name from the operating system
+          and check if it matches the requested database user name.
+          This is only available for local connections.
+          See <xref linkend="auth-peer"> for details.
+         </para>
+        </listitem>
+       </varlistentry>
+
+       <varlistentry>
         <term><literal>ldap</></term>
         <listitem>
          <para>
@@ -1200,7 +1211,7 @@ omicron         bryanh                  guest1
   </sect2>
 
   <sect2 id="auth-ident">
-   <title>Ident-based Authentication</title>
+   <title>Ident Authentication</title>
 
    <indexterm>
     <primary>ident</primary>
@@ -1208,11 +1219,9 @@ omicron         bryanh                  guest1
 
    <para>
     The ident authentication method works by obtaining the client's
-    operating system user name and using it as the allowed database user
-    name (with an optional user name mapping).
-    The determination of the client's
-    user name is the security-critical point, and it works differently
-    depending on the connection type, as described below.
+    operating system user name from an ident server and using it as
+    the allowed database user name (with an optional user name mapping).
+    This is only supported on TCP/IP connections.
    </para>
 
    <para>
@@ -1230,9 +1239,6 @@ omicron         bryanh                  guest1
     </variablelist>
    </para>
 
-   <sect3>
-    <title>Ident Authentication Over TCP/IP</title>
-
    <para>
     The <quote>Identification Protocol</quote> is described in
     RFC 1413. Virtually every Unix-like
@@ -1275,36 +1281,48 @@ omicron         bryanh                  guest1
     since <productname>PostgreSQL</> does not have any way to decrypt the
     returned string to determine the actual user name.
    </para>
-   </sect3>
+  </sect2>
+
+  <sect2 id="auth-peer">
+   <title>Peer Authentication</title>
+
+   <indexterm>
+    <primary>peer</primary>
+   </indexterm>
+
+   <para>
+    The peer authentication method works by obtaining the client's
+    operating system user name from the kernel and using it as the
+    allowed database user name (with optional user name mapping). This
+    is only supported on local connections.
+   </para>
 
-   <sect3>
-    <title>Ident Authentication Over Local Sockets</title>
+   <para>
+    The following configuration options are supported for <productname>peer</productname>:
+    <variablelist>
+     <varlistentry>
+      <term><literal>map</literal></term>
+      <listitem>
+       <para>
+        Allows for mapping between system and database user names. See
+        <xref linkend="auth-username-maps"> for details.
+       </para>
+      </listitem>
+     </varlistentry>
+    </variablelist>
+   </para>
 
    <para>
-    On systems supporting <symbol>SO_PEERCRED</symbol> requests for
+    Peer authentication is only available on  systems supporting
+    <symbol>SO_PEERCRED</symbol> requests for
     Unix-domain sockets (currently <systemitem
     class="osname">Linux</>, <systemitem class="osname">FreeBSD</>,
     <systemitem class="osname">NetBSD</>, <systemitem class="osname">OpenBSD</>,
-    <systemitem class="osname">BSD/OS</>, and <systemitem class="osname">Solaris</systemitem>), ident authentication can also
-    be applied to local connections.
+    <systemitem class="osname">BSD/OS</>, and <systemitem class="osname">Solaris</systemitem>).
     <productname>PostgreSQL</> uses <symbol>SO_PEERCRED</symbol> to find out
     the operating system name of the connected client process.
-    In this case, no security risk is added by
-    using ident authentication; indeed it is a preferable choice for
-    local connections on such systems.
    </para>
 
-    <para>
-     On systems without <symbol>SO_PEERCRED</> requests, ident
-     authentication is only available for TCP/IP connections. As a
-     work-around, it is possible to specify the <systemitem
-     class="systemname">localhost</> address <systemitem
-     class="systemname">127.0.0.1</> and make connections to this
-     address.  This method is trustworthy to the extent that you trust
-     the local ident server.
-    </para>
-    </sect3>
-
   </sect2>
 
   <sect2 id="auth-ldap">
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index f776737..b5ad101 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -148,7 +148,7 @@ postgres$ <userinput>initdb -D /usr/local/pgsql/data</userinput>
    mode is not used; or modify the generated <filename>pg_hba.conf</filename>
    file after running <command>initdb</command>, but
    <emphasis>before</> you start the server for the first time. (Other
-   reasonable approaches include using <literal>ident</literal> authentication
+   reasonable approaches include using <literal>peer</literal> authentication
    or file system permissions to restrict connections. See <xref
    linkend="client-authentication"> for more information.)
   </para>
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index af43c2a..bc8e4ca 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -60,7 +60,8 @@ static int	recv_and_check_password_packet(Port *port);
 /* Standard TCP port number for Ident service.	Assigned by IANA */
 #define IDENT_PORT 113
 
-static int	authident(hbaPort *port);
+static int	ident_inet(hbaPort *port);
+static int	auth_peer(hbaPort *port);
 
 
 /*----------------------------------------------------------------
@@ -269,6 +270,9 @@ auth_failed(Port *port, int status)
 		case uaIdent:
 			errstr = gettext_noop("Ident authentication failed for user \"%s\"");
 			break;
+		case uaPeer:
+			errstr = gettext_noop("Peer authentication failed for user \"%s\"");
+			break;
 		case uaPassword:
 		case uaMD5:
 			errstr = gettext_noop("password authentication failed for user \"%s\"");
@@ -506,11 +510,11 @@ ClientAuthentication(Port *port)
 #endif
 			break;
 
-		case uaIdent:
+		case uaPeer:
 
 			/*
-			 * If we are doing ident on unix-domain sockets, use SCM_CREDS
-			 * only if it is defined and SO_PEERCRED isn't.
+			 * If we are doing peer on unix-domain sockets, use SCM_CREDS only
+			 * if it is defined and SO_PEERCRED isn't.
 			 */
 #if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && \
 	(defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || \
@@ -535,7 +539,11 @@ ClientAuthentication(Port *port)
 				sendAuthRequest(port, AUTH_REQ_SCM_CREDS);
 			}
 #endif
-			status = authident(port);
+			status = auth_peer(port);
+			break;
+
+		case uaIdent:
+			status = ident_inet(port);
 			break;
 
 		case uaMD5:
@@ -1599,11 +1607,12 @@ interpret_ident_response(const char *ident_response,
  *
  *	But iff we're unable to get the information from ident, return false.
  */
-static bool
-ident_inet(const SockAddr remote_addr,
-		   const SockAddr local_addr,
-		   char *ident_user)
+static int
+ident_inet(hbaPort *port)
 {
+	const SockAddr remote_addr = port->raddr;
+	const SockAddr local_addr = port->laddr;
+	char		ident_user[IDENT_USERNAME_MAX + 1];
 	pgsocket	sock_fd,		/* File descriptor for socket on which we talk
 								 * to Ident */
 				rc;				/* Return code from a locally called function */
@@ -1646,7 +1655,7 @@ ident_inet(const SockAddr remote_addr,
 	{
 		if (ident_serv)
 			pg_freeaddrinfo_all(hints.ai_family, ident_serv);
-		return false;			/* we don't expect this to happen */
+		return STATUS_ERROR;	/* we don't expect this to happen */
 	}
 
 	hints.ai_flags = AI_NUMERICHOST;
@@ -1662,7 +1671,7 @@ ident_inet(const SockAddr remote_addr,
 	{
 		if (la)
 			pg_freeaddrinfo_all(hints.ai_family, la);
-		return false;			/* we don't expect this to happen */
+		return STATUS_ERROR;	/* we don't expect this to happen */
 	}
 
 	sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
@@ -1751,7 +1760,11 @@ ident_inet_done:
 		closesocket(sock_fd);
 	pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
 	pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
-	return ident_return;
+
+	if (ident_return)
+		/* Success! Check the usermap */
+		return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
+	return STATUS_ERROR;
 }
 
 /*
@@ -1763,9 +1776,12 @@ ident_inet_done:
  */
 #ifdef HAVE_UNIX_SOCKETS
 
-static bool
-ident_unix(int sock, char *ident_user)
+static int
+auth_peer(hbaPort *port)
 {
+	int			sock = port->sock;
+	char		ident_user[IDENT_USERNAME_MAX + 1];
+
 #if defined(HAVE_GETPEEREID)
 	/* OpenBSD style:  */
 	uid_t		uid;
@@ -1779,7 +1795,7 @@ ident_unix(int sock, char *ident_user)
 		ereport(LOG,
 				(errcode_for_socket_access(),
 				 errmsg("could not get peer credentials: %m")));
-		return false;
+		return STATUS_ERROR;
 	}
 
 	pass = getpwuid(uid);
@@ -1789,12 +1805,11 @@ ident_unix(int sock, char *ident_user)
 		ereport(LOG,
 				(errmsg("local user with ID %d does not exist",
 						(int) uid)));
-		return false;
+		return STATUS_ERROR;
 	}
 
 	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
 
-	return true;
 #elif defined(SO_PEERCRED)
 	/* Linux style: use getsockopt(SO_PEERCRED) */
 	struct ucred peercred;
@@ -1809,7 +1824,7 @@ ident_unix(int sock, char *ident_user)
 		ereport(LOG,
 				(errcode_for_socket_access(),
 				 errmsg("could not get peer credentials: %m")));
-		return false;
+		return STATUS_ERROR;
 	}
 
 	pass = getpwuid(peercred.uid);
@@ -1819,12 +1834,11 @@ ident_unix(int sock, char *ident_user)
 		ereport(LOG,
 				(errmsg("local user with ID %d does not exist",
 						(int) peercred.uid)));
-		return false;
+		return STATUS_ERROR;
 	}
 
 	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
 
-	return true;
 #elif defined(HAVE_GETPEERUCRED)
 	/* Solaris > 10 */
 	uid_t		uid;
@@ -1837,7 +1851,7 @@ ident_unix(int sock, char *ident_user)
 		ereport(LOG,
 				(errcode_for_socket_access(),
 				 errmsg("could not get peer credentials: %m")));
-		return false;
+		return STATUS_ERROR;
 	}
 
 	if ((uid = ucred_geteuid(ucred)) == -1)
@@ -1845,7 +1859,7 @@ ident_unix(int sock, char *ident_user)
 		ereport(LOG,
 				(errcode_for_socket_access(),
 		   errmsg("could not get effective UID from peer credentials: %m")));
-		return false;
+		return STATUS_ERROR;
 	}
 
 	ucred_free(ucred);
@@ -1856,12 +1870,11 @@ ident_unix(int sock, char *ident_user)
 		ereport(LOG,
 				(errmsg("local user with ID %d does not exist",
 						(int) uid)));
-		return false;
+		return STATUS_ERROR;
 	}
 
 	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
 
-	return true;
 #elif defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS))
 	struct msghdr msg;
 
@@ -1913,7 +1926,7 @@ ident_unix(int sock, char *ident_user)
 		ereport(LOG,
 				(errcode_for_socket_access(),
 				 errmsg("could not get peer credentials: %m")));
-		return false;
+		return STATUS_ERROR;
 	}
 
 	cred = (Cred *) CMSG_DATA(cmsg);
@@ -1925,59 +1938,22 @@ ident_unix(int sock, char *ident_user)
 		ereport(LOG,
 				(errmsg("local user with ID %d does not exist",
 						(int) cred->cruid)));
-		return false;
+		return STATUS_ERROR;
 	}
 
 	strlcpy(ident_user, pw->pw_name, IDENT_USERNAME_MAX + 1);
 
-	return true;
 #else
 	ereport(LOG,
 			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 			 errmsg("Ident authentication is not supported on local connections on this platform")));
 
-	return false;
-#endif
-}
-#endif   /* HAVE_UNIX_SOCKETS */
-
-
-/*
- *	Determine the username of the initiator of the connection described
- *	by "port".	Then look in the usermap file under the usermap
- *	port->hba->usermap and see if that user is equivalent to Postgres user
- *	port->user.
- *
- *	Return STATUS_OK if yes, STATUS_ERROR if no match (or couldn't get info).
- */
-static int
-authident(hbaPort *port)
-{
-	char		ident_user[IDENT_USERNAME_MAX + 1];
-
-	switch (port->raddr.addr.ss_family)
-	{
-		case AF_INET:
-#ifdef	HAVE_IPV6
-		case AF_INET6:
-#endif
-			if (!ident_inet(port->raddr, port->laddr, ident_user))
-				return STATUS_ERROR;
-			break;
-
-#ifdef HAVE_UNIX_SOCKETS
-		case AF_UNIX:
-			if (!ident_unix(port->sock, ident_user))
-				return STATUS_ERROR;
-			break;
+	return STATUS_ERROR;
 #endif
 
-		default:
-			return STATUS_ERROR;
-	}
-
 	return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
 }
+#endif   /* HAVE_UNIX_SOCKETS */
 
 
 /*----------------------------------------------------------------
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 1b3a714..2def6ce 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -1060,6 +1060,8 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
 		parsedline->auth_method = uaTrust;
 	else if (strcmp(token, "ident") == 0)
 		parsedline->auth_method = uaIdent;
+	else if (strcmp(token, "peer") == 0)
+		parsedline->auth_method = uaPeer;
 	else if (strcmp(token, "password") == 0)
 		parsedline->auth_method = uaPassword;
 	else if (strcmp(token, "krb5") == 0)
@@ -1137,6 +1139,14 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
 		return false;
 	}
 
+	/*
+	 * XXX: When using ident on local connections, change it to peer, for
+	 * backwards compatibility.
+	 */
+	if (parsedline->conntype == ctLocal &&
+		parsedline->auth_method == uaIdent)
+		parsedline->auth_method = uaPeer;
+
 	/* Invalid authentication combinations */
 	if (parsedline->conntype == ctLocal &&
 		parsedline->auth_method == uaKrb5)
@@ -1160,6 +1170,17 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
 		return false;
 	}
 
+	if (parsedline->conntype != ctLocal &&
+		parsedline->auth_method == uaPeer)
+	{
+		ereport(LOG,
+				(errcode(ERRCODE_CONFIG_FILE_ERROR),
+			errmsg("peer authentication is only supported on local sockets"),
+				 errcontext("line %d of configuration file \"%s\"",
+							line_num, HbaFileName)));
+		return false;
+	}
+
 	/*
 	 * SSPI authentication can never be enabled on ctLocal connections,
 	 * because it's only supported on Windows, where ctLocal isn't supported.
@@ -1203,11 +1224,12 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
 			if (strcmp(token, "map") == 0)
 			{
 				if (parsedline->auth_method != uaIdent &&
+					parsedline->auth_method != uaPeer &&
 					parsedline->auth_method != uaKrb5 &&
 					parsedline->auth_method != uaGSS &&
 					parsedline->auth_method != uaSSPI &&
 					parsedline->auth_method != uaCert)
-					INVALID_AUTH_OPTION("map", gettext_noop("ident, krb5, gssapi, sspi and cert"));
+					INVALID_AUTH_OPTION("map", gettext_noop("ident, peer, krb5, gssapi, sspi and cert"));
 				parsedline->usermap = pstrdup(c);
 			}
 			else if (strcmp(token, "clientcert") == 0)
diff --git a/src/backend/libpq/pg_hba.conf.sample b/src/backend/libpq/pg_hba.conf.sample
index 87f8499..0a90b68 100644
--- a/src/backend/libpq/pg_hba.conf.sample
+++ b/src/backend/libpq/pg_hba.conf.sample
@@ -41,7 +41,7 @@
 # directly connected to.
 #
 # METHOD can be "trust", "reject", "md5", "password", "gss", "sspi",
-# "krb5", "ident", "pam", "ldap", "radius" or "cert".  Note that
+# "krb5", "ident", "peer", "pam", "ldap", "radius" or "cert".  Note that
 # "password" sends passwords in clear text; "md5" is preferred since
 # it sends encrypted passwords.
 #
@@ -75,7 +75,7 @@
 # TYPE  DATABASE        USER            ADDRESS                 METHOD
 
 @remove-line-for-nolocal@# "local" is for Unix domain socket connections only
-@remove-line-for-nolocal@local   all             all                                     @authmethod@
+@remove-line-for-nolocal@local   all             all                                     @authmethodlocal@
 # IPv4 local connections:
 host    all             all             127.0.0.1/32            @authmethod@
 # IPv6 local connections:
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 7a4b698..d509b13 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -82,6 +82,7 @@ static char *username = "";
 static bool pwprompt = false;
 static char *pwfilename = NULL;
 static char *authmethod = "";
+static char *authmethodlocal = "";
 static bool debug = false;
 static bool noclean = false;
 static bool show_setting = false;
@@ -1076,6 +1077,9 @@ setup_config(void)
 	conflines = replace_token(conflines,
 							  "@authmethod@",
 							  authmethod);
+	conflines = replace_token(conflines,
+							  "@authmethodlocal@",
+							  authmethodlocal);
 
 	conflines = replace_token(conflines,
 							  "@authcomment@",
@@ -2637,6 +2641,7 @@ main(int argc, char *argv[])
 	}
 
 	if (strcmp(authmethod, "md5") &&
+		strcmp(authmethod, "peer") &&
 		strcmp(authmethod, "ident") &&
 		strcmp(authmethod, "trust") &&
 #ifdef USE_PAM
@@ -2666,6 +2671,20 @@ main(int argc, char *argv[])
 		exit(1);
 	}
 
+	/*
+	 * When ident is specified, use peer for local connections. Mirrored, when
+	 * peer is specified, use ident for TCP connections.
+	 */
+	if (strcmp(authmethod, "ident") == 0)
+		authmethodlocal = "peer";
+	else if (strcmp(authmethod, "peer") == 0)
+	{
+		authmethodlocal = "peer";
+		authmethod = "ident";
+	}
+	else
+		authmethodlocal = authmethod;
+
 	if (strlen(pg_data) == 0)
 	{
 		pgdenv = getenv("PGDATA");
diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h
index aa60d8d..b92dc0d 100644
--- a/src/include/libpq/hba.h
+++ b/src/include/libpq/hba.h
@@ -29,7 +29,8 @@ typedef enum UserAuth
 	uaPAM,
 	uaLDAP,
 	uaCert,
-	uaRADIUS
+	uaRADIUS,
+	uaPeer
 } UserAuth;
 
 typedef enum IPCompareMethod
#34Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#33)
Re: Indent authentication overloading

Magnus Hagander <magnus@hagander.net> writes:

Here's an updated patch that removes this log message, and adds a few
lines to initdb to create a combination of ident/peer rows. And
finally, adds docs.

Comments?

As near as I can tell (I hate reading u-style diffs) you've documented
the ident and peer keywords as being mutually exclusive, ie, the docs
say that the correct keyword for the connection type *must* be used in
pg_hba.conf. Which is not how the code behaves, and shouldn't be how
the code behaves, for backwards-compatibility reasons. The docs need
to state the truth, namely that "ident" is still allowed as a synonym
for "peer" on local connections. Otherwise people will get confused
as to why their pg_hba files still work.

The code changes look sane in a quick scan, though I didn't read them
in detail.

regards, tom lane

#35Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#34)
1 attachment(s)
Re: Indent authentication overloading

On Sat, Mar 19, 2011 at 16:24, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Magnus Hagander <magnus@hagander.net> writes:

Here's an updated patch that removes this log message, and adds a few
lines to initdb to create a combination of ident/peer rows. And
finally, adds docs.

Comments?

As near as I can tell (I hate reading u-style diffs) you've documented

Ah, apologies. I made a -c diff, found a typo, remade it as -u.. pfft.

the ident and peer keywords as being mutually exclusive, ie, the docs
say that the correct keyword for the connection type *must* be used in
pg_hba.conf.  Which is not how the code behaves, and shouldn't be how
the code behaves, for backwards-compatibility reasons.  The docs need
to state the truth, namely that "ident" is still allowed as a synonym
for "peer" on local connections.  Otherwise people will get confused
as to why their pg_hba files still work.

Hmm: Good point, update attached.

The code changes look sane in a quick scan, though I didn't read them
in detail.

Thx.

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

Attachments:

ident2peer.patchtext/x-patch; charset=US-ASCII; name=ident2peer.patchDownload
*** a/doc/src/sgml/client-auth.sgml
--- b/doc/src/sgml/client-auth.sgml
***************
*** 457,473 **** hostnossl  <replaceable>database</replaceable>  <replaceable>user</replaceable>
          <term><literal>ident</></term>
          <listitem>
           <para>
!           Obtain the operating system user name of the client (for
!           TCP/IP connections by contacting the ident server on the
!           client, for local connections by getting it from the
!           operating system) and check if it matches the requested
!           database user name.
            See <xref linkend="auth-ident"> for details.
           </para>
          </listitem>
         </varlistentry>
  
         <varlistentry>
          <term><literal>ldap</></term>
          <listitem>
           <para>
--- 457,486 ----
          <term><literal>ident</></term>
          <listitem>
           <para>
!           Obtain the operating system user name of the client
!           by contacting the ident server on the client
!           and check if it matches the requested database user name.
!           Ident authentication can only be used on TCP/IP
!           connections. When specified for local connections, peer
!           authentication will be used instead.
            See <xref linkend="auth-ident"> for details.
           </para>
          </listitem>
         </varlistentry>
  
         <varlistentry>
+         <term><literal>peer</></term>
+         <listitem>
+          <para>
+           Obtain the operating system user name from the operating system
+           and check if it matches the requested database user name.
+           This is only available for local connections.
+           See <xref linkend="auth-peer"> for details.
+          </para>
+         </listitem>
+        </varlistentry>
+ 
+        <varlistentry>
          <term><literal>ldap</></term>
          <listitem>
           <para>
***************
*** 1200,1206 **** omicron         bryanh                  guest1
    </sect2>
  
    <sect2 id="auth-ident">
!    <title>Ident-based Authentication</title>
  
     <indexterm>
      <primary>ident</primary>
--- 1213,1219 ----
    </sect2>
  
    <sect2 id="auth-ident">
!    <title>Ident Authentication</title>
  
     <indexterm>
      <primary>ident</primary>
***************
*** 1208,1220 **** omicron         bryanh                  guest1
  
     <para>
      The ident authentication method works by obtaining the client's
!     operating system user name and using it as the allowed database user
!     name (with an optional user name mapping).
!     The determination of the client's
!     user name is the security-critical point, and it works differently
!     depending on the connection type, as described below.
     </para>
  
     <para>
      The following configuration options are supported for <productname>ident</productname>:
      <variablelist>
--- 1221,1239 ----
  
     <para>
      The ident authentication method works by obtaining the client's
!     operating system user name from an ident server and using it as
!     the allowed database user name (with an optional user name mapping).
!     This is only supported on TCP/IP connections.
     </para>
  
+    <note>
+     <para>
+      When ident is specified for a local (non-TCP/IP) connection,
+      peer authentication (see <xref linkend="auth-peer">) will be
+      used instead.
+     </para>
+    </note>
+ 
     <para>
      The following configuration options are supported for <productname>ident</productname>:
      <variablelist>
***************
*** 1230,1238 **** omicron         bryanh                  guest1
      </variablelist>
     </para>
  
-    <sect3>
-     <title>Ident Authentication Over TCP/IP</title>
- 
     <para>
      The <quote>Identification Protocol</quote> is described in
      RFC 1413. Virtually every Unix-like
--- 1249,1254 ----
***************
*** 1275,1310 **** omicron         bryanh                  guest1
      since <productname>PostgreSQL</> does not have any way to decrypt the
      returned string to determine the actual user name.
     </para>
!    </sect3>
  
!    <sect3>
!     <title>Ident Authentication Over Local Sockets</title>
  
     <para>
!     On systems supporting <symbol>SO_PEERCRED</symbol> requests for
      Unix-domain sockets (currently <systemitem
      class="osname">Linux</>, <systemitem class="osname">FreeBSD</>,
      <systemitem class="osname">NetBSD</>, <systemitem class="osname">OpenBSD</>,
!     <systemitem class="osname">BSD/OS</>, and <systemitem class="osname">Solaris</systemitem>), ident authentication can also
!     be applied to local connections.
      <productname>PostgreSQL</> uses <symbol>SO_PEERCRED</symbol> to find out
      the operating system name of the connected client process.
-     In this case, no security risk is added by
-     using ident authentication; indeed it is a preferable choice for
-     local connections on such systems.
     </para>
  
-     <para>
-      On systems without <symbol>SO_PEERCRED</> requests, ident
-      authentication is only available for TCP/IP connections. As a
-      work-around, it is possible to specify the <systemitem
-      class="systemname">localhost</> address <systemitem
-      class="systemname">127.0.0.1</> and make connections to this
-      address.  This method is trustworthy to the extent that you trust
-      the local ident server.
-     </para>
-     </sect3>
- 
    </sect2>
  
    <sect2 id="auth-ldap">
--- 1291,1338 ----
      since <productname>PostgreSQL</> does not have any way to decrypt the
      returned string to determine the actual user name.
     </para>
!   </sect2>
  
!   <sect2 id="auth-peer">
!    <title>Peer Authentication</title>
! 
!    <indexterm>
!     <primary>peer</primary>
!    </indexterm>
  
     <para>
!     The peer authentication method works by obtaining the client's
!     operating system user name from the kernel and using it as the
!     allowed database user name (with optional user name mapping). This
!     is only supported on local connections.
!    </para>
! 
!    <para>
!     The following configuration options are supported for <productname>peer</productname>:
!     <variablelist>
!      <varlistentry>
!       <term><literal>map</literal></term>
!       <listitem>
!        <para>
!         Allows for mapping between system and database user names. See
!         <xref linkend="auth-username-maps"> for details.
!        </para>
!       </listitem>
!      </varlistentry>
!     </variablelist>
!    </para>
! 
!    <para>
!     Peer authentication is only available on  systems supporting
!     <symbol>SO_PEERCRED</symbol> requests for
      Unix-domain sockets (currently <systemitem
      class="osname">Linux</>, <systemitem class="osname">FreeBSD</>,
      <systemitem class="osname">NetBSD</>, <systemitem class="osname">OpenBSD</>,
!     <systemitem class="osname">BSD/OS</>, and <systemitem class="osname">Solaris</systemitem>).
      <productname>PostgreSQL</> uses <symbol>SO_PEERCRED</symbol> to find out
      the operating system name of the connected client process.
     </para>
  
    </sect2>
  
    <sect2 id="auth-ldap">
*** a/doc/src/sgml/runtime.sgml
--- b/doc/src/sgml/runtime.sgml
***************
*** 148,154 **** postgres$ <userinput>initdb -D /usr/local/pgsql/data</userinput>
     mode is not used; or modify the generated <filename>pg_hba.conf</filename>
     file after running <command>initdb</command>, but
     <emphasis>before</> you start the server for the first time. (Other
!    reasonable approaches include using <literal>ident</literal> authentication
     or file system permissions to restrict connections. See <xref
     linkend="client-authentication"> for more information.)
    </para>
--- 148,154 ----
     mode is not used; or modify the generated <filename>pg_hba.conf</filename>
     file after running <command>initdb</command>, but
     <emphasis>before</> you start the server for the first time. (Other
!    reasonable approaches include using <literal>peer</literal> authentication
     or file system permissions to restrict connections. See <xref
     linkend="client-authentication"> for more information.)
    </para>
*** a/src/backend/libpq/auth.c
--- b/src/backend/libpq/auth.c
***************
*** 60,66 **** static int	recv_and_check_password_packet(Port *port);
  /* Standard TCP port number for Ident service.	Assigned by IANA */
  #define IDENT_PORT 113
  
! static int	authident(hbaPort *port);
  
  
  /*----------------------------------------------------------------
--- 60,67 ----
  /* Standard TCP port number for Ident service.	Assigned by IANA */
  #define IDENT_PORT 113
  
! static int	ident_inet(hbaPort *port);
! static int	auth_peer(hbaPort *port);
  
  
  /*----------------------------------------------------------------
***************
*** 269,274 **** auth_failed(Port *port, int status)
--- 270,278 ----
  		case uaIdent:
  			errstr = gettext_noop("Ident authentication failed for user \"%s\"");
  			break;
+ 		case uaPeer:
+ 			errstr = gettext_noop("Peer authentication failed for user \"%s\"");
+ 			break;
  		case uaPassword:
  		case uaMD5:
  			errstr = gettext_noop("password authentication failed for user \"%s\"");
***************
*** 506,516 **** ClientAuthentication(Port *port)
  #endif
  			break;
  
! 		case uaIdent:
  
  			/*
! 			 * If we are doing ident on unix-domain sockets, use SCM_CREDS
! 			 * only if it is defined and SO_PEERCRED isn't.
  			 */
  #if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && \
  	(defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || \
--- 510,520 ----
  #endif
  			break;
  
! 		case uaPeer:
  
  			/*
! 			 * If we are doing peer on unix-domain sockets, use SCM_CREDS only
! 			 * if it is defined and SO_PEERCRED isn't.
  			 */
  #if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && \
  	(defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || \
***************
*** 535,541 **** ClientAuthentication(Port *port)
  				sendAuthRequest(port, AUTH_REQ_SCM_CREDS);
  			}
  #endif
! 			status = authident(port);
  			break;
  
  		case uaMD5:
--- 539,549 ----
  				sendAuthRequest(port, AUTH_REQ_SCM_CREDS);
  			}
  #endif
! 			status = auth_peer(port);
! 			break;
! 
! 		case uaIdent:
! 			status = ident_inet(port);
  			break;
  
  		case uaMD5:
***************
*** 1599,1609 **** interpret_ident_response(const char *ident_response,
   *
   *	But iff we're unable to get the information from ident, return false.
   */
! static bool
! ident_inet(const SockAddr remote_addr,
! 		   const SockAddr local_addr,
! 		   char *ident_user)
  {
  	pgsocket	sock_fd,		/* File descriptor for socket on which we talk
  								 * to Ident */
  				rc;				/* Return code from a locally called function */
--- 1607,1618 ----
   *
   *	But iff we're unable to get the information from ident, return false.
   */
! static int
! ident_inet(hbaPort *port)
  {
+ 	const SockAddr remote_addr = port->raddr;
+ 	const SockAddr local_addr = port->laddr;
+ 	char		ident_user[IDENT_USERNAME_MAX + 1];
  	pgsocket	sock_fd,		/* File descriptor for socket on which we talk
  								 * to Ident */
  				rc;				/* Return code from a locally called function */
***************
*** 1646,1652 **** ident_inet(const SockAddr remote_addr,
  	{
  		if (ident_serv)
  			pg_freeaddrinfo_all(hints.ai_family, ident_serv);
! 		return false;			/* we don't expect this to happen */
  	}
  
  	hints.ai_flags = AI_NUMERICHOST;
--- 1655,1661 ----
  	{
  		if (ident_serv)
  			pg_freeaddrinfo_all(hints.ai_family, ident_serv);
! 		return STATUS_ERROR;	/* we don't expect this to happen */
  	}
  
  	hints.ai_flags = AI_NUMERICHOST;
***************
*** 1662,1668 **** ident_inet(const SockAddr remote_addr,
  	{
  		if (la)
  			pg_freeaddrinfo_all(hints.ai_family, la);
! 		return false;			/* we don't expect this to happen */
  	}
  
  	sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
--- 1671,1677 ----
  	{
  		if (la)
  			pg_freeaddrinfo_all(hints.ai_family, la);
! 		return STATUS_ERROR;	/* we don't expect this to happen */
  	}
  
  	sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
***************
*** 1751,1757 **** ident_inet_done:
  		closesocket(sock_fd);
  	pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
  	pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
! 	return ident_return;
  }
  
  /*
--- 1760,1770 ----
  		closesocket(sock_fd);
  	pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
  	pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
! 
! 	if (ident_return)
! 		/* Success! Check the usermap */
! 		return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
! 	return STATUS_ERROR;
  }
  
  /*
***************
*** 1763,1771 **** ident_inet_done:
   */
  #ifdef HAVE_UNIX_SOCKETS
  
! static bool
! ident_unix(int sock, char *ident_user)
  {
  #if defined(HAVE_GETPEEREID)
  	/* OpenBSD style:  */
  	uid_t		uid;
--- 1776,1787 ----
   */
  #ifdef HAVE_UNIX_SOCKETS
  
! static int
! auth_peer(hbaPort *port)
  {
+ 	int			sock = port->sock;
+ 	char		ident_user[IDENT_USERNAME_MAX + 1];
+ 
  #if defined(HAVE_GETPEEREID)
  	/* OpenBSD style:  */
  	uid_t		uid;
***************
*** 1779,1785 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return false;
  	}
  
  	pass = getpwuid(uid);
--- 1795,1801 ----
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return STATUS_ERROR;
  	}
  
  	pass = getpwuid(uid);
***************
*** 1789,1800 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) uid)));
! 		return false;
  	}
  
  	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
  
- 	return true;
  #elif defined(SO_PEERCRED)
  	/* Linux style: use getsockopt(SO_PEERCRED) */
  	struct ucred peercred;
--- 1805,1815 ----
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) uid)));
! 		return STATUS_ERROR;
  	}
  
  	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
  
  #elif defined(SO_PEERCRED)
  	/* Linux style: use getsockopt(SO_PEERCRED) */
  	struct ucred peercred;
***************
*** 1809,1815 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return false;
  	}
  
  	pass = getpwuid(peercred.uid);
--- 1824,1830 ----
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return STATUS_ERROR;
  	}
  
  	pass = getpwuid(peercred.uid);
***************
*** 1819,1830 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) peercred.uid)));
! 		return false;
  	}
  
  	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
  
- 	return true;
  #elif defined(HAVE_GETPEERUCRED)
  	/* Solaris > 10 */
  	uid_t		uid;
--- 1834,1844 ----
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) peercred.uid)));
! 		return STATUS_ERROR;
  	}
  
  	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
  
  #elif defined(HAVE_GETPEERUCRED)
  	/* Solaris > 10 */
  	uid_t		uid;
***************
*** 1837,1843 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return false;
  	}
  
  	if ((uid = ucred_geteuid(ucred)) == -1)
--- 1851,1857 ----
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return STATUS_ERROR;
  	}
  
  	if ((uid = ucred_geteuid(ucred)) == -1)
***************
*** 1845,1851 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errcode_for_socket_access(),
  		   errmsg("could not get effective UID from peer credentials: %m")));
! 		return false;
  	}
  
  	ucred_free(ucred);
--- 1859,1865 ----
  		ereport(LOG,
  				(errcode_for_socket_access(),
  		   errmsg("could not get effective UID from peer credentials: %m")));
! 		return STATUS_ERROR;
  	}
  
  	ucred_free(ucred);
***************
*** 1856,1867 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) uid)));
! 		return false;
  	}
  
  	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
  
- 	return true;
  #elif defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS))
  	struct msghdr msg;
  
--- 1870,1880 ----
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) uid)));
! 		return STATUS_ERROR;
  	}
  
  	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
  
  #elif defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS))
  	struct msghdr msg;
  
***************
*** 1913,1919 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return false;
  	}
  
  	cred = (Cred *) CMSG_DATA(cmsg);
--- 1926,1932 ----
  		ereport(LOG,
  				(errcode_for_socket_access(),
  				 errmsg("could not get peer credentials: %m")));
! 		return STATUS_ERROR;
  	}
  
  	cred = (Cred *) CMSG_DATA(cmsg);
***************
*** 1925,1983 **** ident_unix(int sock, char *ident_user)
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) cred->cruid)));
! 		return false;
  	}
  
  	strlcpy(ident_user, pw->pw_name, IDENT_USERNAME_MAX + 1);
  
- 	return true;
  #else
  	ereport(LOG,
  			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  			 errmsg("Ident authentication is not supported on local connections on this platform")));
  
! 	return false;
! #endif
! }
! #endif   /* HAVE_UNIX_SOCKETS */
! 
! 
! /*
!  *	Determine the username of the initiator of the connection described
!  *	by "port".	Then look in the usermap file under the usermap
!  *	port->hba->usermap and see if that user is equivalent to Postgres user
!  *	port->user.
!  *
!  *	Return STATUS_OK if yes, STATUS_ERROR if no match (or couldn't get info).
!  */
! static int
! authident(hbaPort *port)
! {
! 	char		ident_user[IDENT_USERNAME_MAX + 1];
! 
! 	switch (port->raddr.addr.ss_family)
! 	{
! 		case AF_INET:
! #ifdef	HAVE_IPV6
! 		case AF_INET6:
! #endif
! 			if (!ident_inet(port->raddr, port->laddr, ident_user))
! 				return STATUS_ERROR;
! 			break;
! 
! #ifdef HAVE_UNIX_SOCKETS
! 		case AF_UNIX:
! 			if (!ident_unix(port->sock, ident_user))
! 				return STATUS_ERROR;
! 			break;
  #endif
  
- 		default:
- 			return STATUS_ERROR;
- 	}
- 
  	return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
  }
  
  
  /*----------------------------------------------------------------
--- 1938,1959 ----
  		ereport(LOG,
  				(errmsg("local user with ID %d does not exist",
  						(int) cred->cruid)));
! 		return STATUS_ERROR;
  	}
  
  	strlcpy(ident_user, pw->pw_name, IDENT_USERNAME_MAX + 1);
  
  #else
  	ereport(LOG,
  			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  			 errmsg("Ident authentication is not supported on local connections on this platform")));
  
! 	return STATUS_ERROR;
  #endif
  
  	return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
  }
+ #endif   /* HAVE_UNIX_SOCKETS */
  
  
  /*----------------------------------------------------------------
*** a/src/backend/libpq/hba.c
--- b/src/backend/libpq/hba.c
***************
*** 1060,1065 **** parse_hba_line(List *line, int line_num, HbaLine *parsedline)
--- 1060,1067 ----
  		parsedline->auth_method = uaTrust;
  	else if (strcmp(token, "ident") == 0)
  		parsedline->auth_method = uaIdent;
+ 	else if (strcmp(token, "peer") == 0)
+ 		parsedline->auth_method = uaPeer;
  	else if (strcmp(token, "password") == 0)
  		parsedline->auth_method = uaPassword;
  	else if (strcmp(token, "krb5") == 0)
***************
*** 1137,1142 **** parse_hba_line(List *line, int line_num, HbaLine *parsedline)
--- 1139,1152 ----
  		return false;
  	}
  
+ 	/*
+ 	 * XXX: When using ident on local connections, change it to peer, for
+ 	 * backwards compatibility.
+ 	 */
+ 	if (parsedline->conntype == ctLocal &&
+ 		parsedline->auth_method == uaIdent)
+ 		parsedline->auth_method = uaPeer;
+ 
  	/* Invalid authentication combinations */
  	if (parsedline->conntype == ctLocal &&
  		parsedline->auth_method == uaKrb5)
***************
*** 1160,1165 **** parse_hba_line(List *line, int line_num, HbaLine *parsedline)
--- 1170,1186 ----
  		return false;
  	}
  
+ 	if (parsedline->conntype != ctLocal &&
+ 		parsedline->auth_method == uaPeer)
+ 	{
+ 		ereport(LOG,
+ 				(errcode(ERRCODE_CONFIG_FILE_ERROR),
+ 			errmsg("peer authentication is only supported on local sockets"),
+ 				 errcontext("line %d of configuration file \"%s\"",
+ 							line_num, HbaFileName)));
+ 		return false;
+ 	}
+ 
  	/*
  	 * SSPI authentication can never be enabled on ctLocal connections,
  	 * because it's only supported on Windows, where ctLocal isn't supported.
***************
*** 1203,1213 **** parse_hba_line(List *line, int line_num, HbaLine *parsedline)
  			if (strcmp(token, "map") == 0)
  			{
  				if (parsedline->auth_method != uaIdent &&
  					parsedline->auth_method != uaKrb5 &&
  					parsedline->auth_method != uaGSS &&
  					parsedline->auth_method != uaSSPI &&
  					parsedline->auth_method != uaCert)
! 					INVALID_AUTH_OPTION("map", gettext_noop("ident, krb5, gssapi, sspi and cert"));
  				parsedline->usermap = pstrdup(c);
  			}
  			else if (strcmp(token, "clientcert") == 0)
--- 1224,1235 ----
  			if (strcmp(token, "map") == 0)
  			{
  				if (parsedline->auth_method != uaIdent &&
+ 					parsedline->auth_method != uaPeer &&
  					parsedline->auth_method != uaKrb5 &&
  					parsedline->auth_method != uaGSS &&
  					parsedline->auth_method != uaSSPI &&
  					parsedline->auth_method != uaCert)
! 					INVALID_AUTH_OPTION("map", gettext_noop("ident, peer, krb5, gssapi, sspi and cert"));
  				parsedline->usermap = pstrdup(c);
  			}
  			else if (strcmp(token, "clientcert") == 0)
*** a/src/backend/libpq/pg_hba.conf.sample
--- b/src/backend/libpq/pg_hba.conf.sample
***************
*** 41,47 ****
  # directly connected to.
  #
  # METHOD can be "trust", "reject", "md5", "password", "gss", "sspi",
! # "krb5", "ident", "pam", "ldap", "radius" or "cert".  Note that
  # "password" sends passwords in clear text; "md5" is preferred since
  # it sends encrypted passwords.
  #
--- 41,47 ----
  # directly connected to.
  #
  # METHOD can be "trust", "reject", "md5", "password", "gss", "sspi",
! # "krb5", "ident", "peer", "pam", "ldap", "radius" or "cert".  Note that
  # "password" sends passwords in clear text; "md5" is preferred since
  # it sends encrypted passwords.
  #
***************
*** 75,81 ****
  # TYPE  DATABASE        USER            ADDRESS                 METHOD
  
  @remove-line-for-nolocal@# "local" is for Unix domain socket connections only
! @remove-line-for-nolocal@local   all             all                                     @authmethod@
  # IPv4 local connections:
  host    all             all             127.0.0.1/32            @authmethod@
  # IPv6 local connections:
--- 75,81 ----
  # TYPE  DATABASE        USER            ADDRESS                 METHOD
  
  @remove-line-for-nolocal@# "local" is for Unix domain socket connections only
! @remove-line-for-nolocal@local   all             all                                     @authmethodlocal@
  # IPv4 local connections:
  host    all             all             127.0.0.1/32            @authmethod@
  # IPv6 local connections:
*** a/src/bin/initdb/initdb.c
--- b/src/bin/initdb/initdb.c
***************
*** 82,87 **** static char *username = "";
--- 82,88 ----
  static bool pwprompt = false;
  static char *pwfilename = NULL;
  static char *authmethod = "";
+ static char *authmethodlocal = "";
  static bool debug = false;
  static bool noclean = false;
  static bool show_setting = false;
***************
*** 1076,1081 **** setup_config(void)
--- 1077,1085 ----
  	conflines = replace_token(conflines,
  							  "@authmethod@",
  							  authmethod);
+ 	conflines = replace_token(conflines,
+ 							  "@authmethodlocal@",
+ 							  authmethodlocal);
  
  	conflines = replace_token(conflines,
  							  "@authcomment@",
***************
*** 2637,2642 **** main(int argc, char *argv[])
--- 2641,2647 ----
  	}
  
  	if (strcmp(authmethod, "md5") &&
+ 		strcmp(authmethod, "peer") &&
  		strcmp(authmethod, "ident") &&
  		strcmp(authmethod, "trust") &&
  #ifdef USE_PAM
***************
*** 2666,2671 **** main(int argc, char *argv[])
--- 2671,2690 ----
  		exit(1);
  	}
  
+ 	/*
+ 	 * When ident is specified, use peer for local connections. Mirrored, when
+ 	 * peer is specified, use ident for TCP connections.
+ 	 */
+ 	if (strcmp(authmethod, "ident") == 0)
+ 		authmethodlocal = "peer";
+ 	else if (strcmp(authmethod, "peer") == 0)
+ 	{
+ 		authmethodlocal = "peer";
+ 		authmethod = "ident";
+ 	}
+ 	else
+ 		authmethodlocal = authmethod;
+ 
  	if (strlen(pg_data) == 0)
  	{
  		pgdenv = getenv("PGDATA");
*** a/src/include/libpq/hba.h
--- b/src/include/libpq/hba.h
***************
*** 29,35 **** typedef enum UserAuth
  	uaPAM,
  	uaLDAP,
  	uaCert,
! 	uaRADIUS
  } UserAuth;
  
  typedef enum IPCompareMethod
--- 29,36 ----
  	uaPAM,
  	uaLDAP,
  	uaCert,
! 	uaRADIUS,
! 	uaPeer
  } UserAuth;
  
  typedef enum IPCompareMethod
#36Tom Lane
tgl@sss.pgh.pa.us
In reply to: Magnus Hagander (#35)
Re: Indent authentication overloading

Magnus Hagander <magnus@hagander.net> writes:

On Sat, Mar 19, 2011 at 16:24, Tom Lane <tgl@sss.pgh.pa.us> wrote:

... The docs need
to state the truth, namely that "ident" is still allowed as a synonym
for "peer" on local connections. �Otherwise people will get confused
as to why their pg_hba files still work.

Hmm: Good point, update attached.

That looks OK to me.

regards, tom lane

#37Magnus Hagander
magnus@hagander.net
In reply to: Tom Lane (#36)
Re: Indent authentication overloading

On Sat, Mar 19, 2011 at 17:39, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Magnus Hagander <magnus@hagander.net> writes:

On Sat, Mar 19, 2011 at 16:24, Tom Lane <tgl@sss.pgh.pa.us> wrote:

... The docs need
to state the truth, namely that "ident" is still allowed as a synonym
for "peer" on local connections.  Otherwise people will get confused
as to why their pg_hba files still work.

Hmm: Good point, update attached.

That looks OK to me.

Applied.

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