On Sat, Mar 19, 2011 at 16:24, Tom Lane <t...@sss.pgh.pa.us> wrote:
> Magnus Hagander <mag...@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/
*** 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
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to