Thread: Adding usernames to pg_hba.conf

Adding usernames to pg_hba.conf

From
Bruce Momjian
Date:
This patch completes the following TODO item:

    * Allow usernames to be specified directly in pg_hba.conf (Bruce)

Currently, we allow usernames in secondary password files, but this is a
very confusing feature.  This patch:

    o  removes secondary password file support
    o  adds a user name column just after the database column
    o  allows a comma separated list of usernames or databases
    o  allows another file to contain a list of username/databases
       by preceding the pg_hba.conf entry with '@'
    o  allow single or double-quoting of user/database names

See the documentation changes and new pg_hba.conf diffs for samples.

Is the '@' sign a good way to identify a file name?  Is putting the
username column just after the database column the right place for it?

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
Index: doc/src/sgml/client-auth.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/client-auth.sgml,v
retrieving revision 1.32
diff -c -r1.32 client-auth.sgml
*** doc/src/sgml/client-auth.sgml    20 Jan 2002 22:19:55 -0000    1.32
--- doc/src/sgml/client-auth.sgml    19 Mar 2002 05:51:45 -0000
***************
*** 10,23 ****
   </indexterm>

   <para>
!   When a client application connects to the database server, it specifies which
!   <productname>PostgreSQL</productname> user name it wants to connect as,
!   much the same way one logs into a Unix computer as a particular user.
!   Within the SQL environment the active
!   database user name determines access privileges to database
!   objects -- see <xref linkend="user-manag"> for more information
!   about that. It is therefore obviously essential to restrict which
!   database user name(s) a given client can connect as.
   </para>

   <para>
--- 10,23 ----
   </indexterm>

   <para>
!   When a client application connects to the database server, it
!   specifies which <productname>PostgreSQL</productname> user name it
!   wants to connect as, much the same way one logs into a Unix computer
!   as a particular user. Within the SQL environment the active database
!   user name determines access privileges to database objects -- see
!   <xref linkend="user-manag"> for more information about that. It is
!   therefore obviously essential to restrict which database user name(s)
!   a given client can connect as.
   </para>

   <para>
***************
*** 30,49 ****

   <para>
    <productname>PostgreSQL</productname> offers a number of different
!   client authentication methods.  The method to be used can be selected
!   on the basis of (client) host and database; some authentication methods
!   allow you to restrict by user name as well.
   </para>

   <para>
!   <productname>PostgreSQL</productname> database user names are logically
    separate from user names of the operating system in which the server
!   runs.  If all the users of a particular server also have accounts on
    the server's machine, it makes sense to assign database user names
!   that match their operating system user names.  However, a server that accepts remote
!   connections may have many users who have no local account, and in such
!   cases there need be no connection between database user names and OS
!   user names.
   </para>

   <sect1 id="pg-hba-conf">
--- 30,48 ----

   <para>
    <productname>PostgreSQL</productname> offers a number of different
!   client authentication methods. The method to be used can be selected
!   on the basis of (client) host, database, and user.
   </para>

   <para>
!   <productname>PostgreSQL</productname> user names are logically
    separate from user names of the operating system in which the server
!   runs. If all the users of a particular server also have accounts on
    the server's machine, it makes sense to assign database user names
!   that match their operating system user names. However, a server that
!   accepts remote connections may have many users who have no local
!   account, and in such cases there need be no connection between
!   database user names and OS user names.
   </para>

   <sect1 id="pg-hba-conf">
***************
*** 56,94 ****
    <para>
     Client authentication is controlled by the file
     <filename>pg_hba.conf</filename> in the data directory, e.g.,
!    <filename>/usr/local/pgsql/data/pg_hba.conf</filename>. (<acronym>HBA</> stands
!    for host-based authentication.) A default <filename>pg_hba.conf</filename>
!    file is installed when the
!    data area is initialized by <command>initdb</command>.
    </para>

    <para>
!    The general format of the <filename>pg_hba.conf</filename> file is
!    of a set of records, one per line. Blank lines and lines beginning
!    with a hash character (<quote>#</quote>) are ignored. A record is
!    made up of a number of fields which are separated by spaces and/or
!    tabs.  Records cannot be continued across lines.
    </para>

    <para>
     Each record specifies a connection type, a client IP address range
!    (if relevant for the connection type), a database name or names,
     and the authentication method to be used for connections matching
!    these parameters.
!    The first record that matches the type, client address, and requested
!    database name of a connection attempt is used to do the
!    authentication step.  There is no <quote>fall-through</> or
     <quote>backup</>: if one record is chosen and the authentication
!    fails, the following records are not considered. If no record
!    matches, the access will be denied.
    </para>

    <para>
     A record may have one of the three formats
     <synopsis>
! local   <replaceable>database</replaceable> <replaceable>authentication-method</replaceable> [
<replaceable>authentication-option</replaceable>] 
! host    <replaceable>database</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable>
<replaceable>authentication-method</replaceable>[ <replaceable>authentication-option</replaceable> ] 
! hostssl <replaceable>database</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable>
<replaceable>authentication-method</replaceable>[ <replaceable>authentication-option</replaceable> ] 
      </synopsis>
     The meaning of the fields is as follows:

--- 55,93 ----
    <para>
     Client authentication is controlled by the file
     <filename>pg_hba.conf</filename> in the data directory, e.g.,
!    <filename>/usr/local/pgsql/data/pg_hba.conf</filename>.
!    (<acronym>HBA</> stands for host-based authentication.) A default
!    <filename>pg_hba.conf</filename> file is installed when the data area
!    is initialized by <command>initdb</command>.
    </para>

    <para>
!    The general format of the <filename>pg_hba.conf</filename> file is of
!    a set of records, one per line. Blank lines are ignored, as is any
!    text after the <quote>#</quote> comment character. A record is made
!    up of a number of fields which are separated by spaces and/or tabs.
!    Fields can contain white space if the field value is quoted. Records
!    cannot be continued across lines.
    </para>

    <para>
     Each record specifies a connection type, a client IP address range
!    (if relevant for the connection type), a database name, a user name,
     and the authentication method to be used for connections matching
!    these parameters. The first record with a matching connection type,
!    client address, requested database, and user name is used to peform
!    authentication. There is no <quote>fall-through</> or
     <quote>backup</>: if one record is chosen and the authentication
!    fails, subsequent records are not considered. If no record matches,
!    access is denied.
    </para>

    <para>
     A record may have one of the three formats
     <synopsis>
! local   <replaceable>database</replaceable> <replaceable>user</replaceable>
<replaceable>authentication-method</replaceable>[ <replaceable>authentication-option</replaceable> ] 
! host    <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable>
<replaceable>IP-mask</replaceable><replaceable>authentication-method</replaceable> 
! hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable>
<replaceable>IP-mask</replaceable><replaceable>authentication-method</replaceable> 
      </synopsis>
     The meaning of the fields is as follows:

***************
*** 97,103 ****
       <term><literal>local</literal></term>
       <listitem>
        <para>
!        This record pertains to connection attempts over Unix domain
         sockets.
        </para>
       </listitem>
--- 96,102 ----
       <term><literal>local</literal></term>
       <listitem>
        <para>
!        This record applies to connection attempts using Unix domain
         sockets.
        </para>
       </listitem>
***************
*** 107,116 ****
       <term><literal>host</literal></term>
       <listitem>
        <para>
!        This record pertains to connection attempts over TCP/IP
!        networks. Note that TCP/IP connections are completely disabled
!        unless the server is started with the <option>-i</option> switch or
!        the equivalent configuration parameter is set.
        </para>
       </listitem>
      </varlistentry>
--- 106,116 ----
       <term><literal>host</literal></term>
       <listitem>
        <para>
!        This record applied to connection attempts using TCP/IP networks.
!        Note that TCP/IP connections are disabled unless the server is
!        started with the <option>-i</option> option or the
!        <literal>tcpip_socket</> <filename>postgresql.conf</>
!        configuration parameter is enabled.
        </para>
       </listitem>
      </varlistentry>
***************
*** 119,131 ****
       <term><literal>hostssl</literal></term>
       <listitem>
        <para>
!        This record pertains to connection attempts with SSL over
         TCP/IP. To make use of this option the server must be
         built with SSL support enabled. Furthermore, SSL must be
         enabled with the <option>-l</> option or equivalent configuration
         setting when the server is started.  (Note: <literal>host</literal>
         records will match either SSL or non-SSL connection attempts, but
!        <literal>hostssl</literal> records match only SSL connections.)
        </para>
       </listitem>
      </varlistentry>
--- 119,131 ----
       <term><literal>hostssl</literal></term>
       <listitem>
        <para>
!        This record applies to connection attempts using SSL over
         TCP/IP. To make use of this option the server must be
         built with SSL support enabled. Furthermore, SSL must be
         enabled with the <option>-l</> option or equivalent configuration
         setting when the server is started.  (Note: <literal>host</literal>
         records will match either SSL or non-SSL connection attempts, but
!        <literal>hostssl</literal> records requires SSL connections.)
        </para>
       </listitem>
      </varlistentry>
***************
*** 134,145 ****
       <term><replaceable>database</replaceable></term>
       <listitem>
        <para>
!        Specifies the database that this record applies to. The value
         <literal>all</literal> specifies that it applies to all
         databases, while the value <literal>sameuser</> identifies the
!        database with the same name as the connecting user.  Otherwise,
!        this is the name of a specific <productname>PostgreSQL</productname>
!        database.
        </para>
       </listitem>
      </varlistentry>
--- 134,165 ----
       <term><replaceable>database</replaceable></term>
       <listitem>
        <para>
!        Specifies the database for this record. The value
         <literal>all</literal> specifies that it applies to all
         databases, while the value <literal>sameuser</> identifies the
!        database with the same name as the connecting user. Otherwise,
!        this is the name of a specific
!        <productname>PostgreSQL</productname> database. Multiple database
!        names can be supplied by separating them with commas. A file
!        containing database names can be specified by preceding the file
!        name with <literal>@</>. The file must be in the same directory
!        as <filename>pg_hba.conf</>.
!       </para>
!      </listitem>
!     </varlistentry>
!
!     <varlistentry>
!      <term><replaceable>user</replaceable></term>
!      <listitem>
!       <para>
!        Specifies the user for this record. The value
!        <literal>all</literal> specifies that it applies to all users.
!        Otherwise, this is the name of a specific
!        <productname>PostgreSQL</productname> user. Multiple user
!        names can be supplied by separating them with commas. A file
!        containing user names can be specified by preceding the file
!        name with <literal>@</>. The file must be in the same directory
!        as <filename>pg_hba.conf</>.
        </para>
       </listitem>
      </varlistentry>
***************
*** 149,158 ****
       <term><replaceable>IP mask</replaceable></term>
       <listitem>
        <para>
!        These two fields specify to which client machines a
!        <literal>host</literal> or <literal>hostssl</literal>
!        record applies, based on their IP
!        address. (Of course IP addresses can be spoofed but this
         consideration is beyond the scope of
         <productname>PostgreSQL</productname>.) The precise logic is that
         <blockquote>
--- 169,177 ----
       <term><replaceable>IP mask</replaceable></term>
       <listitem>
        <para>
!        These two fields specify the client machine IP addresses
!        (<literal>host</literal> or <literal>hostssl</literal>) for this
!        record. (Of course IP addresses can be spoofed but this
         consideration is beyond the scope of
         <productname>PostgreSQL</productname>.) The precise logic is that
         <blockquote>
***************
*** 169,178 ****
       <term><replaceable>authentication method</replaceable></term>
       <listitem>
        <para>
!        Specifies the method that users must use to authenticate themselves
!        when connecting under the control of this authentication record.
!        The possible choices are summarized here,
!        details are in <xref linkend="auth-methods">.

         <variablelist>
          <varlistentry>
--- 188,196 ----
       <term><replaceable>authentication method</replaceable></term>
       <listitem>
        <para>
!        Specifies the authentication method to use when connecting via
!        this record. The possible choices are summarized here; details
!        are in <xref linkend="auth-methods">.

         <variablelist>
          <varlistentry>
***************
*** 190,255 ****
          <term><literal>reject</></term>
          <listitem>
           <para>
!           The connection is rejected unconditionally. This is mostly
!           useful to <quote>filter out</> certain hosts from a group.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term><literal>password</></term>
          <listitem>
           <para>
!           The client is required to supply a password which is required to
!       match the database password that was set up for the user.
!          </para>
!
!          <para>
!           An optional file name may be specified after the
!           <literal>password</literal> keyword. This file is expected to
!           contain a list of users who may connect using this record,
!           and optionally alternative passwords for them.
!          </para>
!
!          <para>
!           The password is sent over the wire in clear text. For better
!           protection, use the <literal>md5</literal> or
!           <literal>crypt</literal> methods.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term><literal>md5</></term>
          <listitem>
           <para>
!           Like the <literal>password</literal> method, but the password
!           is sent over the wire encrypted using a simple
!           challenge-response protocol. This protects against incidental
!           wire-sniffing.  This is now the recommended choice for
!       password-based authentication.
!          </para>
!
!          <para>
!       The name of a file may follow the
!           <literal>md5</literal> keyword.  It contains a list of users
!           who may connect using this record.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term><literal>crypt</></term>
          <listitem>
           <para>
!           Like the <literal>md5</literal> method but uses older crypt
!           encryption, which is needed for pre-7.2
!       clients. <literal>md5</literal> is
!           preferred for 7.2 and later clients. The <literal>crypt</>
!           method is not compatible with encrypting passwords in
!           <filename>pg_shadow</>, and may fail if client and server
!           machines have different implementations of the crypt() library
!           routine.
           </para>
          </listitem>
         </varlistentry>
--- 208,248 ----
          <term><literal>reject</></term>
          <listitem>
           <para>
!           The connection is rejected unconditionally. This is useful for
!           <quote>filtering out</> certain hosts from a group.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term><literal>md5</></term>
          <listitem>
           <para>
!           Requires the client to supply an MD5 encrypted password for
!           authentication. This is the only method that allows encrypted
!           passwords to be stored in pg_shadow.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term><literal>crypt</></term>
          <listitem>
           <para>
!           Like <literal>md5</literal> method but uses older crypt
!           encryption, which is needed for pre-7.2 clients.
!           <literal>md5</literal> is preferred for 7.2 and later clients.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term><literal>password</></term>
          <listitem>
           <para>
!           Same as "md5", but the password is sent in cleartext over the
!           network. This should not be used on untrusted networks.
!          </para>
           </para>
          </listitem>
         </varlistentry>
***************
*** 278,311 ****
          <term><literal>ident</></term>
          <listitem>
       <para>
!       The identity of the user as determined on login to the
!       operating system is used by <productname>PostgreSQL</productname>
!       to determine whether the user
!           is allowed to connect as the requested database user.
!       For TCP/IP connections the user's identity is determined by
!       contacting the <firstterm>ident</firstterm> server on the client
!       host.  (Note that this is only as reliable as the remote ident
!       server; ident authentication should never be used for remote hosts
!       whose administrators are not trustworthy.)
!       On operating systems
!       supporting <symbol>SO_PEERCRED</> requests for Unix domain sockets,
!       ident authentication is possible for local connections;
!       the system is then asked for the connecting user's identity.
       </para>
           <para>
!       On systems without <symbol>SO_PEERCRED</> requests, ident authentication
!       is only available for TCP/IP connections.  As a workaround,
!       it is possible to
!       specify the <systemitem class="systemname">localhost</> address
!           <systemitem class="systemname">127.0.0.1</> and make connections
!       to this address.
!      </para>
!          <para>
!           The <replaceable>authentication option</replaceable> following
!           the <literal>ident</> keyword specifies the name of an
!           <firstterm>ident map</firstterm> that specifies which operating
!           system users equate with which database users. See below for
!           details.
           </para>
          </listitem>
         </varlistentry>
--- 271,306 ----
          <term><literal>ident</></term>
          <listitem>
       <para>
!           For TCP/IP connections, authentication is done by contacting
!           the <firstterm>ident</firstterm> server on the client host.
!           This is only as secure as the client machine. You must specify
!           the map name after the 'ident' keyword. It determines how to
!           map remote user names to PostgreSQL user names. If you use
!           "sameuser", the user names are assumed to be identical. If
!           not, the map name is looked up in the $PGDATA/pg_ident.conf
!           file. The connection is accepted if that file contains an
!           entry for this map name with the ident-supplied username and
!           the requested PostgreSQL username.
!          </para>
!          <para>
!           On machines that support unix-domain socket credentials
!           (currently Linux, FreeBSD, NetBSD, and BSD/OS), ident allows
!           reliable authentication of 'local' connections without ident
!           running on the local machine.
!          </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.
       </para>
           <para>
!           Following the <literal>ident</> keyword, an <firstterm>ident
!           map</firstterm> name should be supplied which specifies which
!           operating system users equate with which database users. See
!           below for details.
           </para>
          </listitem>
         </varlistentry>
***************
*** 315,331 ****
          <listitem>
           <para>
            This authentication type operates similarly to
!           <firstterm>password</firstterm>, with the main difference that
!           it will use PAM (Pluggable Authentication Modules) as the
!           authentication mechanism. The <replaceable>authentication
!           option</replaceable> following the <literal>pam</> keyword
!           specifies the service name that will be passed to PAM. The
!           default service name is <literal>postgresql</literal>.
!           For more information about PAM, please read the <ulink
!           url="http://www.kernel.org/pub/linux/libs/pam/"><productname>Linux-PAM</productname>
!           Page</ulink> and/or the <ulink
!           url="http://www.sun.com/software/solaris/pam/"><systemitem class="osname">Solaris</> PAM
!           Page</ulink>.
           </para>
          </listitem>
         </varlistentry>
--- 310,325 ----
          <listitem>
           <para>
            This authentication type operates similarly to
!           <firstterm>password</firstterm> except that it uses PAM
!           (Pluggable Authentication Modules) as the authentication
!           mechanism. The default PAM service name is
!           <literal>postgresql</literal>. You can optionally supply you
!           own service name after the <literal>pam</> keyword in the
!           file. For more information about PAM, please read the <ulink
!           url="http://www.kernel.org/pub/linux/libs/pam/"><productname>L
!           inux-PAM</productname> Page</ulink> and the <ulink
!           url="http://www.sun.com/software/solaris/pam/"><systemitem
!           class="osname">Solaris</> PAM Page</ulink>.
           </para>
          </listitem>
         </varlistentry>
***************
*** 336,377 ****
       </listitem>
      </varlistentry>

-     <varlistentry>
-      <term><replaceable>authentication option</replaceable></term>
-      <listitem>
-       <para>
-        This field is interpreted differently depending on the
-        authentication method, as described above.
-       </para>
-      </listitem>
-     </varlistentry>
     </variablelist>
    </para>

    <para>
     Since the <filename>pg_hba.conf</filename> records are examined
     sequentially for each connection attempt, the order of the records is
!    very significant.  Typically, earlier records will have tight
!    connection match parameters and weaker authentication methods,
!    while later records will have looser match parameters and stronger
!    authentication methods.  For example, one might wish to use
!    <literal>trust</> authentication for local TCP connections but
!    require a password for remote TCP connections.  In this case a
!    record specifying <literal>trust</> authentication for connections
!    from 127.0.0.1 would appear before a record specifying password
!    authentication for a wider range of allowed client IP addresses.
    </para>

    <para>
      <indexterm>
       <primary>SIGHUP</primary>
      </indexterm>
!    The <filename>pg_hba.conf</filename> file is read on startup
!    and when the <application>postmaster</> receives a
     <systemitem>SIGHUP</systemitem> signal. If you edit the file on an
     active system, you will need to signal the <application>postmaster</>
!    (using <literal>pg_ctl reload</> or <literal>kill -HUP</>)
!    to make it re-read the file.
    </para>

    <para>
--- 330,362 ----
       </listitem>
      </varlistentry>

     </variablelist>
    </para>

    <para>
     Since the <filename>pg_hba.conf</filename> records are examined
     sequentially for each connection attempt, the order of the records is
!    significant. Typically, earlier records will have tight connection
!    match parameters and weaker authentication methods, while later
!    records will have looser match parameters and stronger authentication
!    methods. For example, one might wish to use <literal>trust</>
!    authentication for local TCP connections but require a password for
!    remote TCP connections. In this case a record specifying
!    <literal>trust</> authentication for connections from 127.0.0.1 would
!    appear before a record specifying password authentication for a wider
!    range of allowed client IP addresses.
    </para>

    <para>
      <indexterm>
       <primary>SIGHUP</primary>
      </indexterm>
!    The <filename>pg_hba.conf</filename> file is read on startup and when
!    the <application>postmaster</> receives a
     <systemitem>SIGHUP</systemitem> signal. If you edit the file on an
     active system, you will need to signal the <application>postmaster</>
!    (using <literal>pg_ctl reload</> or <literal>kill -HUP</>) to make it
!    re-read the file.
    </para>

    <para>
***************
*** 382,408 ****
     <example id="example-pg-hba.conf">
      <title>An example <filename>pg_hba.conf</filename> file</title>
  <programlisting>
! # TYPE       DATABASE    IP_ADDRESS    MASK               AUTHTYPE  MAP

  # Allow any user on the local system to connect to any
  # database under any username, but only via an IP connection:

! host         all         127.0.0.1     255.255.255.255    trust

  # The same, over Unix-socket connections:

! local        all                                          trust

  # Allow any user from any host with IP address 192.168.93.x to
  # connect to database "template1" as the same username that ident on that
  # host identifies him as (typically his Unix username):

! host         template1   192.168.93.0  255.255.255.0      ident     sameuser

  # Allow a user from host 192.168.12.10 to connect to database "template1"
! # if the user's password in pg_shadow is correctly supplied:

! host         template1   192.168.12.10 255.255.255.255    md5

  # In the absence of preceding "host" lines, these two lines will reject
  # all connection attempts from 192.168.54.1 (since that entry will be
--- 367,393 ----
     <example id="example-pg-hba.conf">
      <title>An example <filename>pg_hba.conf</filename> file</title>
  <programlisting>
! # TYPE       DATABASE    USER       IP_ADDRESS    MASK               AUTHTYPE

  # Allow any user on the local system to connect to any
  # database under any username, but only via an IP connection:

! host         all         all        127.0.0.1     255.255.255.255    trust

  # The same, over Unix-socket connections:

! local        all         all                                         trust

  # Allow any user from any host with IP address 192.168.93.x to
  # connect to database "template1" as the same username that ident on that
  # host identifies him as (typically his Unix username):

! host         template1   all        192.168.93.0  255.255.255.0      ident sameuser

  # Allow a user from host 192.168.12.10 to connect to database "template1"
! # if the user's password is correctly supplied:

! host         template1   all        192.168.12.10 255.255.255.255    md5

  # In the absence of preceding "host" lines, these two lines will reject
  # all connection attempts from 192.168.54.1 (since that entry will be
***************
*** 410,417 ****
  # else on the Internet. The zero mask means that no bits of the host IP
  # address are considered, so it matches any host:

! host         all        192.168.54.1   255.255.255.255    reject
! host         all        0.0.0.0        0.0.0.0            krb5

  # Allow users from 192.168.x.x hosts to connect to any database, if they
  # pass the ident check.  If, for example, ident says the user is "bryanh"
--- 395,402 ----
  # else on the Internet. The zero mask means that no bits of the host IP
  # address are considered, so it matches any host:

! host         all        all         192.168.54.1   255.255.255.255    reject
! host         all        all         0.0.0.0        0.0.0.0            krb5

  # Allow users from 192.168.x.x hosts to connect to any database, if they
  # pass the ident check.  If, for example, ident says the user is "bryanh"
***************
*** 419,425 ****
  # is allowed if there is an entry in pg_ident.conf for map "omicron" that
  # says "bryanh" is allowed to connect as "guest1":

! host         all        192.168.0.0    255.255.0.0        ident     omicron

  # If these are the only two lines for local connections, they will allow
  # local users to connect only to their own databases (database named the
--- 404,410 ----
  # is allowed if there is an entry in pg_ident.conf for map "omicron" that
  # says "bryanh" is allowed to connect as "guest1":

! host         all        all         192.168.0.0    255.255.0.0        ident omicron

  # If these are the only two lines for local connections, they will allow
  # local users to connect only to their own databases (database named the
***************
*** 429,436 ****
  # cases.  (If you prefer to use ident authorization, an ident map can
  # serve a parallel purpose to the password list file used here.)

! local        sameuser                                     md5
! local        all                                          md5  admins
  </programlisting>
     </example>
    </para>
--- 414,421 ----
  # cases.  (If you prefer to use ident authorization, an ident map can
  # serve a parallel purpose to the password list file used here.)

! local        sameuser   all                                            md5
! local        all        @admins                                        md5
  </programlisting>
     </example>
    </para>
***************
*** 490,575 ****
     <title>Password authentication</title>

     <indexterm>
!     <primary>password</primary>
     </indexterm>
     <indexterm>
!     <primary>MD5</>
     </indexterm>

     <para>
      Password-based authentication methods include <literal>md5</>,
!     <literal>crypt</>, and <literal>password</>.  These methods operate
      similarly except for the way that the password is sent across the
!     connection.  If you are at all concerned about password <quote>sniffing</>
!     attacks then <literal>md5</> is preferred, with <literal>crypt</> a
!     second choice if you must support obsolete clients.  Plain
!     <literal>password</> should especially be avoided for connections over
!     the open Internet (unless you use SSL, SSH, or other communications
!     security wrappers around the connection).
     </para>

     <para>
!     <productname>PostgreSQL</productname> database passwords are separate from
!     operating system user passwords. Ordinarily, the password for each
!     database user is stored in the pg_shadow system catalog table.
!     Passwords can be managed with the query language commands
!     <command>CREATE USER</command> and <command>ALTER USER</command>,
!     e.g., <userinput>CREATE USER foo WITH PASSWORD
!     'secret';</userinput>. By default, that is, if no password has
!     been set up, the stored password is <literal>NULL</literal>
!     and password authentication will always fail for that user.
     </para>

     <para>
      To restrict the set of users that are allowed to connect to certain
!     databases, list the set of users in a separate file (one user name
!     per line) in the same directory that <filename>pg_hba.conf</> is in,
!     and mention the (base) name of the file after the
!     <literal>password</>, <literal>md5</>, or <literal>crypt</> keyword,
!     respectively, in <filename>pg_hba.conf</>. If you do not use this
!     feature, then any user that is known to the database system can
!     connect to any database (so long as he supplies the correct password,
!     of course).
!    </para>
!
!    <para>
!     These files can also be used to apply a different set of passwords
!     to a particular database or set thereof. In that case, the files
!     have a format similar to the standard Unix password file
!     <filename>/etc/passwd</filename>, that is,
! <synopsis>
! <replaceable>username</replaceable>:<replaceable>password</replaceable>
! </synopsis>
!     Any extra colon-separated fields following the password are
!     ignored. The password is expected to be encrypted using the
!     system's <function>crypt()</function> function. The utility
!     program <application>pg_passwd</application> that is installed
!     with <productname>PostgreSQL</productname> can be used to manage
!     these password files.
!    </para>
!
!    <para>
!     Lines with and without passwords can be mixed in secondary
!     password files. Lines without password indicate use of the main
!     password in <literal>pg_shadow</> that is managed by
!     <command>CREATE USER</> and <command>ALTER USER</>. Lines with
!     passwords will cause that password to be used. A password entry of
!     <quote>+</quote> also means using the pg_shadow password.
!    </para>
!
!    <para>
!     Alternative passwords cannot be used when using the <literal>md5</>
!     or <literal>crypt</> methods. The file will be read as
!     usual, but the password field will simply be ignored and the
!     <literal>pg_shadow</> password will always be used.
!    </para>
!
!    <para>
!     Note that using alternative passwords like this means that one can
!     no longer use <command>ALTER USER</command> to change one's
!     password. It will appear to work but the password one is
!     changing is not the password that the system will end up
!     using.
     </para>

    </sect2>
--- 475,522 ----
     <title>Password authentication</title>

     <indexterm>
!     <primary>MD5</>
     </indexterm>
     <indexterm>
!     <primary>crypt</>
!    </indexterm>
!    <indexterm>
!     <primary>password</primary>
     </indexterm>

     <para>
      Password-based authentication methods include <literal>md5</>,
!     <literal>crypt</>, and <literal>password</>. These methods operate
      similarly except for the way that the password is sent across the
!     connection. If you are at all concerned about password
!     <quote>sniffing</> attacks then <literal>md5</> is preferred, with
!     <literal>crypt</> a second choice if you must support pre-7.2
!     clients. Plain <literal>password</> should especially be avoided for
!     connections over the open Internet (unless you use SSL, SSH, or
!     other communications security wrappers around the connection).
     </para>

     <para>
!     <productname>PostgreSQL</productname> database passwords are
!     separate from operating system user passwords. Ordinarily, the
!     password for each database user is stored in the pg_shadow system
!     catalog table. Passwords can be managed with the query language
!     commands <command>CREATE USER</command> and <command>ALTER
!     USER</command>, e.g., <userinput>CREATE USER foo WITH PASSWORD
!     'secret';</userinput>. By default, that is, if no password has been
!     set up, the stored password is <literal>NULL</literal> and password
!     authentication will always fail for that user.
     </para>

     <para>
      To restrict the set of users that are allowed to connect to certain
!     databases, list the users separated by commas, or in a separate
!     file. The file should contain user names separated by commas or one
!     user name per line, and be in the same directory as
!     <filename>pg_hba.conf</>. Mention the (base) name of the file
!     preceded by <literal>@</>in the <literal>USER</> column. The
!     <literal>DATABASE</> column can similarly accept a list of values or
!     a file name.
     </para>

    </sect2>
***************
*** 588,597 ****
      <productname>Kerberos</productname> system is far beyond the scope
      of this document; in all generality it can be quite complex (yet
      powerful). The <ulink
!     url="http://www.nrl.navy.mil/CCS/people/kenh/kerberos-faq.html">Kerberos
!     <acronym>FAQ</></ulink> or <ulink
!     url="ftp://athena-dist.mit.edu">MIT Project Athena</ulink> can be
!     a good starting point for exploration. Several sources for
      <productname>Kerberos</> distributions exist.
     </para>

--- 535,544 ----
      <productname>Kerberos</productname> system is far beyond the scope
      of this document; in all generality it can be quite complex (yet
      powerful). The <ulink
!     url="http://www.nrl.navy.mil/CCS/people/kenh/kerberos-faq.html">Kerb
!     eros <acronym>FAQ</></ulink> or <ulink
!     url="ftp://athena-dist.mit.edu">MIT Project Athena</ulink> can be a
!     good starting point for exploration. Several sources for
      <productname>Kerberos</> distributions exist.
     </para>

***************
*** 606,639 ****
     <para>
      <productname>PostgreSQL</> operates like a normal Kerberos service.
      The name of the service principal is
!     <replaceable>servicename/hostname@realm</>, where
!     <replaceable>servicename</> is <literal>postgres</literal>
!     (unless a different service name was selected at configure time
!     with <literal>./configure --with-krb-srvnam=whatever</>).
!     <replaceable>hostname</> is the fully qualified domain name of the server
!     machine.  The service principal's realm is the preferred realm of the
!     server machine.
     </para>

     <para>
!     Client principals must have their <productname>PostgreSQL</> user name as
!     their first component, for example
!     <replaceable>pgusername/otherstuff@realm</>.
!     At present the realm of the client is not checked by
!     <productname>PostgreSQL</>; so
!     if you have cross-realm authentication enabled, then any principal
!     in any realm that can communicate with yours will be accepted.
     </para>

     <para>
!     Make sure that your server key file is readable (and
!     preferably only readable) by the
!     <productname>PostgreSQL</productname> server account (see
!     <xref linkend="postgres-user">). The location of the key file
!     is specified with the <varname>krb_server_keyfile</> run time
!     configuration parameter. (See also <xref linkend="runtime-config">.)
!     The default is <filename>/etc/srvtab</> if you are using Kerberos 4
!     and <filename>FILE:/usr/local/pgsql/etc/krb5.keytab</> (or whichever
      directory was specified as <varname>sysconfdir</> at build time)
      with Kerberos 5.
     </para>
--- 553,585 ----
     <para>
      <productname>PostgreSQL</> operates like a normal Kerberos service.
      The name of the service principal is
!     <replaceable>servicename/hostname@realm</>, where
!     <replaceable>servicename</> is <literal>postgres</literal> (unless a
!     different service name was selected at configure time with
!     <literal>./configure --with-krb-srvnam=whatever</>).
!     <replaceable>hostname</> is the fully qualified domain name of the
!     server machine. The service principal's realm is the preferred realm
!     of the server machine.
     </para>

     <para>
!     Client principals must have their <productname>PostgreSQL</> user
!     name as their first component, for example
!     <replaceable>pgusername/otherstuff@realm</>. At present the realm of
!     the client is not checked by <productname>PostgreSQL</>; so if you
!     have cross-realm authentication enabled, then any principal in any
!     realm that can communicate with yours will be accepted.
     </para>

     <para>
!     Make sure that your server key file is readable (and preferably only
!     readable) by the <productname>PostgreSQL</productname> server
!     account (see <xref linkend="postgres-user">). The location of the
!     key file is specified with the <varname>krb_server_keyfile</> run
!     time configuration parameter. (See also <xref
!     linkend="runtime-config">.) The default is <filename>/etc/srvtab</>
!     if you are using Kerberos 4 and
!     <filename>FILE:/usr/local/pgsql/etc/krb5.keytab</> (or whichever
      directory was specified as <varname>sysconfdir</> at build time)
      with Kerberos 5.
     </para>
***************
*** 649,666 ****

     <para>
      When connecting to the database make sure you have a ticket for a
!     principal matching the requested database user name.
!     An example: For database user name <literal>fred</>, both principal
      <literal>fred@EXAMPLE.COM</> and
!     <literal>fred/users.example.com@EXAMPLE.COM</> can be
!     used to authenticate to the database server.
     </para>

     <para>
!     If you use <application>mod_auth_krb</application> and <application>mod_perl</application> on your
<productname>Apache</productname>web server, 
!     you can use <literal>AuthType KerberosV5SaveCredentials</literal> with a <application>mod_perl</application>
!     script. This gives secure database access over the web, no extra
!     passwords required.
     </para>

    </sect2>
--- 595,614 ----

     <para>
      When connecting to the database make sure you have a ticket for a
!     principal matching the requested database user name. An example: For
!     database user name <literal>fred</>, both principal
      <literal>fred@EXAMPLE.COM</> and
!     <literal>fred/users.example.com@EXAMPLE.COM</> can be used to
!     authenticate to the database server.
     </para>

     <para>
!     If you use <application>mod_auth_krb</application> and
!     <application>mod_perl</application> on your
!     <productname>Apache</productname> web server, you can use
!     <literal>AuthType KerberosV5SaveCredentials</literal> with a
!     <application>mod_perl</application> script. This gives secure
!     database access over the web, no extra passwords required.
     </para>

    </sect2>
***************
*** 707,761 ****
     </para>

     <para>
!     On systems supporting <symbol>SO_PEERCRED</symbol> requests for Unix-domain sockets,
!     ident authentication can also be applied to local connections.  In this
!     case, no security risk is added by using ident authentication; indeed
!     it is a preferable choice for local connections on such a system.
     </para>

     <para>
      When using ident-based authentication, after having determined the
      name of the operating system user that initiated the connection,
!     <productname>PostgreSQL</productname> checks whether that user is allowed
!     to connect as the database user he is requesting to connect as.
!     This is controlled by the ident map
!     argument that follows the <literal>ident</> keyword in the
!     <filename>pg_hba.conf</filename> file. There is a predefined ident map
!     <literal>sameuser</literal>, which allows any operating system
!     user to connect as the database user of the same name (if the
!     latter exists). Other maps must be created manually.
     </para>

     <para>
!     <indexterm><primary>pg_ident.conf</primary></indexterm>
!     Ident maps other than <literal>sameuser</literal> are defined
!     in the file <filename>pg_ident.conf</filename>
!     in the data directory, which contains lines of the general form:
  <synopsis>
  <replaceable>map-name</> <replaceable>ident-username</> <replaceable>database-username</>
  </synopsis>
!     Comments and whitespace are handled in the usual way.
!     The <replaceable>map-name</> is an arbitrary name that will be
!     used to refer to this mapping in <filename>pg_hba.conf</filename>.
!     The other two fields specify which operating system user is
!     allowed to connect as which database user. The same
!     <replaceable>map-name</> can be used repeatedly to specify more
!     user-mappings within a single map. There is no restriction regarding
!     how many
!     database users a given operating system user may correspond to and vice
!     versa.
     </para>

    <para>
      <indexterm>
       <primary>SIGHUP</primary>
      </indexterm>
!    The <filename>pg_ident.conf</filename> file is read on startup
!    and when the <application>postmaster</> receives a
     <systemitem>SIGHUP</systemitem> signal. If you edit the file on an
     active system, you will need to signal the <application>postmaster</>
!    (using <literal>pg_ctl reload</> or <literal>kill -HUP</>)
!    to make it re-read the file.
    </para>

     <para>
--- 655,708 ----
     </para>

     <para>
!     On systems supporting <symbol>SO_PEERCRED</symbol> requests for
!     Unix-domain sockets, ident authentication can also be applied to
!     local connections. 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>
      When using ident-based authentication, after having determined the
      name of the operating system user that initiated the connection,
!     <productname>PostgreSQL</productname> checks whether that user is
!     allowed to connect as the database user he is requesting to connect
!     as. This is controlled by the ident map argument that follows the
!     <literal>ident</> keyword in the <filename>pg_hba.conf</filename>
!     file. There is a predefined ident map <literal>sameuser</literal>,
!     which allows any operating system user to connect as the database
!     user of the same name (if the latter exists). Other maps must be
!     created manually.
     </para>

     <para>
!     <indexterm><primary>pg_ident.conf</primary></indexterm> Ident maps
!     other than <literal>sameuser</literal> are defined in the file
!     <filename>pg_ident.conf</filename> in the data directory, which
!     contains lines of the general form:
  <synopsis>
  <replaceable>map-name</> <replaceable>ident-username</> <replaceable>database-username</>
  </synopsis>
!     Comments and whitespace are handled in the usual way. The
!     <replaceable>map-name</> is an arbitrary name that will be used to
!     refer to this mapping in <filename>pg_hba.conf</filename>. The other
!     two fields specify which operating system user is allowed to connect
!     as which database user. The same <replaceable>map-name</> can be
!     used repeatedly to specify more user-mappings within a single map.
!     There is no restriction regarding how many database users a given
!     operating system user may correspond to and vice versa.
     </para>

    <para>
      <indexterm>
       <primary>SIGHUP</primary>
      </indexterm>
!    The <filename>pg_ident.conf</filename> file is read on startup and
!    when the <application>postmaster</> receives a
     <systemitem>SIGHUP</systemitem> signal. If you edit the file on an
     active system, you will need to signal the <application>postmaster</>
!    (using <literal>pg_ctl reload</> or <literal>kill -HUP</>) to make it
!    re-read the file.
    </para>

     <para>
***************
*** 763,775 ****
      conjunction with the <filename>pg_hba.conf</> file in <xref
      linkend="example-pg-hba.conf"> is shown in <xref
      linkend="example-pg-ident.conf">. In this example setup, anyone
!     logged in to a machine on the 192.168 network that does not have
!     the Unix user name <systemitem>bryanh</>, <systemitem>ann</>, or <systemitem>robert</> would not be granted
access.
!     Unix user <systemitem>robert</> would only be allowed access when he tries to
!     connect as <productname>PostgreSQL</> user <systemitem>bob</>,
!       not as <systemitem>robert</>
!     or anyone else. <systemitem>ann</> would only be allowed to connect as
!     <systemitem>ann</>. User <systemitem>bryanh</> would be allowed to connect as either
      <systemitem>bryanh</> himself or as <systemitem>guest1</>.
     </para>

--- 710,723 ----
      conjunction with the <filename>pg_hba.conf</> file in <xref

Re: Adding usernames to pg_hba.conf

From
Bruce Momjian
Date:
Sorry, the previous posting didn't have the full patch.  This one does.

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

pgman wrote:
> This patch completes the following TODO item:
>
>     * Allow usernames to be specified directly in pg_hba.conf (Bruce)
>
> Currently, we allow usernames in secondary password files, but this is a
> very confusing feature.  This patch:
>
>     o  removes secondary password file support
>     o  adds a user name column just after the database column
>     o  allows a comma separated list of usernames or databases
>     o  allows another file to contain a list of username/databases
>        by preceding the pg_hba.conf entry with '@'
>     o  allow single or double-quoting of user/database names
>
> See the documentation changes and new pg_hba.conf diffs for samples.
>
> Is the '@' sign a good way to identify a file name?  Is putting the
> username column just after the database column the right place for it?

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
Index: doc/src/sgml/client-auth.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/client-auth.sgml,v
retrieving revision 1.32
diff -c -r1.32 client-auth.sgml
*** doc/src/sgml/client-auth.sgml    20 Jan 2002 22:19:55 -0000    1.32
--- doc/src/sgml/client-auth.sgml    19 Mar 2002 05:51:45 -0000
***************
*** 10,23 ****
   </indexterm>

   <para>
!   When a client application connects to the database server, it specifies which
!   <productname>PostgreSQL</productname> user name it wants to connect as,
!   much the same way one logs into a Unix computer as a particular user.
!   Within the SQL environment the active
!   database user name determines access privileges to database
!   objects -- see <xref linkend="user-manag"> for more information
!   about that. It is therefore obviously essential to restrict which
!   database user name(s) a given client can connect as.
   </para>

   <para>
--- 10,23 ----
   </indexterm>

   <para>
!   When a client application connects to the database server, it
!   specifies which <productname>PostgreSQL</productname> user name it
!   wants to connect as, much the same way one logs into a Unix computer
!   as a particular user. Within the SQL environment the active database
!   user name determines access privileges to database objects -- see
!   <xref linkend="user-manag"> for more information about that. It is
!   therefore obviously essential to restrict which database user name(s)
!   a given client can connect as.
   </para>

   <para>
***************
*** 30,49 ****

   <para>
    <productname>PostgreSQL</productname> offers a number of different
!   client authentication methods.  The method to be used can be selected
!   on the basis of (client) host and database; some authentication methods
!   allow you to restrict by user name as well.
   </para>

   <para>
!   <productname>PostgreSQL</productname> database user names are logically
    separate from user names of the operating system in which the server
!   runs.  If all the users of a particular server also have accounts on
    the server's machine, it makes sense to assign database user names
!   that match their operating system user names.  However, a server that accepts remote
!   connections may have many users who have no local account, and in such
!   cases there need be no connection between database user names and OS
!   user names.
   </para>

   <sect1 id="pg-hba-conf">
--- 30,48 ----

   <para>
    <productname>PostgreSQL</productname> offers a number of different
!   client authentication methods. The method to be used can be selected
!   on the basis of (client) host, database, and user.
   </para>

   <para>
!   <productname>PostgreSQL</productname> user names are logically
    separate from user names of the operating system in which the server
!   runs. If all the users of a particular server also have accounts on
    the server's machine, it makes sense to assign database user names
!   that match their operating system user names. However, a server that
!   accepts remote connections may have many users who have no local
!   account, and in such cases there need be no connection between
!   database user names and OS user names.
   </para>

   <sect1 id="pg-hba-conf">
***************
*** 56,94 ****
    <para>
     Client authentication is controlled by the file
     <filename>pg_hba.conf</filename> in the data directory, e.g.,
!    <filename>/usr/local/pgsql/data/pg_hba.conf</filename>. (<acronym>HBA</> stands
!    for host-based authentication.) A default <filename>pg_hba.conf</filename>
!    file is installed when the
!    data area is initialized by <command>initdb</command>.
    </para>

    <para>
!    The general format of the <filename>pg_hba.conf</filename> file is
!    of a set of records, one per line. Blank lines and lines beginning
!    with a hash character (<quote>#</quote>) are ignored. A record is
!    made up of a number of fields which are separated by spaces and/or
!    tabs.  Records cannot be continued across lines.
    </para>

    <para>
     Each record specifies a connection type, a client IP address range
!    (if relevant for the connection type), a database name or names,
     and the authentication method to be used for connections matching
!    these parameters.
!    The first record that matches the type, client address, and requested
!    database name of a connection attempt is used to do the
!    authentication step.  There is no <quote>fall-through</> or
     <quote>backup</>: if one record is chosen and the authentication
!    fails, the following records are not considered. If no record
!    matches, the access will be denied.
    </para>

    <para>
     A record may have one of the three formats
     <synopsis>
! local   <replaceable>database</replaceable> <replaceable>authentication-method</replaceable> [
<replaceable>authentication-option</replaceable>] 
! host    <replaceable>database</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable>
<replaceable>authentication-method</replaceable>[ <replaceable>authentication-option</replaceable> ] 
! hostssl <replaceable>database</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable>
<replaceable>authentication-method</replaceable>[ <replaceable>authentication-option</replaceable> ] 
      </synopsis>
     The meaning of the fields is as follows:

--- 55,93 ----
    <para>
     Client authentication is controlled by the file
     <filename>pg_hba.conf</filename> in the data directory, e.g.,
!    <filename>/usr/local/pgsql/data/pg_hba.conf</filename>.
!    (<acronym>HBA</> stands for host-based authentication.) A default
!    <filename>pg_hba.conf</filename> file is installed when the data area
!    is initialized by <command>initdb</command>.
    </para>

    <para>
!    The general format of the <filename>pg_hba.conf</filename> file is of
!    a set of records, one per line. Blank lines are ignored, as is any
!    text after the <quote>#</quote> comment character. A record is made
!    up of a number of fields which are separated by spaces and/or tabs.
!    Fields can contain white space if the field value is quoted. Records
!    cannot be continued across lines.
    </para>

    <para>
     Each record specifies a connection type, a client IP address range
!    (if relevant for the connection type), a database name, a user name,
     and the authentication method to be used for connections matching
!    these parameters. The first record with a matching connection type,
!    client address, requested database, and user name is used to peform
!    authentication. There is no <quote>fall-through</> or
     <quote>backup</>: if one record is chosen and the authentication
!    fails, subsequent records are not considered. If no record matches,
!    access is denied.
    </para>

    <para>
     A record may have one of the three formats
     <synopsis>
! local   <replaceable>database</replaceable> <replaceable>user</replaceable>
<replaceable>authentication-method</replaceable>[ <replaceable>authentication-option</replaceable> ] 
! host    <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable>
<replaceable>IP-mask</replaceable><replaceable>authentication-method</replaceable> 
! hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable>
<replaceable>IP-mask</replaceable><replaceable>authentication-method</replaceable> 
      </synopsis>
     The meaning of the fields is as follows:

***************
*** 97,103 ****
       <term><literal>local</literal></term>
       <listitem>
        <para>
!        This record pertains to connection attempts over Unix domain
         sockets.
        </para>
       </listitem>
--- 96,102 ----
       <term><literal>local</literal></term>
       <listitem>
        <para>
!        This record applies to connection attempts using Unix domain
         sockets.
        </para>
       </listitem>
***************
*** 107,116 ****
       <term><literal>host</literal></term>
       <listitem>
        <para>
!        This record pertains to connection attempts over TCP/IP
!        networks. Note that TCP/IP connections are completely disabled
!        unless the server is started with the <option>-i</option> switch or
!        the equivalent configuration parameter is set.
        </para>
       </listitem>
      </varlistentry>
--- 106,116 ----
       <term><literal>host</literal></term>
       <listitem>
        <para>
!        This record applied to connection attempts using TCP/IP networks.
!        Note that TCP/IP connections are disabled unless the server is
!        started with the <option>-i</option> option or the
!        <literal>tcpip_socket</> <filename>postgresql.conf</>
!        configuration parameter is enabled.
        </para>
       </listitem>
      </varlistentry>
***************
*** 119,131 ****
       <term><literal>hostssl</literal></term>
       <listitem>
        <para>
!        This record pertains to connection attempts with SSL over
         TCP/IP. To make use of this option the server must be
         built with SSL support enabled. Furthermore, SSL must be
         enabled with the <option>-l</> option or equivalent configuration
         setting when the server is started.  (Note: <literal>host</literal>
         records will match either SSL or non-SSL connection attempts, but
!        <literal>hostssl</literal> records match only SSL connections.)
        </para>
       </listitem>
      </varlistentry>
--- 119,131 ----
       <term><literal>hostssl</literal></term>
       <listitem>
        <para>
!        This record applies to connection attempts using SSL over
         TCP/IP. To make use of this option the server must be
         built with SSL support enabled. Furthermore, SSL must be
         enabled with the <option>-l</> option or equivalent configuration
         setting when the server is started.  (Note: <literal>host</literal>
         records will match either SSL or non-SSL connection attempts, but
!        <literal>hostssl</literal> records requires SSL connections.)
        </para>
       </listitem>
      </varlistentry>
***************
*** 134,145 ****
       <term><replaceable>database</replaceable></term>
       <listitem>
        <para>
!        Specifies the database that this record applies to. The value
         <literal>all</literal> specifies that it applies to all
         databases, while the value <literal>sameuser</> identifies the
!        database with the same name as the connecting user.  Otherwise,
!        this is the name of a specific <productname>PostgreSQL</productname>
!        database.
        </para>
       </listitem>
      </varlistentry>
--- 134,165 ----
       <term><replaceable>database</replaceable></term>
       <listitem>
        <para>
!        Specifies the database for this record. The value
         <literal>all</literal> specifies that it applies to all
         databases, while the value <literal>sameuser</> identifies the
!        database with the same name as the connecting user. Otherwise,
!        this is the name of a specific
!        <productname>PostgreSQL</productname> database. Multiple database
!        names can be supplied by separating them with commas. A file
!        containing database names can be specified by preceding the file
!        name with <literal>@</>. The file must be in the same directory
!        as <filename>pg_hba.conf</>.
!       </para>
!      </listitem>
!     </varlistentry>
!
!     <varlistentry>
!      <term><replaceable>user</replaceable></term>
!      <listitem>
!       <para>
!        Specifies the user for this record. The value
!        <literal>all</literal> specifies that it applies to all users.
!        Otherwise, this is the name of a specific
!        <productname>PostgreSQL</productname> user. Multiple user
!        names can be supplied by separating them with commas. A file
!        containing user names can be specified by preceding the file
!        name with <literal>@</>. The file must be in the same directory
!        as <filename>pg_hba.conf</>.
        </para>
       </listitem>
      </varlistentry>
***************
*** 149,158 ****
       <term><replaceable>IP mask</replaceable></term>
       <listitem>
        <para>
!        These two fields specify to which client machines a
!        <literal>host</literal> or <literal>hostssl</literal>
!        record applies, based on their IP
!        address. (Of course IP addresses can be spoofed but this
         consideration is beyond the scope of
         <productname>PostgreSQL</productname>.) The precise logic is that
         <blockquote>
--- 169,177 ----
       <term><replaceable>IP mask</replaceable></term>
       <listitem>
        <para>
!        These two fields specify the client machine IP addresses
!        (<literal>host</literal> or <literal>hostssl</literal>) for this
!        record. (Of course IP addresses can be spoofed but this
         consideration is beyond the scope of
         <productname>PostgreSQL</productname>.) The precise logic is that
         <blockquote>
***************
*** 169,178 ****
       <term><replaceable>authentication method</replaceable></term>
       <listitem>
        <para>
!        Specifies the method that users must use to authenticate themselves
!        when connecting under the control of this authentication record.
!        The possible choices are summarized here,
!        details are in <xref linkend="auth-methods">.

         <variablelist>
          <varlistentry>
--- 188,196 ----
       <term><replaceable>authentication method</replaceable></term>
       <listitem>
        <para>
!        Specifies the authentication method to use when connecting via
!        this record. The possible choices are summarized here; details
!        are in <xref linkend="auth-methods">.

         <variablelist>
          <varlistentry>
***************
*** 190,255 ****
          <term><literal>reject</></term>
          <listitem>
           <para>
!           The connection is rejected unconditionally. This is mostly
!           useful to <quote>filter out</> certain hosts from a group.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term><literal>password</></term>
          <listitem>
           <para>
!           The client is required to supply a password which is required to
!       match the database password that was set up for the user.
!          </para>
!
!          <para>
!           An optional file name may be specified after the
!           <literal>password</literal> keyword. This file is expected to
!           contain a list of users who may connect using this record,
!           and optionally alternative passwords for them.
!          </para>
!
!          <para>
!           The password is sent over the wire in clear text. For better
!           protection, use the <literal>md5</literal> or
!           <literal>crypt</literal> methods.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term><literal>md5</></term>
          <listitem>
           <para>
!           Like the <literal>password</literal> method, but the password
!           is sent over the wire encrypted using a simple
!           challenge-response protocol. This protects against incidental
!           wire-sniffing.  This is now the recommended choice for
!       password-based authentication.
!          </para>
!
!          <para>
!       The name of a file may follow the
!           <literal>md5</literal> keyword.  It contains a list of users
!           who may connect using this record.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term><literal>crypt</></term>
          <listitem>
           <para>
!           Like the <literal>md5</literal> method but uses older crypt
!           encryption, which is needed for pre-7.2
!       clients. <literal>md5</literal> is
!           preferred for 7.2 and later clients. The <literal>crypt</>
!           method is not compatible with encrypting passwords in
!           <filename>pg_shadow</>, and may fail if client and server
!           machines have different implementations of the crypt() library
!           routine.
           </para>
          </listitem>
         </varlistentry>
--- 208,248 ----
          <term><literal>reject</></term>
          <listitem>
           <para>
!           The connection is rejected unconditionally. This is useful for
!           <quote>filtering out</> certain hosts from a group.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term><literal>md5</></term>
          <listitem>
           <para>
!           Requires the client to supply an MD5 encrypted password for
!           authentication. This is the only method that allows encrypted
!           passwords to be stored in pg_shadow.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term><literal>crypt</></term>
          <listitem>
           <para>
!           Like <literal>md5</literal> method but uses older crypt
!           encryption, which is needed for pre-7.2 clients.
!           <literal>md5</literal> is preferred for 7.2 and later clients.
           </para>
          </listitem>
         </varlistentry>

         <varlistentry>
!         <term><literal>password</></term>
          <listitem>
           <para>
!           Same as "md5", but the password is sent in cleartext over the
!           network. This should not be used on untrusted networks.
!          </para>
           </para>
          </listitem>
         </varlistentry>
***************
*** 278,311 ****
          <term><literal>ident</></term>
          <listitem>
       <para>
!       The identity of the user as determined on login to the
!       operating system is used by <productname>PostgreSQL</productname>
!       to determine whether the user
!           is allowed to connect as the requested database user.
!       For TCP/IP connections the user's identity is determined by
!       contacting the <firstterm>ident</firstterm> server on the client
!       host.  (Note that this is only as reliable as the remote ident
!       server; ident authentication should never be used for remote hosts
!       whose administrators are not trustworthy.)
!       On operating systems
!       supporting <symbol>SO_PEERCRED</> requests for Unix domain sockets,
!       ident authentication is possible for local connections;
!       the system is then asked for the connecting user's identity.
       </para>
           <para>
!       On systems without <symbol>SO_PEERCRED</> requests, ident authentication
!       is only available for TCP/IP connections.  As a workaround,
!       it is possible to
!       specify the <systemitem class="systemname">localhost</> address
!           <systemitem class="systemname">127.0.0.1</> and make connections
!       to this address.
!      </para>
!          <para>
!           The <replaceable>authentication option</replaceable> following
!           the <literal>ident</> keyword specifies the name of an
!           <firstterm>ident map</firstterm> that specifies which operating
!           system users equate with which database users. See below for
!           details.
           </para>
          </listitem>
         </varlistentry>
--- 271,306 ----
          <term><literal>ident</></term>
          <listitem>
       <para>
!           For TCP/IP connections, authentication is done by contacting
!           the <firstterm>ident</firstterm> server on the client host.
!           This is only as secure as the client machine. You must specify
!           the map name after the 'ident' keyword. It determines how to
!           map remote user names to PostgreSQL user names. If you use
!           "sameuser", the user names are assumed to be identical. If
!           not, the map name is looked up in the $PGDATA/pg_ident.conf
!           file. The connection is accepted if that file contains an
!           entry for this map name with the ident-supplied username and
!           the requested PostgreSQL username.
!          </para>
!          <para>
!           On machines that support unix-domain socket credentials
!           (currently Linux, FreeBSD, NetBSD, and BSD/OS), ident allows
!           reliable authentication of 'local' connections without ident
!           running on the local machine.
!          </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.
       </para>
           <para>
!           Following the <literal>ident</> keyword, an <firstterm>ident
!           map</firstterm> name should be supplied which specifies which
!           operating system users equate with which database users. See
!           below for details.
           </para>
          </listitem>
         </varlistentry>
***************
*** 315,331 ****
          <listitem>
           <para>
            This authentication type operates similarly to
!           <firstterm>password</firstterm>, with the main difference that
!           it will use PAM (Pluggable Authentication Modules) as the
!           authentication mechanism. The <replaceable>authentication
!           option</replaceable> following the <literal>pam</> keyword
!           specifies the service name that will be passed to PAM. The
!           default service name is <literal>postgresql</literal>.
!           For more information about PAM, please read the <ulink
!           url="http://www.kernel.org/pub/linux/libs/pam/"><productname>Linux-PAM</productname>
!           Page</ulink> and/or the <ulink
!           url="http://www.sun.com/software/solaris/pam/"><systemitem class="osname">Solaris</> PAM
!           Page</ulink>.
           </para>
          </listitem>
         </varlistentry>
--- 310,325 ----
          <listitem>
           <para>
            This authentication type operates similarly to
!           <firstterm>password</firstterm> except that it uses PAM
!           (Pluggable Authentication Modules) as the authentication
!           mechanism. The default PAM service name is
!           <literal>postgresql</literal>. You can optionally supply you
!           own service name after the <literal>pam</> keyword in the
!           file. For more information about PAM, please read the <ulink
!           url="http://www.kernel.org/pub/linux/libs/pam/"><productname>L
!           inux-PAM</productname> Page</ulink> and the <ulink
!           url="http://www.sun.com/software/solaris/pam/"><systemitem
!           class="osname">Solaris</> PAM Page</ulink>.
           </para>
          </listitem>
         </varlistentry>
***************
*** 336,377 ****
       </listitem>
      </varlistentry>

-     <varlistentry>
-      <term><replaceable>authentication option</replaceable></term>
-      <listitem>
-       <para>
-        This field is interpreted differently depending on the
-        authentication method, as described above.
-       </para>
-      </listitem>
-     </varlistentry>
     </variablelist>
    </para>

    <para>
     Since the <filename>pg_hba.conf</filename> records are examined
     sequentially for each connection attempt, the order of the records is
!    very significant.  Typically, earlier records will have tight
!    connection match parameters and weaker authentication methods,
!    while later records will have looser match parameters and stronger
!    authentication methods.  For example, one might wish to use
!    <literal>trust</> authentication for local TCP connections but
!    require a password for remote TCP connections.  In this case a
!    record specifying <literal>trust</> authentication for connections
!    from 127.0.0.1 would appear before a record specifying password
!    authentication for a wider range of allowed client IP addresses.
    </para>

    <para>
      <indexterm>
       <primary>SIGHUP</primary>
      </indexterm>
!    The <filename>pg_hba.conf</filename> file is read on startup
!    and when the <application>postmaster</> receives a
     <systemitem>SIGHUP</systemitem> signal. If you edit the file on an
     active system, you will need to signal the <application>postmaster</>
!    (using <literal>pg_ctl reload</> or <literal>kill -HUP</>)
!    to make it re-read the file.
    </para>

    <para>
--- 330,362 ----
       </listitem>
      </varlistentry>

     </variablelist>
    </para>

    <para>
     Since the <filename>pg_hba.conf</filename> records are examined
     sequentially for each connection attempt, the order of the records is
!    significant. Typically, earlier records will have tight connection
!    match parameters and weaker authentication methods, while later
!    records will have looser match parameters and stronger authentication
!    methods. For example, one might wish to use <literal>trust</>
!    authentication for local TCP connections but require a password for
!    remote TCP connections. In this case a record specifying
!    <literal>trust</> authentication for connections from 127.0.0.1 would
!    appear before a record specifying password authentication for a wider
!    range of allowed client IP addresses.
    </para>

    <para>
      <indexterm>
       <primary>SIGHUP</primary>
      </indexterm>
!    The <filename>pg_hba.conf</filename> file is read on startup and when
!    the <application>postmaster</> receives a
     <systemitem>SIGHUP</systemitem> signal. If you edit the file on an
     active system, you will need to signal the <application>postmaster</>
!    (using <literal>pg_ctl reload</> or <literal>kill -HUP</>) to make it
!    re-read the file.
    </para>

    <para>
***************
*** 382,408 ****
     <example id="example-pg-hba.conf">
      <title>An example <filename>pg_hba.conf</filename> file</title>
  <programlisting>
! # TYPE       DATABASE    IP_ADDRESS    MASK               AUTHTYPE  MAP

  # Allow any user on the local system to connect to any
  # database under any username, but only via an IP connection:

! host         all         127.0.0.1     255.255.255.255    trust

  # The same, over Unix-socket connections:

! local        all                                          trust

  # Allow any user from any host with IP address 192.168.93.x to
  # connect to database "template1" as the same username that ident on that
  # host identifies him as (typically his Unix username):

! host         template1   192.168.93.0  255.255.255.0      ident     sameuser

  # Allow a user from host 192.168.12.10 to connect to database "template1"
! # if the user's password in pg_shadow is correctly supplied:

! host         template1   192.168.12.10 255.255.255.255    md5

  # In the absence of preceding "host" lines, these two lines will reject
  # all connection attempts from 192.168.54.1 (since that entry will be
--- 367,393 ----
     <example id="example-pg-hba.conf">
      <title>An example <filename>pg_hba.conf</filename> file</title>
  <programlisting>
! # TYPE       DATABASE    USER       IP_ADDRESS    MASK               AUTHTYPE

  # Allow any user on the local system to connect to any
  # database under any username, but only via an IP connection:

! host         all         all        127.0.0.1     255.255.255.255    trust

  # The same, over Unix-socket connections:

! local        all         all                                         trust

  # Allow any user from any host with IP address 192.168.93.x to
  # connect to database "template1" as the same username that ident on that
  # host identifies him as (typically his Unix username):

! host         template1   all        192.168.93.0  255.255.255.0      ident sameuser

  # Allow a user from host 192.168.12.10 to connect to database "template1"
! # if the user's password is correctly supplied:

! host         template1   all        192.168.12.10 255.255.255.255    md5

  # In the absence of preceding "host" lines, these two lines will reject
  # all connection attempts from 192.168.54.1 (since that entry will be
***************
*** 410,417 ****
  # else on the Internet. The zero mask means that no bits of the host IP
  # address are considered, so it matches any host:

! host         all        192.168.54.1   255.255.255.255    reject
! host         all        0.0.0.0        0.0.0.0            krb5

  # Allow users from 192.168.x.x hosts to connect to any database, if they
  # pass the ident check.  If, for example, ident says the user is "bryanh"
--- 395,402 ----
  # else on the Internet. The zero mask means that no bits of the host IP
  # address are considered, so it matches any host:

! host         all        all         192.168.54.1   255.255.255.255    reject
! host         all        all         0.0.0.0        0.0.0.0            krb5

  # Allow users from 192.168.x.x hosts to connect to any database, if they
  # pass the ident check.  If, for example, ident says the user is "bryanh"
***************
*** 419,425 ****
  # is allowed if there is an entry in pg_ident.conf for map "omicron" that
  # says "bryanh" is allowed to connect as "guest1":

! host         all        192.168.0.0    255.255.0.0        ident     omicron

  # If these are the only two lines for local connections, they will allow
  # local users to connect only to their own databases (database named the
--- 404,410 ----
  # is allowed if there is an entry in pg_ident.conf for map "omicron" that
  # says "bryanh" is allowed to connect as "guest1":

! host         all        all         192.168.0.0    255.255.0.0        ident omicron

  # If these are the only two lines for local connections, they will allow
  # local users to connect only to their own databases (database named the
***************
*** 429,436 ****
  # cases.  (If you prefer to use ident authorization, an ident map can
  # serve a parallel purpose to the password list file used here.)

! local        sameuser                                     md5
! local        all                                          md5  admins
  </programlisting>
     </example>
    </para>
--- 414,421 ----
  # cases.  (If you prefer to use ident authorization, an ident map can
  # serve a parallel purpose to the password list file used here.)

! local        sameuser   all                                            md5
! local        all        @admins                                        md5
  </programlisting>
     </example>
    </para>
***************
*** 490,575 ****
     <title>Password authentication</title>

     <indexterm>
!     <primary>password</primary>
     </indexterm>
     <indexterm>
!     <primary>MD5</>
     </indexterm>

     <para>
      Password-based authentication methods include <literal>md5</>,
!     <literal>crypt</>, and <literal>password</>.  These methods operate
      similarly except for the way that the password is sent across the
!     connection.  If you are at all concerned about password <quote>sniffing</>
!     attacks then <literal>md5</> is preferred, with <literal>crypt</> a
!     second choice if you must support obsolete clients.  Plain
!     <literal>password</> should especially be avoided for connections over
!     the open Internet (unless you use SSL, SSH, or other communications
!     security wrappers around the connection).
     </para>

     <para>
!     <productname>PostgreSQL</productname> database passwords are separate from
!     operating system user passwords. Ordinarily, the password for each
!     database user is stored in the pg_shadow system catalog table.
!     Passwords can be managed with the query language commands
!     <command>CREATE USER</command> and <command>ALTER USER</command>,
!     e.g., <userinput>CREATE USER foo WITH PASSWORD
!     'secret';</userinput>. By default, that is, if no password has
!     been set up, the stored password is <literal>NULL</literal>
!     and password authentication will always fail for that user.
     </para>

     <para>
      To restrict the set of users that are allowed to connect to certain
!     databases, list the set of users in a separate file (one user name
!     per line) in the same directory that <filename>pg_hba.conf</> is in,
!     and mention the (base) name of the file after the
!     <literal>password</>, <literal>md5</>, or <literal>crypt</> keyword,
!     respectively, in <filename>pg_hba.conf</>. If you do not use this
!     feature, then any user that is known to the database system can
!     connect to any database (so long as he supplies the correct password,
!     of course).
!    </para>
!
!    <para>
!     These files can also be used to apply a different set of passwords
!     to a particular database or set thereof. In that case, the files
!     have a format similar to the standard Unix password file
!     <filename>/etc/passwd</filename>, that is,
! <synopsis>
! <replaceable>username</replaceable>:<replaceable>password</replaceable>
! </synopsis>
!     Any extra colon-separated fields following the password are
!     ignored. The password is expected to be encrypted using the
!     system's <function>crypt()</function> function. The utility
!     program <application>pg_passwd</application> that is installed
!     with <productname>PostgreSQL</productname> can be used to manage
!     these password files.
!    </para>
!
!    <para>
!     Lines with and without passwords can be mixed in secondary
!     password files. Lines without password indicate use of the main
!     password in <literal>pg_shadow</> that is managed by
!     <command>CREATE USER</> and <command>ALTER USER</>. Lines with
!     passwords will cause that password to be used. A password entry of
!     <quote>+</quote> also means using the pg_shadow password.
!    </para>
!
!    <para>
!     Alternative passwords cannot be used when using the <literal>md5</>
!     or <literal>crypt</> methods. The file will be read as
!     usual, but the password field will simply be ignored and the
!     <literal>pg_shadow</> password will always be used.
!    </para>
!
!    <para>
!     Note that using alternative passwords like this means that one can
!     no longer use <command>ALTER USER</command> to change one's
!     password. It will appear to work but the password one is
!     changing is not the password that the system will end up
!     using.
     </para>

    </sect2>
--- 475,522 ----
     <title>Password authentication</title>

     <indexterm>
!     <primary>MD5</>
     </indexterm>
     <indexterm>
!     <primary>crypt</>
!    </indexterm>
!    <indexterm>
!     <primary>password</primary>
     </indexterm>

     <para>
      Password-based authentication methods include <literal>md5</>,
!     <literal>crypt</>, and <literal>password</>. These methods operate
      similarly except for the way that the password is sent across the
!     connection. If you are at all concerned about password
!     <quote>sniffing</> attacks then <literal>md5</> is preferred, with
!     <literal>crypt</> a second choice if you must support pre-7.2
!     clients. Plain <literal>password</> should especially be avoided for
!     connections over the open Internet (unless you use SSL, SSH, or
!     other communications security wrappers around the connection).
     </para>

     <para>
!     <productname>PostgreSQL</productname> database passwords are
!     separate from operating system user passwords. Ordinarily, the
!     password for each database user is stored in the pg_shadow system
!     catalog table. Passwords can be managed with the query language
!     commands <command>CREATE USER</command> and <command>ALTER
!     USER</command>, e.g., <userinput>CREATE USER foo WITH PASSWORD
!     'secret';</userinput>. By default, that is, if no password has been
!     set up, the stored password is <literal>NULL</literal> and password
!     authentication will always fail for that user.
     </para>

     <para>
      To restrict the set of users that are allowed to connect to certain
!     databases, list the users separated by commas, or in a separate
!     file. The file should contain user names separated by commas or one
!     user name per line, and be in the same directory as
!     <filename>pg_hba.conf</>. Mention the (base) name of the file
!     preceded by <literal>@</>in the <literal>USER</> column. The
!     <literal>DATABASE</> column can similarly accept a list of values or
!     a file name.
     </para>

    </sect2>
***************
*** 588,597 ****
      <productname>Kerberos</productname> system is far beyond the scope
      of this document; in all generality it can be quite complex (yet
      powerful). The <ulink
!     url="http://www.nrl.navy.mil/CCS/people/kenh/kerberos-faq.html">Kerberos
!     <acronym>FAQ</></ulink> or <ulink
!     url="ftp://athena-dist.mit.edu">MIT Project Athena</ulink> can be
!     a good starting point for exploration. Several sources for
      <productname>Kerberos</> distributions exist.
     </para>

--- 535,544 ----
      <productname>Kerberos</productname> system is far beyond the scope
      of this document; in all generality it can be quite complex (yet
      powerful). The <ulink
!     url="http://www.nrl.navy.mil/CCS/people/kenh/kerberos-faq.html">Kerb
!     eros <acronym>FAQ</></ulink> or <ulink
!     url="ftp://athena-dist.mit.edu">MIT Project Athena</ulink> can be a
!     good starting point for exploration. Several sources for
      <productname>Kerberos</> distributions exist.
     </para>

***************
*** 606,639 ****
     <para>
      <productname>PostgreSQL</> operates like a normal Kerberos service.
      The name of the service principal is
!     <replaceable>servicename/hostname@realm</>, where
!     <replaceable>servicename</> is <literal>postgres</literal>
!     (unless a different service name was selected at configure time
!     with <literal>./configure --with-krb-srvnam=whatever</>).
!     <replaceable>hostname</> is the fully qualified domain name of the server
!     machine.  The service principal's realm is the preferred realm of the
!     server machine.
     </para>

     <para>
!     Client principals must have their <productname>PostgreSQL</> user name as
!     their first component, for example
!     <replaceable>pgusername/otherstuff@realm</>.
!     At present the realm of the client is not checked by
!     <productname>PostgreSQL</>; so
!     if you have cross-realm authentication enabled, then any principal
!     in any realm that can communicate with yours will be accepted.
     </para>

     <para>
!     Make sure that your server key file is readable (and
!     preferably only readable) by the
!     <productname>PostgreSQL</productname> server account (see
!     <xref linkend="postgres-user">). The location of the key file
!     is specified with the <varname>krb_server_keyfile</> run time
!     configuration parameter. (See also <xref linkend="runtime-config">.)
!     The default is <filename>/etc/srvtab</> if you are using Kerberos 4
!     and <filename>FILE:/usr/local/pgsql/etc/krb5.keytab</> (or whichever
      directory was specified as <varname>sysconfdir</> at build time)
      with Kerberos 5.
     </para>
--- 553,585 ----
     <para>
      <productname>PostgreSQL</> operates like a normal Kerberos service.
      The name of the service principal is
!     <replaceable>servicename/hostname@realm</>, where
!     <replaceable>servicename</> is <literal>postgres</literal> (unless a
!     different service name was selected at configure time with
!     <literal>./configure --with-krb-srvnam=whatever</>).
!     <replaceable>hostname</> is the fully qualified domain name of the
!     server machine. The service principal's realm is the preferred realm
!     of the server machine.
     </para>

     <para>
!     Client principals must have their <productname>PostgreSQL</> user
!     name as their first component, for example
!     <replaceable>pgusername/otherstuff@realm</>. At present the realm of
!     the client is not checked by <productname>PostgreSQL</>; so if you
!     have cross-realm authentication enabled, then any principal in any
!     realm that can communicate with yours will be accepted.
     </para>

     <para>
!     Make sure that your server key file is readable (and preferably only
!     readable) by the <productname>PostgreSQL</productname> server
!     account (see <xref linkend="postgres-user">). The location of the
!     key file is specified with the <varname>krb_server_keyfile</> run
!     time configuration parameter. (See also <xref
!     linkend="runtime-config">.) The default is <filename>/etc/srvtab</>
!     if you are using Kerberos 4 and
!     <filename>FILE:/usr/local/pgsql/etc/krb5.keytab</> (or whichever
      directory was specified as <varname>sysconfdir</> at build time)
      with Kerberos 5.
     </para>
***************
*** 649,666 ****

     <para>
      When connecting to the database make sure you have a ticket for a
!     principal matching the requested database user name.
!     An example: For database user name <literal>fred</>, both principal
      <literal>fred@EXAMPLE.COM</> and
!     <literal>fred/users.example.com@EXAMPLE.COM</> can be
!     used to authenticate to the database server.
     </para>

     <para>
!     If you use <application>mod_auth_krb</application> and <application>mod_perl</application> on your
<productname>Apache</productname>web server, 
!     you can use <literal>AuthType KerberosV5SaveCredentials</literal> with a <application>mod_perl</application>
!     script. This gives secure database access over the web, no extra
!     passwords required.
     </para>

    </sect2>
--- 595,614 ----

     <para>
      When connecting to the database make sure you have a ticket for a
!     principal matching the requested database user name. An example: For
!     database user name <literal>fred</>, both principal
      <literal>fred@EXAMPLE.COM</> and
!     <literal>fred/users.example.com@EXAMPLE.COM</> can be used to
!     authenticate to the database server.
     </para>

     <para>
!     If you use <application>mod_auth_krb</application> and
!     <application>mod_perl</application> on your
!     <productname>Apache</productname> web server, you can use
!     <literal>AuthType KerberosV5SaveCredentials</literal> with a
!     <application>mod_perl</application> script. This gives secure
!     database access over the web, no extra passwords required.
     </para>

    </sect2>
***************
*** 707,761 ****
     </para>

     <para>
!     On systems supporting <symbol>SO_PEERCRED</symbol> requests for Unix-domain sockets,
!     ident authentication can also be applied to local connections.  In this
!     case, no security risk is added by using ident authentication; indeed
!     it is a preferable choice for local connections on such a system.
     </para>

     <para>
      When using ident-based authentication, after having determined the
      name of the operating system user that initiated the connection,
!     <productname>PostgreSQL</productname> checks whether that user is allowed
!     to connect as the database user he is requesting to connect as.
!     This is controlled by the ident map
!     argument that follows the <literal>ident</> keyword in the
!     <filename>pg_hba.conf</filename> file. There is a predefined ident map
!     <literal>sameuser</literal>, which allows any operating system
!     user to connect as the database user of the same name (if the
!     latter exists). Other maps must be created manually.
     </para>

     <para>
!     <indexterm><primary>pg_ident.conf</primary></indexterm>
!     Ident maps other than <literal>sameuser</literal> are defined
!     in the file <filename>pg_ident.conf</filename>
!     in the data directory, which contains lines of the general form:
  <synopsis>
  <replaceable>map-name</> <replaceable>ident-username</> <replaceable>database-username</>
  </synopsis>
!     Comments and whitespace are handled in the usual way.
!     The <replaceable>map-name</> is an arbitrary name that will be
!     used to refer to this mapping in <filename>pg_hba.conf</filename>.
!     The other two fields specify which operating system user is
!     allowed to connect as which database user. The same
!     <replaceable>map-name</> can be used repeatedly to specify more
!     user-mappings within a single map. There is no restriction regarding
!     how many
!     database users a given operating system user may correspond to and vice
!     versa.
     </para>

    <para>
      <indexterm>
       <primary>SIGHUP</primary>
      </indexterm>
!    The <filename>pg_ident.conf</filename> file is read on startup
!    and when the <application>postmaster</> receives a
     <systemitem>SIGHUP</systemitem> signal. If you edit the file on an
     active system, you will need to signal the <application>postmaster</>
!    (using <literal>pg_ctl reload</> or <literal>kill -HUP</>)
!    to make it re-read the file.
    </para>

     <para>
--- 655,708 ----
     </para>

     <para>
!     On systems supporting <symbol>SO_PEERCRED</symbol> requests for
!     Unix-domain sockets, ident authentication can also be applied to
!     local connections. 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>
      When using ident-based authentication, after having determined the
      name of the operating system user that initiated the connection,
!     <productname>PostgreSQL</productname> checks whether that user is
!     allowed to connect as the database user he is requesting to connect
!     as. This is controlled by the ident map argument that follows the
!     <literal>ident</> keyword in the <filename>pg_hba.conf</filename>
!     file. There is a predefined ident map <literal>sameuser</literal>,
!     which allows any operating system user to connect as the database
!     user of the same name (if the latter exists). Other maps must be
!     created manually.
     </para>

     <para>
!     <indexterm><primary>pg_ident.conf</primary></indexterm> Ident maps
!     other than <literal>sameuser</literal> are defined in the file
!     <filename>pg_ident.conf</filename> in the data directory, which
!     contains lines of the general form:
  <synopsis>
  <replaceable>map-name</> <replaceable>ident-username</> <replaceable>database-username</>
  </synopsis>
!     Comments and whitespace are handled in the usual way. The
!     <replaceable>map-name</> is an arbitrary name that will be used to
!     refer to this mapping in <filename>pg_hba.conf</filename>. The other
!     two fields specify which operating system user is allowed to connect
!     as which database user. The same <replaceable>map-name</> can be
!     used repeatedly to specify more user-mappings within a single map.
!     There is no restriction regarding how many database users a given
!     operating system user may correspond to and vice versa.
     </para>

    <para>
      <indexterm>
       <primary>SIGHUP</primary>
      </indexterm>
!    The <filename>pg_ident.conf</filename> file is read on startup and
!    when the <application>postmaster</> receives a
     <systemitem>SIGHUP</systemitem> signal. If you edit the file on an
     active system, you will need to signal the <application>postmaster</>
!    (using <literal>pg_ctl reload</> or <literal>kill -HUP</>) to make it
!    re-read the file.
    </para>

     <para>
***************
*** 763,775 ****
      conjunction with the <filename>pg_hba.conf</> file in <xref
      linkend="example-pg-hba.conf"> is shown in <xref
      linkend="example-pg-ident.conf">. In this example setup, anyone
!     logged in to a machine on the 192.168 network that does not have
!     the Unix user name <systemitem>bryanh</>, <systemitem>ann</>, or <systemitem>robert</> would not be granted
access.
!     Unix user <systemitem>robert</> would only be allowed access when he tries to
!     connect as <productname>PostgreSQL</> user <systemitem>bob</>,
!       not as <systemitem>robert</>
!     or anyone else. <systemitem>ann</> would only be allowed to connect as
!     <systemitem>ann</>. User <systemitem>bryanh</> would be allowed to connect as either
      <systemitem>bryanh</> himself or as <systemitem>guest1</>.
     </para>

--- 710,723 ----
      conjunction with the <filename>pg_hba.conf</> file in <xref
      linkend="example-pg-hba.conf"> is shown in <xref
      linkend="example-pg-ident.conf">. In this example setup, anyone
!     logged in to a machine on the 192.168 network that does not have the
!     Unix user name <systemitem>bryanh</>, <systemitem>ann</>, or
!     <systemitem>robert</> would not be granted access. Unix user
!     <systemitem>robert</> would only be allowed access when he tries to
!     connect as <productname>PostgreSQL</> user <systemitem>bob</>, not
!     as <systemitem>robert</> or anyone else. <systemitem>ann</> would
!     only be allowed to connect as <systemitem>ann</>. User
!     <systemitem>bryanh</> would be allowed to connect as either
      <systemitem>bryanh</> himself or as <systemitem>guest1</>.
     </para>

***************
*** 799,828 ****

     <para>
  <ProgramListing>
! No pg_hba.conf entry for host 123.123.123.123, user joeblow, database testdb
  </ProgramListing>
!     This is what you are most likely to get if you succeed in
!     contacting the server, but it does not want to talk to you. As the
!     message suggests, the server refused the connection request
!     because it found no authorizing entry in its <filename>pg_hba.conf</filename>
      configuration file.
     </para>

     <para>
  <ProgramListing>
! Password authentication failed for user 'joeblow'
  </ProgramListing>
!     Messages like this indicate that you contacted the server, and
!     it is willing to talk to you, but not until you pass the
!     authorization method specified in the
!     <filename>pg_hba.conf</filename> file. Check the password you are
!     providing, or check your Kerberos or ident software if the
!     complaint mentions one of those authentication types.
     </para>

     <para>
  <ProgramListing>
! FATAL 1:  user "joeblow" does not exist
  </ProgramListing>
      The indicated user name was not found.
     </para>
--- 747,776 ----

     <para>
  <ProgramListing>
! No pg_hba.conf entry for host 123.123.123.123, user andym, database testdb
  </ProgramListing>
!     This is what you are most likely to get if you succeed in contacting
!     the server, but it does not want to talk to you. As the message
!     suggests, the server refused the connection request because it found
!     no authorizing entry in its <filename>pg_hba.conf</filename>
      configuration file.
     </para>

     <para>
  <ProgramListing>
! Password authentication failed for user 'andym'
  </ProgramListing>
!     Messages like this indicate that you contacted the server, and it is
!     willing to talk to you, but not until you pass the authorization
!     method specified in the <filename>pg_hba.conf</filename> file. Check
!     the password you are providing, or check your Kerberos or ident
!     software if the complaint mentions one of those authentication
!     types.
     </para>

     <para>
  <ProgramListing>
! FATAL 1:  user "andym" does not exist
  </ProgramListing>
      The indicated user name was not found.
     </para>
***************
*** 837,845 ****
     </para>

     <para>
!     Note that the server log may contain more information
!     about an authentication failure than is reported to the client.
!     If you are confused about the reason for a failure, check the log.
     </para>
    </sect1>

--- 785,793 ----
     </para>

     <para>
!     Note that the server log may contain more information about an
!     authentication failure than is reported to the client. If you are
!     confused about the reason for a failure, check the log.
     </para>
    </sect1>

Index: doc/src/sgml/reference.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v
retrieving revision 1.24
diff -c -r1.24 reference.sgml
*** doc/src/sgml/reference.sgml    19 Mar 2002 02:18:11 -0000    1.24
--- doc/src/sgml/reference.sgml    19 Mar 2002 05:51:45 -0000
***************
*** 191,197 ****
     &initlocation;
     &ipcclean;
     &pgCtl;
-    &pgPasswd;
     &postgres;
     &postmaster;

--- 191,196 ----
Index: doc/src/sgml/ref/allfiles.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v
retrieving revision 1.36
diff -c -r1.36 allfiles.sgml
*** doc/src/sgml/ref/allfiles.sgml    19 Mar 2002 02:18:12 -0000    1.36
--- doc/src/sgml/ref/allfiles.sgml    19 Mar 2002 05:51:45 -0000
***************
*** 125,131 ****
  <!entity pgCtl              system "pg_ctl-ref.sgml">
  <!entity pgDump             system "pg_dump.sgml">
  <!entity pgDumpall          system "pg_dumpall.sgml">
- <!entity pgPasswd           system "pg_passwd.sgml">
  <!entity pgRestore          system "pg_restore.sgml">
  <!entity pgTclSh            system "pgtclsh.sgml">
  <!entity pgTkSh             system "pgtksh.sgml">
--- 125,130 ----
Index: src/backend/libpq/Makefile
===================================================================
RCS file: /cvsroot/pgsql/src/backend/libpq/Makefile,v
retrieving revision 1.29
diff -c -r1.29 Makefile
*** src/backend/libpq/Makefile    4 Mar 2002 01:46:02 -0000    1.29
--- src/backend/libpq/Makefile    19 Mar 2002 05:51:45 -0000
***************
*** 14,22 ****

  # be-fsstubs is here for historical reasons, probably belongs elsewhere

! OBJS = be-fsstubs.o \
!     auth.o crypt.o hba.o md5.o password.o \
!     pqcomm.o pqformat.o pqsignal.o


  all: SUBSYS.o
--- 14,20 ----

  # be-fsstubs is here for historical reasons, probably belongs elsewhere

! OBJS = be-fsstubs.o auth.o crypt.o hba.o md5.o pqcomm.o pqformat.o pqsignal.o


  all: SUBSYS.o
Index: src/backend/libpq/auth.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/libpq/auth.c,v
retrieving revision 1.79
diff -c -r1.79 auth.c
*** src/backend/libpq/auth.c    5 Mar 2002 07:57:45 -0000    1.79
--- src/backend/libpq/auth.c    19 Mar 2002 05:51:57 -0000
***************
*** 34,40 ****
  #include "miscadmin.h"

  static void sendAuthRequest(Port *port, AuthRequest areq);
- static int    checkPassword(Port *port, char *user, char *password);
  static int    old_be_recvauth(Port *port);
  static int    map_old_to_new(Port *port, UserAuth old, int status);
  static void auth_failed(Port *port, int status);
--- 34,39 ----
***************
*** 381,387 ****
          saved = port->auth_method;
          port->auth_method = uaPassword;

!         status = checkPassword(port, user, password);

          port->auth_method = saved;

--- 380,386 ----
          saved = port->auth_method;
          port->auth_method = uaPassword;

!         status = md5_crypt_verify(port, user, password);

          port->auth_method = saved;

***************
*** 663,669 ****

          initStringInfo(&buf);
          pq_getstr(&buf);
!
          /* Do not echo failed password to logs, for security. */
          elog(DEBUG5, "received PAM packet");

--- 662,668 ----

          initStringInfo(&buf);
          pq_getstr(&buf);
!
          /* Do not echo failed password to logs, for security. */
          elog(DEBUG5, "received PAM packet");

***************
*** 810,832 ****
      /* Do not echo failed password to logs, for security. */
      elog(DEBUG5, "received password packet");

!     result = checkPassword(port, port->user, buf.data);
      pfree(buf.data);
      return result;
- }
-
-
- /*
-  * Handle `password' and `crypt' records. If an auth argument was
-  * specified, use the respective file. Else use pg_shadow passwords.
-  */
- static int
- checkPassword(Port *port, char *user, char *password)
- {
-     if (port->auth_arg[0] != '\0')
-         return verify_password(port, user, password);
-
-     return md5_crypt_verify(port, user, password);
  }


--- 809,818 ----
      /* Do not echo failed password to logs, for security. */
      elog(DEBUG5, "received password packet");

!     result = md5_crypt_verify(port, port->user, buf.data);
!
      pfree(buf.data);
      return result;
  }


Index: src/backend/libpq/hba.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/libpq/hba.c,v
retrieving revision 1.80
diff -c -r1.80 hba.c
*** src/backend/libpq/hba.c    4 Mar 2002 01:46:03 -0000    1.80
--- src/backend/libpq/hba.c    19 Mar 2002 05:51:58 -0000
***************
*** 54,59 ****
--- 54,60 ----
  static List *hba_lines = NIL;    /* pre-parsed contents of hba file */
  static List *ident_lines = NIL; /* pre-parsed contents of ident file */

+ static List *tokenize_file(FILE *file);

  /*
   * Some standard C libraries, including GNU, have an isblank() function.
***************
*** 79,111 ****
  next_token(FILE *fp, char *buf, const int bufsz)
  {
      int            c;
!     char       *eb = buf + (bufsz - 1);

!     /* Move over initial token-delimiting blanks */
!     while ((c = getc(fp)) != EOF && isblank(c))
!         ;
!
!     if (c != EOF && c != '\n')
      {
!         /*
!          * build a token in buf of next characters up to EOF, eol, or
!          * blank.  If the token gets too long, we still parse it
!          * correctly, but the excess characters are not stored into *buf.
!          */
!         while (c != EOF && c != '\n' && !isblank(c))
          {
!             if (buf < eb)
!                 *buf++ = c;
!             c = getc(fp);
          }

!         /*
!          * Put back the char right after the token (critical in case it is
!          * eol, since we need to detect end-of-line at next call).
!          */
!         if (c != EOF)
!             ungetc(c, fp);
!     }
      *buf = '\0';
  }

--- 80,136 ----
  next_token(FILE *fp, char *buf, const int bufsz)
  {
      int            c;
!     char       *end_buf = buf + (bufsz - 1);
!     char        quote = '\0';
!     bool        is_quote;

!     do
      {
!         /* Move over initial token-delimiting blanks */
!         while ((c = getc(fp)) != EOF && isblank(c))
!             ;
!
!         if (c != EOF && c != '\n')
          {
!             /*
!              * build a token in buf of next characters up to EOF, eol, or
!              * blank.  If the token gets too long, we still parse it
!              * correctly, but the excess characters are not stored into *buf.
!              */
!             while (c != EOF && c != '\n' && (!isblank(c) || quote != '\0'))
!             {
!                 is_quote = false;
!                 if (c == '"' || c == '\'')
!                 {
!                     /* Allow single or double quoted strings, strip quotes */
!                     if (quote == '\0')
!                     {
!                         quote = c;
!                         is_quote = true;
!                     }
!                     else if (c == quote)
!                     {
!                         quote = '\0';
!                         is_quote = true;
!                     }
!                 }
!
!                 if (!is_quote && buf < end_buf)
!                     *buf++ = c;
!                 c = getc(fp);
!             }
!
!             /*
!              * Put back the char right after the token (critical in case it is
!              * eol, since we need to detect end-of-line at next call).
!              */
!             if (c != EOF)
!                 ungetc(c, fp);
          }

!     /* If the token has a trailing comma, get another token */
!     } while (*buf == ',' && c != EOF && c != '\n');
!
      *buf = '\0';
  }

***************
*** 121,126 ****
--- 146,241 ----


  /*
+  * Free memory used by lines/tokens (ie, structure built by tokenize_file)
+  */
+ static void
+ free_lines(List **lines)
+ {
+     if (*lines)
+     {
+         List       *line,
+                    *token;
+
+         foreach(line, *lines)
+         {
+             List       *ln = lfirst(line);
+
+             /* free the pstrdup'd tokens (don't try it on the line number) */
+             foreach(token, lnext(ln))
+                 pfree(lfirst(token));
+             /* free the sublist structure itself */
+             freeList(ln);
+         }
+         /* free the list structure itself */
+         freeList(*lines);
+         /* clear the static variable */
+         *lines = NIL;
+     }
+ }
+
+
+ static char *
+ tokenize_at_file(const char *at_filename)
+ {
+     char       *at_fullname;
+     FILE       *at_file;
+     List        *at_lines;
+     List       *line;
+     char       *comma_str = NULL;
+     List        *token;
+
+     at_fullname = (char *) palloc(strlen(DataDir) +
+                                 strlen(at_filename) + 2);
+     strcpy(at_fullname, DataDir);
+     strcat(at_fullname, "/");
+     strcat(at_fullname, at_filename);
+
+     at_file = AllocateFile(at_fullname, PG_BINARY_R);
+     if (!at_file)
+     {
+         elog(LOG, "tokenize_at_file: Unable to open secondary authentication file \"@%s\" as \"%s\": %m",
+              at_filename, at_fullname);
+         pfree(at_fullname);
+
+         /* return empty string, it matches nothing */
+         return pstrdup("");
+     }
+     pfree(at_fullname);
+
+     /* There is possible recursion here if the file contains @ */
+     at_lines = tokenize_file(at_file);
+
+     /* Create comma-separate string from List */
+     foreach(line, at_lines)
+     {
+         List       *ln = lfirst(line);
+
+         /* First entry is line number */
+         foreach(token, lnext(ln))
+         {
+             if (comma_str != NULL)
+             {
+                 comma_str = repalloc(comma_str,
+                             strlen(comma_str) + strlen(lfirst(token)) + 2);
+                 strcat(comma_str, ",");
+                 strcat(comma_str, lfirst(token));
+             }
+             else
+             {
+                 comma_str = palloc(strlen(lfirst(token))+1);
+                 strcpy(comma_str, lfirst(token));
+             }
+
+         }
+     }
+     free_lines(&at_lines);
+     FreeFile(at_file);
+
+     return comma_str;
+ }
+
+
+ /*
   *    Read the given file and create a list of line sublists.
   */
  static List *
***************
*** 150,157 ****
                  next_line = makeListi1(line_number);
                  lines = lappend(lines, next_line);
              }
!             /* append token to current line's list */
!             next_line = lappend(next_line, pstrdup(buf));
          }
          else
          {
--- 265,277 ----
                  next_line = makeListi1(line_number);
                  lines = lappend(lines, next_line);
              }
!             /* Is this referencing a file? */
!             if (buf[0] != '@')
!                 /* append token to current line's list */
!                 next_line = lappend(next_line, pstrdup(buf));
!             else
!                 /* Already palloc'ed */
!                 next_line = lappend(next_line, tokenize_at_file(buf+1));
          }
          else
          {
***************
*** 175,206 ****
  }


! /*
!  * Free memory used by lines/tokens (ie, structure built by tokenize_file)
!  */
! static void
! free_lines(List **lines)
  {
!     if (*lines)
      {
!         List       *line,
!                    *token;

-         foreach(line, *lines)
-         {
-             List       *ln = lfirst(line);

!             /* free the pstrdup'd tokens (don't try it on the line number) */
!             foreach(token, lnext(ln))
!                 pfree(lfirst(token));
!             /* free the sublist structure itself */
!             freeList(ln);
!         }
!         /* free the list structure itself */
!         freeList(*lines);
!         /* clear the static variable */
!         *lines = NIL;
      }
  }


--- 295,329 ----
  }


! static int
! check_db(char *dbname, char *user, char *param_str)
  {
!     char *tok;
!
!     for (tok = strtok(param_str, ","); tok != NULL; tok = strtok(NULL, ","))
      {
!         if (strcmp(tok, dbname) == 0 ||
!             strcmp(tok, "all") == 0 ||
!             (strcmp(tok, "sameuser") == 0 &&
!              strcmp(dbname, user) == 0))
!             return 1;
!     }
!     return 0;
! }


! static int
! check_user(char *user, char *param_str)
! {
!     char *tok;
!
!     for (tok = strtok(param_str, ","); tok != NULL; tok = strtok(NULL, ","))
!     {
!         if (strcmp(tok, user) == 0 ||
!             strcmp(tok, "all") == 0)
!             return 1;
      }
+     return 0;
  }


***************
*** 278,283 ****
--- 401,407 ----
      int            line_number;
      char       *token;
      char       *db;
+     char       *user;

      Assert(line != NIL);
      line_number = lfirsti(line);
***************
*** 293,302 ****
              goto hba_syntax;
          db = lfirst(line);

!         /* Read the rest of the line. */
          line = lnext(line);
          if (!line)
              goto hba_syntax;
          parse_hba_auth(line, &port->auth_method, port->auth_arg, error_p);
          if (*error_p)
              goto hba_syntax;
--- 417,433 ----
              goto hba_syntax;
          db = lfirst(line);

!         /* Get the user. */
!         line = lnext(line);
!         if (!line)
!             goto hba_syntax;
!         user = lfirst(line);
!
          line = lnext(line);
          if (!line)
              goto hba_syntax;
+
+         /* Read the rest of the line. */
          parse_hba_auth(line, &port->auth_method, port->auth_arg, error_p);
          if (*error_p)
              goto hba_syntax;
***************
*** 308,322 ****
              port->auth_method == uaKrb5)
              goto hba_syntax;

!         /*
!          * If this record doesn't match the parameters of the connection
!          * attempt, ignore it.
!          */
!         if ((strcmp(db, port->database) != 0 &&
!              strcmp(db, "all") != 0 &&
!              (strcmp(db, "sameuser") != 0 ||
!               strcmp(port->database, port->user) != 0)) ||
!             port->raddr.sa.sa_family != AF_UNIX)
              return;
      }
      else if (strcmp(token, "host") == 0 || strcmp(token, "hostssl") == 0)
--- 439,445 ----
              port->auth_method == uaKrb5)
              goto hba_syntax;

!         if (port->raddr.sa.sa_family != AF_UNIX)
              return;
      }
      else if (strcmp(token, "host") == 0 || strcmp(token, "hostssl") == 0)
***************
*** 347,352 ****
--- 470,481 ----
              goto hba_syntax;
          db = lfirst(line);

+         /* Get the user. */
+         line = lnext(line);
+         if (!line)
+             goto hba_syntax;
+         user = lfirst(line);
+
          /* Read the IP address field. */
          line = lnext(line);
          if (!line)
***************
*** 371,390 ****
          if (*error_p)
              goto hba_syntax;

!         /*
!          * If this record doesn't match the parameters of the connection
!          * attempt, ignore it.
!          */
!         if ((strcmp(db, port->database) != 0 &&
!              strcmp(db, "all") != 0 &&
!              (strcmp(db, "sameuser") != 0 ||
!               strcmp(port->database, port->user) != 0)) ||
!             port->raddr.sa.sa_family != AF_INET ||
              ((file_ip_addr.s_addr ^ port->raddr.in.sin_addr.s_addr) & mask.s_addr) != 0)
              return;
      }
      else
          goto hba_syntax;

      /* Success */
      *found_p = true;
--- 500,517 ----
          if (*error_p)
              goto hba_syntax;

!         /* Must meet network restrictions */
!         if (port->raddr.sa.sa_family != AF_INET ||
              ((file_ip_addr.s_addr ^ port->raddr.in.sin_addr.s_addr) & mask.s_addr) != 0)
              return;
      }
      else
          goto hba_syntax;
+
+     if (!check_db(port->database, port->user, db))
+         return;
+     if (!check_user(port->user, user))
+         return;

      /* Success */
      *found_p = true;
Index: src/backend/libpq/pg_hba.conf.sample
===================================================================
RCS file: /cvsroot/pgsql/src/backend/libpq/pg_hba.conf.sample,v
retrieving revision 1.35
diff -c -r1.35 pg_hba.conf.sample
*** src/backend/libpq/pg_hba.conf.sample    8 Mar 2002 20:36:58 -0000    1.35
--- src/backend/libpq/pg_hba.conf.sample    19 Mar 2002 05:51:58 -0000
***************
*** 42,63 ****
  #
  # Format:
  #
! #   host  DBNAME  IP_ADDRESS  ADDRESS_MASK  AUTH_TYPE  [AUTH_ARGUMENT]
  #
! # DBNAME can be:
! #     o a database name
! #     o "all", which means the record matches all databases
! #   o "sameuser", which means users can only access databases whose name
! #     is the same as their username
  #
! # IP_ADDRESS and ADDRESS_MASK are standard dotted decimal IP address and
  # mask values. IP addresses can only be specified numerically, not as
  # domain or host names.
  #
  # Do not prevent the superuser from accessing the template1 database.
  # Various utility commands need access to template1.
  #
! # AUTH_TYPE and AUTH_ARGUMENT are described below.
  #
  #
  # hostssl
--- 42,74 ----
  #
  # Format:
  #
! #   host       DATABASE    USER      IP_ADDRESS    MASK               AUTH_TYPE
  #
! # DATABASE can be:
! #    o a database name
! #    o "sameuser", which means users can only access databases with the
! #      same name as their user name
! #    o "all", which matches all databases
! #    o a list of database names, separated by commas
! #    o a file name containing database names, starting with '@'
! #
! # USER can be:
! #     o a user name
! #     o "all", which matches all users
! #    o a list of user names, separated by commas
! #    o a file name containing user names, starting with '@'
  #
! # Files read using '@' can contain comma-separated database/user names,
! # or one name per line.  The files can also contain comments using '#'.
! #
! # IP_ADDRESS and MASK are standard dotted decimal IP address and
  # mask values. IP addresses can only be specified numerically, not as
  # domain or host names.
  #
  # Do not prevent the superuser from accessing the template1 database.
  # Various utility commands need access to template1.
  #
! # AUTH_TYPE is described below.
  #
  #
  # hostssl
***************
*** 65,74 ****
  #
  # The format of this record is identical to "host".
  #
! #
! #
! # It specifies hosts that required connection via secure SSL. "host"
! # records allow SSL connections too, but "hostssl" only allows SSL-secured
  # connections.
  #
  # This keyword is only available if the server was compiled with SSL
--- 76,83 ----
  #
  # The format of this record is identical to "host".
  #
! # It specifies hosts that require connection via secure SSL. "host"
! # allows SSL connections too, but "hostssl" requires SSL-secured
  # connections.
  #
  # This keyword is only available if the server was compiled with SSL
***************
*** 82,91 ****
  # connections. Without this record, UNIX-socket connections are disallowed
  #
  # Format:
! #   local  DBNAME  AUTH_TYPE  [AUTH_ARGUMENT]
  #
  # This format is identical to the "host" record type except there are no
! # IP_ADDRESS and ADDRESS_MASK fields.
  #
  #
  #
--- 91,100 ----
  # connections. Without this record, UNIX-socket connections are disallowed
  #
  # Format:
! #   local      DATABASE    USER      AUTH_TYPE
  #
  # This format is identical to the "host" record type except there are no
! # IP_ADDRESS and MASK fields.
  #
  #
  #
***************
*** 96,152 ****
  # has an AUTH_TYPE.
  #
  #   trust:
! #        No authentication is done. Any valid username is accepted,
  #         including the PostgreSQL superuser. This option should
  #         be used only for hosts where all users are trusted.
  #
- #   password:
- #        Authentication is done by matching a password supplied
- #        in clear by the host. If no AUTH_ARGUMENT is used, the
- #        password is compared with the user's entry in the
- #        pg_shadow table.
- #
- #         If AUTH_ARGUMENT is specified, the username is looked up
- #         in that file in the $PGDATA directory. If the username
- #         is found but there is no password, the password is looked
- #         up in pg_shadow. If a password exists in the file, it is
- #         used instead. These secondary files allow fine-grained
- #         control over who can access which databases and whether
- #         a non-default password is required. The same file can be
- #         used in multiple records for easier administration.
- #         Password files can be maintained with the pg_passwd(1)
- #         utility. Remember, these passwords override pg_shadow
- #         passwords.  Also, such passwords are passed over the network
- #        in cleartext, meaning this should not be used on untrusted
- #        networks.
- #
  #   md5:
! #          Same as "password", except the password is encrypted over the
! #          network. This method is preferable to "password" and "crypt"
! #          except for pre-7.2 clients that don't support it. NOTE: md5 can
! #          use usernames stored in secondary password files but ignores
! #          passwords stored there. The pg_shadow password will always be
! #          used.
  #
  #   crypt:
! #          Same as "md5", but uses crypt for pre-7.2 clients.  You can
! #        not store encrypted passwords in pg_shadow if you use this
! #        method.
  #
  #   ident:
  #        For TCP/IP connections, authentication is done by contacting the
  #        ident server on the client host. This is only as secure as the
! #        client machine. On machines that support unix-domain socket
! #        credentials (currently Linux, FreeBSD, NetBSD, and BSD/OS), this
! #        method also works for "local" connections.
! #
! #        AUTH_ARGUMENT is required. It determines how to map remote user
! #        names to PostgreSQL user names. If you use "sameuser", the user
! #        names are assumed to be the identical. If not, AUTH_ARGUMENT is
! #        assumed to be a map name found in the $PGDATA/pg_ident.conf
! #        file. The connection is accepted if that file contains an entry
! #        for this map name with the ident-supplied username and the
! #        requested PostgreSQL username.
  #
  #   krb4:
  #        Kerberos V4 authentication is used.  Allowed only for
--- 105,142 ----
  # has an AUTH_TYPE.
  #
  #   trust:
! #        No authentication is done. Any valid user name is accepted,
  #         including the PostgreSQL superuser. This option should
  #         be used only for hosts where all users are trusted.
  #
  #   md5:
! #          Requires the client to supply an MD5 encrypted password for
! #        authentication.  This is the only method that allows encrypted
! #        passwords to be stored in pg_shadow.
  #
  #   crypt:
! #          Same as "md5", but uses crypt for pre-7.2 clients.
  #
+ #   password:
+ #        Same as "md5", but the password is sent in cleartext over
+ #        the network.  This should not be used on untrusted
+ #        networks.
+ #
  #   ident:
  #        For TCP/IP connections, authentication is done by contacting the
  #        ident server on the client host. This is only as secure as the
! #        client machine. You must specify the map name after the 'ident'
! #        keyword. It determines how to map remote user names to
! #        PostgreSQL user names. If you use "sameuser", the user names are
! #        assumed to be identical. If not, the map name is looked up
! #        in the $PGDATA/pg_ident.conf file. The connection is accepted if
! #        that file contains an entry for this map name with the
! #        ident-supplied username and the requested PostgreSQL username.
! #
! #        On machines that support unix-domain socket credentials
! #        (currently Linux, FreeBSD, NetBSD, and BSD/OS), ident allows
! #        reliable authentication of 'local' connections without ident
! #        running on the local machine.
  #
  #   krb4:
  #        Kerberos V4 authentication is used.  Allowed only for
***************
*** 157,166 ****
  #        TCP/IP connections, not for local UNIX-domain sockets.
  #
  #   pam:
! #        Authentication is passed off to PAM (PostgreSQL must be
! #        configured --with-pam), using the default service name
! #        "postgresql" - you can specify your own service name by
! #        setting AUTH_ARGUMENT to the desired service name.
  #
  #   reject:
  #         Reject the connection. This is used to reject certain hosts
--- 147,156 ----
  #        TCP/IP connections, not for local UNIX-domain sockets.
  #
  #   pam:
! #        Authentication is done by PAM using the default service name
! #        "postgresql". You can specify your own service name by adding
! #        the service name after the 'pam' keyword. To use this option,
! #        PostgreSQL must be configured --with-pam.
  #
  #   reject:
  #         Reject the connection. This is used to reject certain hosts
***************
*** 177,236 ****
  # Allow any user on the local system to connect to any database under any
  # username using Unix-domain sockets (the default for local connections):
  #
! # TYPE       DATABASE    IP_ADDRESS    MASK               AUTH_TYPE  AUTH_ARGUMENT
! # local      all                                          trust
  #
  # The same using local loopback TCP/IP connections:
  #
! # TYPE       DATABASE    IP_ADDRESS    MASK               AUTH_TYPE  AUTH_ARGUMENT
! # host       all         127.0.0.1     255.255.255.255    trust
  #
  # Allow any user from any host with IP address 192.168.93.x to
  # connect to database "template1" as the same username that ident reports
  # for the connection (typically his Unix username):
  #
! # TYPE       DATABASE    IP_ADDRESS    MASK               AUTH_TYPE  AUTH_ARGUMENT
! # host       template1   192.168.93.0  255.255.255.0      ident      sameuser
  #
  # Allow a user from host 192.168.12.10 to connect to database "template1"
! # if the user's password in pg_shadow is correctly supplied:
  #
! # TYPE       DATABASE    IP_ADDRESS    MASK               AUTH_TYPE  AUTH_ARGUMENT
! # host       template1   192.168.12.10 255.255.255.255    md5
  #
  # In the absence of preceding "host" lines, these two lines will reject
  # all connection from 192.168.54.1 (since that entry will be matched
  # first), but allow Kerberos V5 connections from anywhere else on the
  # Internet. The zero mask means that no bits of the host IP address are
! # considered, so it matches any host:
  #
  #
! # TYPE       DATABASE    IP_ADDRESS    MASK               AUTH_TYPE  AUTH_ARGUMENT
! # host       all        192.168.54.1   255.255.255.255    reject
! # host       all        0.0.0.0        0.0.0.0            krb5
  #
  # Allow users from 192.168.x.x hosts to connect to any database if they
  # pass the ident check. For example, if ident says the user is "james" and
  # he requests to connect as PostgreSQL user "guest", the connection is
  # allowed if there is an entry in $PGDATA/pg_ident.conf with map name
  # "phoenix" that says "james" is allowed to connect as "guest":
  #
! # TYPE       DATABASE    IP_ADDRESS    MASK               AUTH_TYPE  AUTH_ARGUMENT
! # host       all        192.168.0.0    255.255.0.0        ident      phoenix
  #
  # If these are the only two lines for local connections, they will allow
  # local users to connect only to their own databases (databases with the
  # same name as their user name) except for administrators who may connect
  # to all databases. The file $PGDATA/admins lists the user names who are
  # permitted to connect to all databases. Passwords are required in all
! # cases. (If you prefer to use ident authorization, an ident map can
! # serve a parallel purpose to the password list file used here.)
  #
! # TYPE       DATABASE    IP_ADDRESS    MASK               AUTH_TYPE  AUTH_ARGUMENT
! # local      sameuser                                     md5
! # local      all                                          md5  admins
  #
- # See $PGDATA/pg_ident.conf for more information on Ident maps.
  #
  #
  #
--- 167,225 ----
  # Allow any user on the local system to connect to any database under any
  # username using Unix-domain sockets (the default for local connections):
  #
! # TYPE       DATABASE    USER       IP_ADDRESS    MASK               AUTH_TYPE
! # local      all         all                                         trust
  #
  # The same using local loopback TCP/IP connections:
  #
! # TYPE      DATABASE     USER    IP_ADDRESS    MASK               AUTH_TYPE
! # host      all          all     127.0.0.1     255.255.255.255    trust
  #
  # Allow any user from any host with IP address 192.168.93.x to
  # connect to database "template1" as the same username that ident reports
  # for the connection (typically his Unix username):
  #
! # TYPE       DATABASE    USER    IP_ADDRESS    MASK               AUTH_TYPE
! # host       template1   all     192.168.93.0  255.255.255.0      ident sameuser
  #
  # Allow a user from host 192.168.12.10 to connect to database "template1"
! # if the user's password is correctly supplied:
  #
! # TYPE       DATABASE    USER     IP_ADDRESS    MASK               AUTH_TYPE
! # host       template1   all      192.168.12.10 255.255.255.255    md5
  #
  # In the absence of preceding "host" lines, these two lines will reject
  # all connection from 192.168.54.1 (since that entry will be matched
  # first), but allow Kerberos V5 connections from anywhere else on the
  # Internet. The zero mask means that no bits of the host IP address are
! # considered so it matches any host:
  #
  #
! # TYPE       DATABASE    USER     IP_ADDRESS    MASK               AUTH_TYPE
! # host       all         all      192.168.54.1  255.255.255.255    reject
! # host       all         all      0.0.0.0       0.0.0.0            krb5
  #
  # Allow users from 192.168.x.x hosts to connect to any database if they
  # pass the ident check. For example, if ident says the user is "james" and
  # he requests to connect as PostgreSQL user "guest", the connection is
  # allowed if there is an entry in $PGDATA/pg_ident.conf with map name
  # "phoenix" that says "james" is allowed to connect as "guest":
+ # See $PGDATA/pg_ident.conf for more information on Ident maps.
  #
! # TYPE       DATABASE    USER     IP_ADDRESS    MASK               AUTH_TYPE
! # host       all         all      192.168.0.0    255.255.0.0       ident phoenix
  #
  # If these are the only two lines for local connections, they will allow
  # local users to connect only to their own databases (databases with the
  # same name as their user name) except for administrators who may connect
  # to all databases. The file $PGDATA/admins lists the user names who are
  # permitted to connect to all databases. Passwords are required in all
! # cases.
  #
! # TYPE       DATABASE    USER      IP_ADDRESS    MASK               AUTH_TYPE
! # local      sameuser    all                                        md5
! # local      all         @admins                                    md5
  #
  #
  #
  #
***************
*** 250,256 ****
  # configuration is probably too liberal for you. Change it to use
  # something other than "trust" authentication.
  #
! # TYPE     DATABASE    IP_ADDRESS    MASK               AUTH_TYPE  AUTH_ARGUMENT

! local      all                                          trust
! host       all         127.0.0.1     255.255.255.255    trust
--- 239,245 ----
  # configuration is probably too liberal for you. Change it to use
  # something other than "trust" authentication.
  #
! # TYPE       DATABASE      USER      IP_ADDRESS    MASK               AUTH_TYPE

! local        all           all                                        trust
! host         all           all       127.0.0.1     255.255.255.255    trust
Index: src/bin/Makefile
===================================================================
RCS file: /cvsroot/pgsql/src/bin/Makefile,v
retrieving revision 1.34
diff -c -r1.34 Makefile
*** src/bin/Makefile    18 Feb 2001 18:33:59 -0000    1.34
--- src/bin/Makefile    19 Mar 2002 05:51:59 -0000
***************
*** 14,20 ****
  include $(top_builddir)/src/Makefile.global

  DIRS := initdb initlocation ipcclean pg_ctl pg_dump pg_id \
!     pg_passwd psql scripts pg_config

  ifdef MULTIBYTE
  DIRS += pg_encoding
--- 14,20 ----
  include $(top_builddir)/src/Makefile.global

  DIRS := initdb initlocation ipcclean pg_ctl pg_dump pg_id \
!     psql scripts pg_config

  ifdef MULTIBYTE
  DIRS += pg_encoding

Re: Adding usernames to pg_hba.conf

From
"Rod Taylor"
Date:
I see.. @ denotes a list of users in a file.

Wouldn't it make more sense to simply allow groups to be specified
(groups from pg_group)?

In my case any group I would specify for connection purposes I've
already created for permission purposes.

--
Rod Taylor

This message represents the official view of the voices in my head

----- Original Message -----
From: "Bruce Momjian" <pgman@candle.pha.pa.us>
To: <pgman@candle.pha.pa.us>
Cc: "PostgreSQL-patches" <pgsql-patches@postgresql.org>
Sent: Tuesday, March 19, 2002 1:06 AM
Subject: Re: [PATCHES] Adding usernames to pg_hba.conf


>
> Sorry, the previous posting didn't have the full patch.  This one
does.
>
> --------------------------------------------------------------------
-------
>
> pgman wrote:
> > This patch completes the following TODO item:
> >
> > * Allow usernames to be specified directly in pg_hba.conf (Bruce)
> >
> > Currently, we allow usernames in secondary password files, but
this is a
> > very confusing feature.  This patch:
> >
> > o  removes secondary password file support
> > o  adds a user name column just after the database column
> > o  allows a comma separated list of usernames or databases
> > o  allows another file to contain a list of username/databases
> >    by preceding the pg_hba.conf entry with '@'
> > o  allow single or double-quoting of user/database names
> >
> > See the documentation changes and new pg_hba.conf diffs for
samples.
> >
> > Is the '@' sign a good way to identify a file name?  Is putting
the
> > username column just after the database column the right place for
it?
>
> --
>   Bruce Momjian                        |  http://candle.pha.pa.us
>   pgman@candle.pha.pa.us               |  (610) 853-3000
>   +  If your life is a hard drive,     |  830 Blythe Avenue
>   +  Christ can be your backup.        |  Drexel Hill, Pennsylvania
19026
>


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


> Index: doc/src/sgml/client-auth.sgml
> ===================================================================
> RCS file: /cvsroot/pgsql/doc/src/sgml/client-auth.sgml,v
> retrieving revision 1.32
> diff -c -r1.32 client-auth.sgml
> *** doc/src/sgml/client-auth.sgml 20 Jan 2002 22:19:55 -0000 1.32
> --- doc/src/sgml/client-auth.sgml 19 Mar 2002 05:51:45 -0000
> ***************
> *** 10,23 ****
>    </indexterm>
>
>    <para>
> !   When a client application connects to the database server, it
specifies which
> !   <productname>PostgreSQL</productname> user name it wants to
connect as,
> !   much the same way one logs into a Unix computer as a particular
user.
> !   Within the SQL environment the active
> !   database user name determines access privileges to database
> !   objects -- see <xref linkend="user-manag"> for more information
> !   about that. It is therefore obviously essential to restrict
which
> !   database user name(s) a given client can connect as.
>    </para>
>
>    <para>
> --- 10,23 ----
>    </indexterm>
>
>    <para>
> !   When a client application connects to the database server, it
> !   specifies which <productname>PostgreSQL</productname> user name
it
> !   wants to connect as, much the same way one logs into a Unix
computer
> !   as a particular user. Within the SQL environment the active
database
> !   user name determines access privileges to database objects --
see
> !   <xref linkend="user-manag"> for more information about that. It
is
> !   therefore obviously essential to restrict which database user
name(s)
> !   a given client can connect as.
>    </para>
>
>    <para>
> ***************
> *** 30,49 ****
>
>    <para>
>     <productname>PostgreSQL</productname> offers a number of
different
> !   client authentication methods.  The method to be used can be
selected
> !   on the basis of (client) host and database; some authentication
methods
> !   allow you to restrict by user name as well.
>    </para>
>
>    <para>
> !   <productname>PostgreSQL</productname> database user names are
logically
>     separate from user names of the operating system in which the
server
> !   runs.  If all the users of a particular server also have
accounts on
>     the server's machine, it makes sense to assign database user
names
> !   that match their operating system user names.  However, a server
that accepts remote
> !   connections may have many users who have no local account, and
in such
> !   cases there need be no connection between database user names
and OS
> !   user names.
>    </para>
>
>    <sect1 id="pg-hba-conf">
> --- 30,48 ----
>
>    <para>
>     <productname>PostgreSQL</productname> offers a number of
different
> !   client authentication methods. The method to be used can be
selected
> !   on the basis of (client) host, database, and user.
>    </para>
>
>    <para>
> !   <productname>PostgreSQL</productname> user names are logically
>     separate from user names of the operating system in which the
server
> !   runs. If all the users of a particular server also have accounts
on
>     the server's machine, it makes sense to assign database user
names
> !   that match their operating system user names. However, a server
that
> !   accepts remote connections may have many users who have no local
> !   account, and in such cases there need be no connection between
> !   database user names and OS user names.
>    </para>
>
>    <sect1 id="pg-hba-conf">
> ***************
> *** 56,94 ****
>     <para>
>      Client authentication is controlled by the file
>      <filename>pg_hba.conf</filename> in the data directory, e.g.,
> !    <filename>/usr/local/pgsql/data/pg_hba.conf</filename>.
(<acronym>HBA</> stands
> !    for host-based authentication.) A default
<filename>pg_hba.conf</filename>
> !    file is installed when the
> !    data area is initialized by <command>initdb</command>.
>     </para>
>
>     <para>
> !    The general format of the <filename>pg_hba.conf</filename> file
is
> !    of a set of records, one per line. Blank lines and lines
beginning
> !    with a hash character (<quote>#</quote>) are ignored. A record
is
> !    made up of a number of fields which are separated by spaces
and/or
> !    tabs.  Records cannot be continued across lines.
>     </para>
>
>     <para>
>      Each record specifies a connection type, a client IP address
range
> !    (if relevant for the connection type), a database name or
names,
>      and the authentication method to be used for connections
matching
> !    these parameters.
> !    The first record that matches the type, client address, and
requested
> !    database name of a connection attempt is used to do the
> !    authentication step.  There is no <quote>fall-through</> or
>      <quote>backup</>: if one record is chosen and the
authentication
> !    fails, the following records are not considered. If no record
> !    matches, the access will be denied.
>     </para>
>
>     <para>
>      A record may have one of the three formats
>      <synopsis>
> ! local   <replaceable>database</replaceable>
<replaceable>authentication-method</replaceable> [
<replaceable>authentication-option</replaceable> ]
> ! host    <replaceable>database</replaceable>
<replaceable>IP-address</replaceable>
<replaceable>IP-mask</replaceable>
<replaceable>authentication-method</replaceable> [
<replaceable>authentication-option</replaceable> ]
> ! hostssl <replaceable>database</replaceable>
<replaceable>IP-address</replaceable>
<replaceable>IP-mask</replaceable>
<replaceable>authentication-method</replaceable> [
<replaceable>authentication-option</replaceable> ]
>       </synopsis>
>      The meaning of the fields is as follows:
>
> --- 55,93 ----
>     <para>
>      Client authentication is controlled by the file
>      <filename>pg_hba.conf</filename> in the data directory, e.g.,
> !    <filename>/usr/local/pgsql/data/pg_hba.conf</filename>.
> !    (<acronym>HBA</> stands for host-based authentication.) A
default
> !    <filename>pg_hba.conf</filename> file is installed when the
data area
> !    is initialized by <command>initdb</command>.
>     </para>
>
>     <para>
> !    The general format of the <filename>pg_hba.conf</filename> file
is of
> !    a set of records, one per line. Blank lines are ignored, as is
any
> !    text after the <quote>#</quote> comment character. A record is
made
> !    up of a number of fields which are separated by spaces and/or
tabs.
> !    Fields can contain white space if the field value is quoted.
Records
> !    cannot be continued across lines.
>     </para>
>
>     <para>
>      Each record specifies a connection type, a client IP address
range
> !    (if relevant for the connection type), a database name, a user
name,
>      and the authentication method to be used for connections
matching
> !    these parameters. The first record with a matching connection
type,
> !    client address, requested database, and user name is used to
peform
> !    authentication. There is no <quote>fall-through</> or
>      <quote>backup</>: if one record is chosen and the
authentication
> !    fails, subsequent records are not considered. If no record
matches,
> !    access is denied.
>     </para>
>
>     <para>
>      A record may have one of the three formats
>      <synopsis>
> ! local   <replaceable>database</replaceable>
<replaceable>user</replaceable>
<replaceable>authentication-method</replaceable> [
<replaceable>authentication-option</replaceable> ]
> ! host    <replaceable>database</replaceable>
<replaceable>user</replaceable> <replaceable>IP-address</replaceable>
<replaceable>IP-mask</replaceable>
<replaceable>authentication-method</replaceable>
> ! hostssl <replaceable>database</replaceable>
<replaceable>user</replaceable> <replaceable>IP-address</replaceable>
<replaceable>IP-mask</replaceable>
<replaceable>authentication-method</replaceable>
>       </synopsis>
>      The meaning of the fields is as follows:
>
> ***************
> *** 97,103 ****
>        <term><literal>local</literal></term>
>        <listitem>
>         <para>
> !        This record pertains to connection attempts over Unix
domain
>          sockets.
>         </para>
>        </listitem>
> --- 96,102 ----
>        <term><literal>local</literal></term>
>        <listitem>
>         <para>
> !        This record applies to connection attempts using Unix
domain
>          sockets.
>         </para>
>        </listitem>
> ***************
> *** 107,116 ****
>        <term><literal>host</literal></term>
>        <listitem>
>         <para>
> !        This record pertains to connection attempts over TCP/IP
> !        networks. Note that TCP/IP connections are completely
disabled
> !        unless the server is started with the <option>-i</option>
switch or
> !        the equivalent configuration parameter is set.
>         </para>
>        </listitem>
>       </varlistentry>
> --- 106,116 ----
>        <term><literal>host</literal></term>
>        <listitem>
>         <para>
> !        This record applied to connection attempts using TCP/IP
networks.
> !        Note that TCP/IP connections are disabled unless the server
is
> !        started with the <option>-i</option> option or the
> !        <literal>tcpip_socket</> <filename>postgresql.conf</>
> !        configuration parameter is enabled.
>         </para>
>        </listitem>
>       </varlistentry>
> ***************
> *** 119,131 ****
>        <term><literal>hostssl</literal></term>
>        <listitem>
>         <para>
> !        This record pertains to connection attempts with SSL over
>          TCP/IP. To make use of this option the server must be
>          built with SSL support enabled. Furthermore, SSL must be
>          enabled with the <option>-l</> option or equivalent
configuration
>          setting when the server is started.  (Note:
<literal>host</literal>
>          records will match either SSL or non-SSL connection
attempts, but
> !        <literal>hostssl</literal> records match only SSL
connections.)
>         </para>
>        </listitem>
>       </varlistentry>
> --- 119,131 ----
>        <term><literal>hostssl</literal></term>
>        <listitem>
>         <para>
> !        This record applies to connection attempts using SSL over
>          TCP/IP. To make use of this option the server must be
>          built with SSL support enabled. Furthermore, SSL must be
>          enabled with the <option>-l</> option or equivalent
configuration
>          setting when the server is started.  (Note:
<literal>host</literal>
>          records will match either SSL or non-SSL connection
attempts, but
> !        <literal>hostssl</literal> records requires SSL
connections.)
>         </para>
>        </listitem>
>       </varlistentry>
> ***************
> *** 134,145 ****
>        <term><replaceable>database</replaceable></term>
>        <listitem>
>         <para>
> !        Specifies the database that this record applies to. The
value
>          <literal>all</literal> specifies that it applies to all
>          databases, while the value <literal>sameuser</> identifies
the
> !        database with the same name as the connecting user.
Otherwise,
> !        this is the name of a specific
<productname>PostgreSQL</productname>
> !        database.
>         </para>
>        </listitem>
>       </varlistentry>
> --- 134,165 ----
>        <term><replaceable>database</replaceable></term>
>        <listitem>
>         <para>
> !        Specifies the database for this record. The value
>          <literal>all</literal> specifies that it applies to all
>          databases, while the value <literal>sameuser</> identifies
the
> !        database with the same name as the connecting user.
Otherwise,
> !        this is the name of a specific
> !        <productname>PostgreSQL</productname> database. Multiple
database
> !        names can be supplied by separating them with commas. A
file
> !        containing database names can be specified by preceding the
file
> !        name with <literal>@</>. The file must be in the same
directory
> !        as <filename>pg_hba.conf</>.
> !       </para>
> !      </listitem>
> !     </varlistentry>
> !
> !     <varlistentry>
> !      <term><replaceable>user</replaceable></term>
> !      <listitem>
> !       <para>
> !        Specifies the user for this record. The value
> !        <literal>all</literal> specifies that it applies to all
users.
> !        Otherwise, this is the name of a specific
> !        <productname>PostgreSQL</productname> user. Multiple user
> !        names can be supplied by separating them with commas. A
file
> !        containing user names can be specified by preceding the
file
> !        name with <literal>@</>. The file must be in the same
directory
> !        as <filename>pg_hba.conf</>.
>         </para>
>        </listitem>
>       </varlistentry>
> ***************
> *** 149,158 ****
>        <term><replaceable>IP mask</replaceable></term>
>        <listitem>
>         <para>
> !        These two fields specify to which client machines a
> !        <literal>host</literal> or <literal>hostssl</literal>
> !        record applies, based on their IP
> !        address. (Of course IP addresses can be spoofed but this
>          consideration is beyond the scope of
>          <productname>PostgreSQL</productname>.) The precise logic
is that
>          <blockquote>
> --- 169,177 ----
>        <term><replaceable>IP mask</replaceable></term>
>        <listitem>
>         <para>
> !        These two fields specify the client machine IP addresses
> !        (<literal>host</literal> or <literal>hostssl</literal>) for
this
> !        record. (Of course IP addresses can be spoofed but this
>          consideration is beyond the scope of
>          <productname>PostgreSQL</productname>.) The precise logic
is that
>          <blockquote>
> ***************
> *** 169,178 ****
>        <term><replaceable>authentication method</replaceable></term>
>        <listitem>
>         <para>
> !        Specifies the method that users must use to authenticate
themselves
> !        when connecting under the control of this authentication
record.
> !        The possible choices are summarized here,
> !        details are in <xref linkend="auth-methods">.
>
>          <variablelist>
>           <varlistentry>
> --- 188,196 ----
>        <term><replaceable>authentication method</replaceable></term>
>        <listitem>
>         <para>
> !        Specifies the authentication method to use when connecting
via
> !        this record. The possible choices are summarized here;
details
> !        are in <xref linkend="auth-methods">.
>
>          <variablelist>
>           <varlistentry>
> ***************
> *** 190,255 ****
>           <term><literal>reject</></term>
>           <listitem>
>            <para>
> !           The connection is rejected unconditionally. This is
mostly
> !           useful to <quote>filter out</> certain hosts from a
group.
>            </para>
>           </listitem>
>          </varlistentry>
>
>          <varlistentry>
> !         <term><literal>password</></term>
>           <listitem>
>            <para>
> !           The client is required to supply a password which is
required to
> !   match the database password that was set up for the user.
> !          </para>
> !
> !          <para>
> !           An optional file name may be specified after the
> !           <literal>password</literal> keyword. This file is
expected to
> !           contain a list of users who may connect using this
record,
> !           and optionally alternative passwords for them.
> !          </para>
> !
> !          <para>
> !           The password is sent over the wire in clear text. For
better
> !           protection, use the <literal>md5</literal> or
> !           <literal>crypt</literal> methods.
>            </para>
>           </listitem>
>          </varlistentry>
>
>          <varlistentry>
> !         <term><literal>md5</></term>
>           <listitem>
>            <para>
> !           Like the <literal>password</literal> method, but the
password
> !           is sent over the wire encrypted using a simple
> !           challenge-response protocol. This protects against
incidental
> !           wire-sniffing.  This is now the recommended choice for
> !   password-based authentication.
> !          </para>
> !
> !          <para>
> !   The name of a file may follow the
> !           <literal>md5</literal> keyword.  It contains a list of
users
> !           who may connect using this record.
>            </para>
>           </listitem>
>          </varlistentry>
>
>          <varlistentry>
> !         <term><literal>crypt</></term>
>           <listitem>
>            <para>
> !           Like the <literal>md5</literal> method but uses older
crypt
> !           encryption, which is needed for pre-7.2
> !   clients. <literal>md5</literal> is
> !           preferred for 7.2 and later clients. The
<literal>crypt</>
> !           method is not compatible with encrypting passwords in
> !           <filename>pg_shadow</>, and may fail if client and
server
> !           machines have different implementations of the crypt()
library
> !           routine.
>            </para>
>           </listitem>
>          </varlistentry>
> --- 208,248 ----
>           <term><literal>reject</></term>
>           <listitem>
>            <para>
> !           The connection is rejected unconditionally. This is
useful for
> !           <quote>filtering out</> certain hosts from a group.
>            </para>
>           </listitem>
>          </varlistentry>
>
>          <varlistentry>
> !         <term><literal>md5</></term>
>           <listitem>
>            <para>
> !           Requires the client to supply an MD5 encrypted password
for
> !           authentication. This is the only method that allows
encrypted
> !           passwords to be stored in pg_shadow.
>            </para>
>           </listitem>
>          </varlistentry>
>
>          <varlistentry>
> !         <term><literal>crypt</></term>
>           <listitem>
>            <para>
> !           Like <literal>md5</literal> method but uses older crypt
> !           encryption, which is needed for pre-7.2 clients.
> !           <literal>md5</literal> is preferred for 7.2 and later
clients.
>            </para>
>           </listitem>
>          </varlistentry>
>
>          <varlistentry>
> !         <term><literal>password</></term>
>           <listitem>
>            <para>
> !           Same as "md5", but the password is sent in cleartext
over the
> !           network. This should not be used on untrusted networks.
> !          </para>
>            </para>
>           </listitem>
>          </varlistentry>
> ***************
> *** 278,311 ****
>           <term><literal>ident</></term>
>           <listitem>
>   <para>
> !   The identity of the user as determined on login to the
> !   operating system is used by
<productname>PostgreSQL</productname>
> !   to determine whether the user
> !           is allowed to connect as the requested database user.
> !   For TCP/IP connections the user's identity is determined by
> !   contacting the <firstterm>ident</firstterm> server on the client
> !   host.  (Note that this is only as reliable as the remote ident
> !   server; ident authentication should never be used for remote
hosts
> !   whose administrators are not trustworthy.)
> !   On operating systems
> !   supporting <symbol>SO_PEERCRED</> requests for Unix domain
sockets,
> !   ident authentication is possible for local connections;
> !   the system is then asked for the connecting user's identity.
>   </para>
>            <para>
> !   On systems without <symbol>SO_PEERCRED</> requests, ident
authentication
> !   is only available for TCP/IP connections.  As a workaround,
> !   it is possible to
> !   specify the <systemitem class="systemname">localhost</> address
> !           <systemitem class="systemname">127.0.0.1</> and make
connections
> !   to this address.
> ! </para>
> !          <para>
> !           The <replaceable>authentication option</replaceable>
following
> !           the <literal>ident</> keyword specifies the name of an
> !           <firstterm>ident map</firstterm> that specifies which
operating
> !           system users equate with which database users. See below
for
> !           details.
>            </para>
>           </listitem>
>          </varlistentry>
> --- 271,306 ----
>           <term><literal>ident</></term>
>           <listitem>
>   <para>
> !           For TCP/IP connections, authentication is done by
contacting
> !           the <firstterm>ident</firstterm> server on the client
host.
> !           This is only as secure as the client machine. You must
specify
> !           the map name after the 'ident' keyword. It determines
how to
> !           map remote user names to PostgreSQL user names. If you
use
> !           "sameuser", the user names are assumed to be identical.
If
> !           not, the map name is looked up in the
$PGDATA/pg_ident.conf
> !           file. The connection is accepted if that file contains
an
> !           entry for this map name with the ident-supplied username
and
> !           the requested PostgreSQL username.
> !          </para>
> !          <para>
> !           On machines that support unix-domain socket credentials
> !           (currently Linux, FreeBSD, NetBSD, and BSD/OS), ident
allows
> !           reliable authentication of 'local' connections without
ident
> !           running on the local machine.
> !          </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.
>   </para>
>            <para>
> !           Following the <literal>ident</> keyword, an
<firstterm>ident
> !           map</firstterm> name should be supplied which specifies
which
> !           operating system users equate with which database users.
See
> !           below for details.
>            </para>
>           </listitem>
>          </varlistentry>
> ***************
> *** 315,331 ****
>           <listitem>
>            <para>
>             This authentication type operates similarly to
> !           <firstterm>password</firstterm>, with the main
difference that
> !           it will use PAM (Pluggable Authentication Modules) as
the
> !           authentication mechanism. The
<replaceable>authentication
> !           option</replaceable> following the <literal>pam</>
keyword
> !           specifies the service name that will be passed to PAM.
The
> !           default service name is <literal>postgresql</literal>.
> !           For more information about PAM, please read the <ulink
> !
url="http://www.kernel.org/pub/linux/libs/pam/"><productname>Linux-PAM
</productname>
> !           Page</ulink> and/or the <ulink
> !
url="http://www.sun.com/software/solaris/pam/"><systemitem
class="osname">Solaris</> PAM
> !           Page</ulink>.
>            </para>
>           </listitem>
>          </varlistentry>
> --- 310,325 ----
>           <listitem>
>            <para>
>             This authentication type operates similarly to
> !           <firstterm>password</firstterm> except that it uses PAM
> !           (Pluggable Authentication Modules) as the authentication
> !           mechanism. The default PAM service name is
> !           <literal>postgresql</literal>. You can optionally supply
you
> !           own service name after the <literal>pam</> keyword in
the
> !           file. For more information about PAM, please read the
<ulink
> !
url="http://www.kernel.org/pub/linux/libs/pam/"><productname>L
> !           inux-PAM</productname> Page</ulink> and the <ulink
> !
url="http://www.sun.com/software/solaris/pam/"><systemitem
> !           class="osname">Solaris</> PAM Page</ulink>.
>            </para>
>           </listitem>
>          </varlistentry>
> ***************
> *** 336,377 ****
>        </listitem>
>       </varlistentry>
>
> -     <varlistentry>
> -      <term><replaceable>authentication option</replaceable></term>
> -      <listitem>
> -       <para>
> -        This field is interpreted differently depending on the
> -        authentication method, as described above.
> -       </para>
> -      </listitem>
> -     </varlistentry>
>      </variablelist>
>     </para>
>
>     <para>
>      Since the <filename>pg_hba.conf</filename> records are examined
>      sequentially for each connection attempt, the order of the
records is
> !    very significant.  Typically, earlier records will have tight
> !    connection match parameters and weaker authentication methods,
> !    while later records will have looser match parameters and
stronger
> !    authentication methods.  For example, one might wish to use
> !    <literal>trust</> authentication for local TCP connections but
> !    require a password for remote TCP connections.  In this case a
> !    record specifying <literal>trust</> authentication for
connections
> !    from 127.0.0.1 would appear before a record specifying password
> !    authentication for a wider range of allowed client IP
addresses.
>     </para>
>
>     <para>
>       <indexterm>
>        <primary>SIGHUP</primary>
>       </indexterm>
> !    The <filename>pg_hba.conf</filename> file is read on startup
> !    and when the <application>postmaster</> receives a
>      <systemitem>SIGHUP</systemitem> signal. If you edit the file on
an
>      active system, you will need to signal the
<application>postmaster</>
> !    (using <literal>pg_ctl reload</> or <literal>kill -HUP</>)
> !    to make it re-read the file.
>     </para>
>
>     <para>
> --- 330,362 ----
>        </listitem>
>       </varlistentry>
>
>      </variablelist>
>     </para>
>
>     <para>
>      Since the <filename>pg_hba.conf</filename> records are examined
>      sequentially for each connection attempt, the order of the
records is
> !    significant. Typically, earlier records will have tight
connection
> !    match parameters and weaker authentication methods, while later
> !    records will have looser match parameters and stronger
authentication
> !    methods. For example, one might wish to use <literal>trust</>
> !    authentication for local TCP connections but require a password
for
> !    remote TCP connections. In this case a record specifying
> !    <literal>trust</> authentication for connections from 127.0.0.1
would
> !    appear before a record specifying password authentication for a
wider
> !    range of allowed client IP addresses.
>     </para>
>
>     <para>
>       <indexterm>
>        <primary>SIGHUP</primary>
>       </indexterm>
> !    The <filename>pg_hba.conf</filename> file is read on startup
and when
> !    the <application>postmaster</> receives a
>      <systemitem>SIGHUP</systemitem> signal. If you edit the file on
an
>      active system, you will need to signal the
<application>postmaster</>
> !    (using <literal>pg_ctl reload</> or <literal>kill -HUP</>) to
make it
> !    re-read the file.
>     </para>
>
>     <para>
> ***************
> *** 382,408 ****
>      <example id="example-pg-hba.conf">
>       <title>An example <filename>pg_hba.conf</filename>
file</title>
>   <programlisting>
> ! # TYPE       DATABASE    IP_ADDRESS    MASK               AUTHTYPE
MAP
>
>   # Allow any user on the local system to connect to any
>   # database under any username, but only via an IP connection:
>
> ! host         all         127.0.0.1     255.255.255.255    trust
>
>   # The same, over Unix-socket connections:
>
> ! local        all                                          trust
>
>   # Allow any user from any host with IP address 192.168.93.x to
>   # connect to database "template1" as the same username that ident
on that
>   # host identifies him as (typically his Unix username):
>
> ! host         template1   192.168.93.0  255.255.255.0      ident
sameuser
>
>   # Allow a user from host 192.168.12.10 to connect to database
"template1"
> ! # if the user's password in pg_shadow is correctly supplied:
>
> ! host         template1   192.168.12.10 255.255.255.255    md5
>
>   # In the absence of preceding "host" lines, these two lines will
reject
>   # all connection attempts from 192.168.54.1 (since that entry will
be
> --- 367,393 ----
>      <example id="example-pg-hba.conf">
>       <title>An example <filename>pg_hba.conf</filename>
file</title>
>   <programlisting>
> ! # TYPE       DATABASE    USER       IP_ADDRESS    MASK
AUTHTYPE
>
>   # Allow any user on the local system to connect to any
>   # database under any username, but only via an IP connection:
>
> ! host         all         all        127.0.0.1     255.255.255.255
trust
>
>   # The same, over Unix-socket connections:
>
> ! local        all         all
trust
>
>   # Allow any user from any host with IP address 192.168.93.x to
>   # connect to database "template1" as the same username that ident
on that
>   # host identifies him as (typically his Unix username):
>
> ! host         template1   all        192.168.93.0  255.255.255.0
ident sameuser
>
>   # Allow a user from host 192.168.12.10 to connect to database
"template1"
> ! # if the user's password is correctly supplied:
>
> ! host         template1   all        192.168.12.10 255.255.255.255
md5
>
>   # In the absence of preceding "host" lines, these two lines will
reject
>   # all connection attempts from 192.168.54.1 (since that entry will
be
> ***************
> *** 410,417 ****
>   # else on the Internet. The zero mask means that no bits of the
host IP
>   # address are considered, so it matches any host:
>
> ! host         all        192.168.54.1   255.255.255.255    reject
> ! host         all        0.0.0.0        0.0.0.0            krb5
>
>   # Allow users from 192.168.x.x hosts to connect to any database,
if they
>   # pass the ident check.  If, for example, ident says the user is
"bryanh"
> --- 395,402 ----
>   # else on the Internet. The zero mask means that no bits of the
host IP
>   # address are considered, so it matches any host:
>
> ! host         all        all         192.168.54.1   255.255.255.255
reject
> ! host         all        all         0.0.0.0        0.0.0.0
krb5
>
>   # Allow users from 192.168.x.x hosts to connect to any database,
if they
>   # pass the ident check.  If, for example, ident says the user is
"bryanh"
> ***************
> *** 419,425 ****
>   # is allowed if there is an entry in pg_ident.conf for map
"omicron" that
>   # says "bryanh" is allowed to connect as "guest1":
>
> ! host         all        192.168.0.0    255.255.0.0        ident
omicron
>
>   # If these are the only two lines for local connections, they will
allow
>   # local users to connect only to their own databases (database
named the
> --- 404,410 ----
>   # is allowed if there is an entry in pg_ident.conf for map
"omicron" that
>   # says "bryanh" is allowed to connect as "guest1":
>
> ! host         all        all         192.168.0.0    255.255.0.0
ident omicron
>
>   # If these are the only two lines for local connections, they will
allow
>   # local users to connect only to their own databases (database
named the
> ***************
> *** 429,436 ****
>   # cases.  (If you prefer to use ident authorization, an ident map
can
>   # serve a parallel purpose to the password list file used here.)
>
> ! local        sameuser                                     md5
> ! local        all                                          md5
admins
>   </programlisting>
>      </example>
>     </para>
> --- 414,421 ----
>   # cases.  (If you prefer to use ident authorization, an ident map
can
>   # serve a parallel purpose to the password list file used here.)
>
> ! local        sameuser   all
md5
> ! local        all        @admins
md5
>   </programlisting>
>      </example>
>     </para>
> ***************
> *** 490,575 ****
>      <title>Password authentication</title>
>
>      <indexterm>
> !     <primary>password</primary>
>      </indexterm>
>      <indexterm>
> !     <primary>MD5</>
>      </indexterm>
>
>      <para>
>       Password-based authentication methods include <literal>md5</>,
> !     <literal>crypt</>, and <literal>password</>.  These methods
operate
>       similarly except for the way that the password is sent across
the
> !     connection.  If you are at all concerned about password
<quote>sniffing</>
> !     attacks then <literal>md5</> is preferred, with
<literal>crypt</> a
> !     second choice if you must support obsolete clients.  Plain
> !     <literal>password</> should especially be avoided for
connections over
> !     the open Internet (unless you use SSL, SSH, or other
communications
> !     security wrappers around the connection).
>      </para>
>
>      <para>
> !     <productname>PostgreSQL</productname> database passwords are
separate from
> !     operating system user passwords. Ordinarily, the password for
each
> !     database user is stored in the pg_shadow system catalog table.
> !     Passwords can be managed with the query language commands
> !     <command>CREATE USER</command> and <command>ALTER
USER</command>,
> !     e.g., <userinput>CREATE USER foo WITH PASSWORD
> !     'secret';</userinput>. By default, that is, if no password has
> !     been set up, the stored password is <literal>NULL</literal>
> !     and password authentication will always fail for that user.
>      </para>
>
>      <para>
>       To restrict the set of users that are allowed to connect to
certain
> !     databases, list the set of users in a separate file (one user
name
> !     per line) in the same directory that <filename>pg_hba.conf</>
is in,
> !     and mention the (base) name of the file after the
> !     <literal>password</>, <literal>md5</>, or <literal>crypt</>
keyword,
> !     respectively, in <filename>pg_hba.conf</>. If you do not use
this
> !     feature, then any user that is known to the database system
can
> !     connect to any database (so long as he supplies the correct
password,
> !     of course).
> !    </para>
> !
> !    <para>
> !     These files can also be used to apply a different set of
passwords
> !     to a particular database or set thereof. In that case, the
files
> !     have a format similar to the standard Unix password file
> !     <filename>/etc/passwd</filename>, that is,
> ! <synopsis>
> !
<replaceable>username</replaceable>:<replaceable>password</replaceable
>
> ! </synopsis>
> !     Any extra colon-separated fields following the password are
> !     ignored. The password is expected to be encrypted using the
> !     system's <function>crypt()</function> function. The utility
> !     program <application>pg_passwd</application> that is installed
> !     with <productname>PostgreSQL</productname> can be used to
manage
> !     these password files.
> !    </para>
> !
> !    <para>
> !     Lines with and without passwords can be mixed in secondary
> !     password files. Lines without password indicate use of the
main
> !     password in <literal>pg_shadow</> that is managed by
> !     <command>CREATE USER</> and <command>ALTER USER</>. Lines with
> !     passwords will cause that password to be used. A password
entry of
> !     <quote>+</quote> also means using the pg_shadow password.
> !    </para>
> !
> !    <para>
> !     Alternative passwords cannot be used when using the
<literal>md5</>
> !     or <literal>crypt</> methods. The file will be read as
> !     usual, but the password field will simply be ignored and the
> !     <literal>pg_shadow</> password will always be used.
> !    </para>
> !
> !    <para>
> !     Note that using alternative passwords like this means that one
can
> !     no longer use <command>ALTER USER</command> to change one's
> !     password. It will appear to work but the password one is
> !     changing is not the password that the system will end up
> !     using.
>      </para>
>
>     </sect2>
> --- 475,522 ----
>      <title>Password authentication</title>
>
>      <indexterm>
> !     <primary>MD5</>
>      </indexterm>
>      <indexterm>
> !     <primary>crypt</>
> !    </indexterm>
> !    <indexterm>
> !     <primary>password</primary>
>      </indexterm>
>
>      <para>
>       Password-based authentication methods include <literal>md5</>,
> !     <literal>crypt</>, and <literal>password</>. These methods
operate
>       similarly except for the way that the password is sent across
the
> !     connection. If you are at all concerned about password
> !     <quote>sniffing</> attacks then <literal>md5</> is preferred,
with
> !     <literal>crypt</> a second choice if you must support pre-7.2
> !     clients. Plain <literal>password</> should especially be
avoided for
> !     connections over the open Internet (unless you use SSL, SSH,
or
> !     other communications security wrappers around the connection).
>      </para>
>
>      <para>
> !     <productname>PostgreSQL</productname> database passwords are
> !     separate from operating system user passwords. Ordinarily, the
> !     password for each database user is stored in the pg_shadow
system
> !     catalog table. Passwords can be managed with the query
language
> !     commands <command>CREATE USER</command> and <command>ALTER
> !     USER</command>, e.g., <userinput>CREATE USER foo WITH PASSWORD
> !     'secret';</userinput>. By default, that is, if no password has
been
> !     set up, the stored password is <literal>NULL</literal> and
password
> !     authentication will always fail for that user.
>      </para>
>
>      <para>
>       To restrict the set of users that are allowed to connect to
certain
> !     databases, list the users separated by commas, or in a
separate
> !     file. The file should contain user names separated by commas
or one
> !     user name per line, and be in the same directory as
> !     <filename>pg_hba.conf</>. Mention the (base) name of the file
> !     preceded by <literal>@</>in the <literal>USER</> column. The
> !     <literal>DATABASE</> column can similarly accept a list of
values or
> !     a file name.
>      </para>
>
>     </sect2>
> ***************
> *** 588,597 ****
>       <productname>Kerberos</productname> system is far beyond the
scope
>       of this document; in all generality it can be quite complex
(yet
>       powerful). The <ulink
> !
url="http://www.nrl.navy.mil/CCS/people/kenh/kerberos-faq.html">Kerber
os
> !     <acronym>FAQ</></ulink> or <ulink
> !     url="ftp://athena-dist.mit.edu">MIT Project Athena</ulink> can
be
> !     a good starting point for exploration. Several sources for
>       <productname>Kerberos</> distributions exist.
>      </para>
>
> --- 535,544 ----
>       <productname>Kerberos</productname> system is far beyond the
scope
>       of this document; in all generality it can be quite complex
(yet
>       powerful). The <ulink
> !
url="http://www.nrl.navy.mil/CCS/people/kenh/kerberos-faq.html">Kerb
> !     eros <acronym>FAQ</></ulink> or <ulink
> !     url="ftp://athena-dist.mit.edu">MIT Project Athena</ulink> can
be a
> !     good starting point for exploration. Several sources for
>       <productname>Kerberos</> distributions exist.
>      </para>
>
> ***************
> *** 606,639 ****
>      <para>
>       <productname>PostgreSQL</> operates like a normal Kerberos
service.
>       The name of the service principal is
> !     <replaceable>servicename/hostname@realm</>, where
> !     <replaceable>servicename</> is <literal>postgres</literal>
> !     (unless a different service name was selected at configure
time
> !     with <literal>./configure --with-krb-srvnam=whatever</>).
> !     <replaceable>hostname</> is the fully qualified domain name of
the server
> !     machine.  The service principal's realm is the preferred realm
of the
> !     server machine.
>      </para>
>
>      <para>
> !     Client principals must have their <productname>PostgreSQL</>
user name as
> !     their first component, for example
> !     <replaceable>pgusername/otherstuff@realm</>.
> !     At present the realm of the client is not checked by
> !     <productname>PostgreSQL</>; so
> !     if you have cross-realm authentication enabled, then any
principal
> !     in any realm that can communicate with yours will be accepted.
>      </para>
>
>      <para>
> !     Make sure that your server key file is readable (and
> !     preferably only readable) by the
> !     <productname>PostgreSQL</productname> server account (see
> !     <xref linkend="postgres-user">). The location of the key file
> !     is specified with the <varname>krb_server_keyfile</> run time
> !     configuration parameter. (See also <xref
linkend="runtime-config">.)
> !     The default is <filename>/etc/srvtab</> if you are using
Kerberos 4
> !     and <filename>FILE:/usr/local/pgsql/etc/krb5.keytab</> (or
whichever
>       directory was specified as <varname>sysconfdir</> at build
time)
>       with Kerberos 5.
>      </para>
> --- 553,585 ----
>      <para>
>       <productname>PostgreSQL</> operates like a normal Kerberos
service.
>       The name of the service principal is
> !     <replaceable>servicename/hostname@realm</>, where
> !     <replaceable>servicename</> is <literal>postgres</literal>
(unless a
> !     different service name was selected at configure time with
> !     <literal>./configure --with-krb-srvnam=whatever</>).
> !     <replaceable>hostname</> is the fully qualified domain name of
the
> !     server machine. The service principal's realm is the preferred
realm
> !     of the server machine.
>      </para>
>
>      <para>
> !     Client principals must have their <productname>PostgreSQL</>
user
> !     name as their first component, for example
> !     <replaceable>pgusername/otherstuff@realm</>. At present the
realm of
> !     the client is not checked by <productname>PostgreSQL</>; so if
you
> !     have cross-realm authentication enabled, then any principal in
any
> !     realm that can communicate with yours will be accepted.
>      </para>
>
>      <para>
> !     Make sure that your server key file is readable (and
preferably only
> !     readable) by the <productname>PostgreSQL</productname> server
> !     account (see <xref linkend="postgres-user">). The location of
the
> !     key file is specified with the <varname>krb_server_keyfile</>
run
> !     time configuration parameter. (See also <xref
> !     linkend="runtime-config">.) The default is
<filename>/etc/srvtab</>
> !     if you are using Kerberos 4 and
> !     <filename>FILE:/usr/local/pgsql/etc/krb5.keytab</> (or
whichever
>       directory was specified as <varname>sysconfdir</> at build
time)
>       with Kerberos 5.
>      </para>
> ***************
> *** 649,666 ****
>
>      <para>
>       When connecting to the database make sure you have a ticket
for a
> !     principal matching the requested database user name.
> !     An example: For database user name <literal>fred</>, both
principal
>       <literal>fred@EXAMPLE.COM</> and
> !     <literal>fred/users.example.com@EXAMPLE.COM</> can be
> !     used to authenticate to the database server.
>      </para>
>
>      <para>
> !     If you use <application>mod_auth_krb</application> and
<application>mod_perl</application> on your
<productname>Apache</productname> web server,
> !     you can use <literal>AuthType
KerberosV5SaveCredentials</literal> with a
<application>mod_perl</application>
> !     script. This gives secure database access over the web, no
extra
> !     passwords required.
>      </para>
>
>     </sect2>
> --- 595,614 ----
>
>      <para>
>       When connecting to the database make sure you have a ticket
for a
> !     principal matching the requested database user name. An
example: For
> !     database user name <literal>fred</>, both principal
>       <literal>fred@EXAMPLE.COM</> and
> !     <literal>fred/users.example.com@EXAMPLE.COM</> can be used to
> !     authenticate to the database server.
>      </para>
>
>      <para>
> !     If you use <application>mod_auth_krb</application> and
> !     <application>mod_perl</application> on your
> !     <productname>Apache</productname> web server, you can use
> !     <literal>AuthType KerberosV5SaveCredentials</literal> with a
> !     <application>mod_perl</application> script. This gives secure
> !     database access over the web, no extra passwords required.
>      </para>
>
>     </sect2>
> ***************
> *** 707,761 ****
>      </para>
>
>      <para>
> !     On systems supporting <symbol>SO_PEERCRED</symbol> requests
for Unix-domain sockets,
> !     ident authentication can also be applied to local connections.
In this
> !     case, no security risk is added by using ident authentication;
indeed
> !     it is a preferable choice for local connections on such a
system.
>      </para>
>
>      <para>
>       When using ident-based authentication, after having determined
the
>       name of the operating system user that initiated the
connection,
> !     <productname>PostgreSQL</productname> checks whether that user
is allowed
> !     to connect as the database user he is requesting to connect
as.
> !     This is controlled by the ident map
> !     argument that follows the <literal>ident</> keyword in the
> !     <filename>pg_hba.conf</filename> file. There is a predefined
ident map
> !     <literal>sameuser</literal>, which allows any operating system
> !     user to connect as the database user of the same name (if the
> !     latter exists). Other maps must be created manually.
>      </para>
>
>      <para>
> !     <indexterm><primary>pg_ident.conf</primary></indexterm>
> !     Ident maps other than <literal>sameuser</literal> are defined
> !     in the file <filename>pg_ident.conf</filename>
> !     in the data directory, which contains lines of the general
form:
>   <synopsis>
>   <replaceable>map-name</> <replaceable>ident-username</>
<replaceable>database-username</>
>   </synopsis>
> !     Comments and whitespace are handled in the usual way.
> !     The <replaceable>map-name</> is an arbitrary name that will be
> !     used to refer to this mapping in
<filename>pg_hba.conf</filename>.
> !     The other two fields specify which operating system user is
> !     allowed to connect as which database user. The same
> !     <replaceable>map-name</> can be used repeatedly to specify
more
> !     user-mappings within a single map. There is no restriction
regarding
> !     how many
> !     database users a given operating system user may correspond to
and vice
> !     versa.
>      </para>
>
>     <para>
>       <indexterm>
>        <primary>SIGHUP</primary>
>       </indexterm>
> !    The <filename>pg_ident.conf</filename> file is read on startup
> !    and when the <application>postmaster</> receives a
>      <systemitem>SIGHUP</systemitem> signal. If you edit the file on
an
>      active system, you will need to signal the
<application>postmaster</>
> !    (using <literal>pg_ctl reload</> or <literal>kill -HUP</>)
> !    to make it re-read the file.
>     </para>
>
>      <para>
> --- 655,708 ----
>      </para>
>
>      <para>
> !     On systems supporting <symbol>SO_PEERCRED</symbol> requests
for
> !     Unix-domain sockets, ident authentication can also be applied
to
> !     local connections. 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>
>       When using ident-based authentication, after having determined
the
>       name of the operating system user that initiated the
connection,
> !     <productname>PostgreSQL</productname> checks whether that user
is
> !     allowed to connect as the database user he is requesting to
connect
> !     as. This is controlled by the ident map argument that follows
the
> !     <literal>ident</> keyword in the
<filename>pg_hba.conf</filename>
> !     file. There is a predefined ident map
<literal>sameuser</literal>,
> !     which allows any operating system user to connect as the
database
> !     user of the same name (if the latter exists). Other maps must
be
> !     created manually.
>      </para>
>
>      <para>
> !     <indexterm><primary>pg_ident.conf</primary></indexterm> Ident
maps
> !     other than <literal>sameuser</literal> are defined in the file
> !     <filename>pg_ident.conf</filename> in the data directory,
which
> !     contains lines of the general form:
>   <synopsis>
>   <replaceable>map-name</> <replaceable>ident-username</>
<replaceable>database-username</>
>   </synopsis>
> !     Comments and whitespace are handled in the usual way. The
> !     <replaceable>map-name</> is an arbitrary name that will be
used to
> !     refer to this mapping in <filename>pg_hba.conf</filename>. The
other
> !     two fields specify which operating system user is allowed to
connect
> !     as which database user. The same <replaceable>map-name</> can
be
> !     used repeatedly to specify more user-mappings within a single
map.
> !     There is no restriction regarding how many database users a
given
> !     operating system user may correspond to and vice versa.
>      </para>
>
>     <para>
>       <indexterm>
>        <primary>SIGHUP</primary>
>       </indexterm>
> !    The <filename>pg_ident.conf</filename> file is read on startup
and
> !    when the <application>postmaster</> receives a
>      <systemitem>SIGHUP</systemitem> signal. If you edit the file on
an
>      active system, you will need to signal the
<application>postmaster</>
> !    (using <literal>pg_ctl reload</> or <literal>kill -HUP</>) to
make it
> !    re-read the file.
>     </para>
>
>      <para>
> ***************
> *** 763,775 ****
>       conjunction with the <filename>pg_hba.conf</> file in <xref
>       linkend="example-pg-hba.conf"> is shown in <xref
>       linkend="example-pg-ident.conf">. In this example setup,
anyone
> !     logged in to a machine on the 192.168 network that does not
have
> !     the Unix user name <systemitem>bryanh</>, <systemitem>ann</>,
or <systemitem>robert</> would not be granted access.
> !     Unix user <systemitem>robert</> would only be allowed access
when he tries to
> !     connect as <productname>PostgreSQL</> user <systemitem>bob</>,
> !       not as <systemitem>robert</>
> !     or anyone else. <systemitem>ann</> would only be allowed to
connect as
> !     <systemitem>ann</>. User <systemitem>bryanh</> would be
allowed to connect as either
>       <systemitem>bryanh</> himself or as <systemitem>guest1</>.
>      </para>
>
> --- 710,723 ----
>       conjunction with the <filename>pg_hba.conf</> file in <xref
>       linkend="example-pg-hba.conf"> is shown in <xref
>       linkend="example-pg-ident.conf">. In this example setup,
anyone
> !     logged in to a machine on the 192.168 network that does not
have the
> !     Unix user name <systemitem>bryanh</>, <systemitem>ann</>, or
> !     <systemitem>robert</> would not be granted access. Unix user
> !     <systemitem>robert</> would only be allowed access when he
tries to
> !     connect as <productname>PostgreSQL</> user <systemitem>bob</>,
not
> !     as <systemitem>robert</> or anyone else. <systemitem>ann</>
would
> !     only be allowed to connect as <systemitem>ann</>. User
> !     <systemitem>bryanh</> would be allowed to connect as either
>       <systemitem>bryanh</> himself or as <systemitem>guest1</>.
>      </para>
>
> ***************
> *** 799,828 ****
>
>      <para>
>   <ProgramListing>
> ! No pg_hba.conf entry for host 123.123.123.123, user joeblow,
database testdb
>   </ProgramListing>
> !     This is what you are most likely to get if you succeed in
> !     contacting the server, but it does not want to talk to you. As
the
> !     message suggests, the server refused the connection request
> !     because it found no authorizing entry in its
<filename>pg_hba.conf</filename>
>       configuration file.
>      </para>
>
>      <para>
>   <ProgramListing>
> ! Password authentication failed for user 'joeblow'
>   </ProgramListing>
> !     Messages like this indicate that you contacted the server, and
> !     it is willing to talk to you, but not until you pass the
> !     authorization method specified in the
> !     <filename>pg_hba.conf</filename> file. Check the password you
are
> !     providing, or check your Kerberos or ident software if the
> !     complaint mentions one of those authentication types.
>      </para>
>
>      <para>
>   <ProgramListing>
> ! FATAL 1:  user "joeblow" does not exist
>   </ProgramListing>
>       The indicated user name was not found.
>      </para>
> --- 747,776 ----
>
>      <para>
>   <ProgramListing>
> ! No pg_hba.conf entry for host 123.123.123.123, user andym,
database testdb
>   </ProgramListing>
> !     This is what you are most likely to get if you succeed in
contacting
> !     the server, but it does not want to talk to you. As the
message
> !     suggests, the server refused the connection request because it
found
> !     no authorizing entry in its <filename>pg_hba.conf</filename>
>       configuration file.
>      </para>
>
>      <para>
>   <ProgramListing>
> ! Password authentication failed for user 'andym'
>   </ProgramListing>
> !     Messages like this indicate that you contacted the server, and
it is
> !     willing to talk to you, but not until you pass the
authorization
> !     method specified in the <filename>pg_hba.conf</filename> file.
Check
> !     the password you are providing, or check your Kerberos or
ident
> !     software if the complaint mentions one of those authentication
> !     types.
>      </para>
>
>      <para>
>   <ProgramListing>
> ! FATAL 1:  user "andym" does not exist
>   </ProgramListing>
>       The indicated user name was not found.
>      </para>
> ***************
> *** 837,845 ****
>      </para>
>
>      <para>
> !     Note that the server log may contain more information
> !     about an authentication failure than is reported to the
client.
> !     If you are confused about the reason for a failure, check the
log.
>      </para>
>     </sect1>
>
> --- 785,793 ----
>      </para>
>
>      <para>
> !     Note that the server log may contain more information about an
> !     authentication failure than is reported to the client. If you
are
> !     confused about the reason for a failure, check the log.
>      </para>
>     </sect1>
>
> Index: doc/src/sgml/reference.sgml
> ===================================================================
> RCS file: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v
> retrieving revision 1.24
> diff -c -r1.24 reference.sgml
> *** doc/src/sgml/reference.sgml 19 Mar 2002 02:18:11 -0000 1.24
> --- doc/src/sgml/reference.sgml 19 Mar 2002 05:51:45 -0000
> ***************
> *** 191,197 ****
>      &initlocation;
>      &ipcclean;
>      &pgCtl;
> -    &pgPasswd;
>      &postgres;
>      &postmaster;
>
> --- 191,196 ----
> Index: doc/src/sgml/ref/allfiles.sgml
> ===================================================================
> RCS file: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v
> retrieving revision 1.36
> diff -c -r1.36 allfiles.sgml
> *** doc/src/sgml/ref/allfiles.sgml 19 Mar 2002 02:18:12 -0000 1.36
> --- doc/src/sgml/ref/allfiles.sgml 19 Mar 2002 05:51:45 -0000
> ***************
> *** 125,131 ****
>   <!entity pgCtl              system "pg_ctl-ref.sgml">
>   <!entity pgDump             system "pg_dump.sgml">
>   <!entity pgDumpall          system "pg_dumpall.sgml">
> - <!entity pgPasswd           system "pg_passwd.sgml">
>   <!entity pgRestore          system "pg_restore.sgml">
>   <!entity pgTclSh            system "pgtclsh.sgml">
>   <!entity pgTkSh             system "pgtksh.sgml">
> --- 125,130 ----
> Index: src/backend/libpq/Makefile
> ===================================================================
> RCS file: /cvsroot/pgsql/src/backend/libpq/Makefile,v
> retrieving revision 1.29
> diff -c -r1.29 Makefile
> *** src/backend/libpq/Makefile 4 Mar 2002 01:46:02 -0000 1.29
> --- src/backend/libpq/Makefile 19 Mar 2002 05:51:45 -0000
> ***************
> *** 14,22 ****
>
>   # be-fsstubs is here for historical reasons, probably belongs
elsewhere
>
> ! OBJS = be-fsstubs.o \
> ! auth.o crypt.o hba.o md5.o password.o \
> ! pqcomm.o pqformat.o pqsignal.o
>
>
>   all: SUBSYS.o
> --- 14,20 ----
>
>   # be-fsstubs is here for historical reasons, probably belongs
elsewhere
>
> ! OBJS = be-fsstubs.o auth.o crypt.o hba.o md5.o pqcomm.o pqformat.o
pqsignal.o
>
>
>   all: SUBSYS.o
> Index: src/backend/libpq/auth.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/backend/libpq/auth.c,v
> retrieving revision 1.79
> diff -c -r1.79 auth.c
> *** src/backend/libpq/auth.c 5 Mar 2002 07:57:45 -0000 1.79
> --- src/backend/libpq/auth.c 19 Mar 2002 05:51:57 -0000
> ***************
> *** 34,40 ****
>   #include "miscadmin.h"
>
>   static void sendAuthRequest(Port *port, AuthRequest areq);
> - static int checkPassword(Port *port, char *user, char *password);
>   static int old_be_recvauth(Port *port);
>   static int map_old_to_new(Port *port, UserAuth old, int status);
>   static void auth_failed(Port *port, int status);
> --- 34,39 ----
> ***************
> *** 381,387 ****
>   saved = port->auth_method;
>   port->auth_method = uaPassword;
>
> ! status = checkPassword(port, user, password);
>
>   port->auth_method = saved;
>
> --- 380,386 ----
>   saved = port->auth_method;
>   port->auth_method = uaPassword;
>
> ! status = md5_crypt_verify(port, user, password);
>
>   port->auth_method = saved;
>
> ***************
> *** 663,669 ****
>
>   initStringInfo(&buf);
>   pq_getstr(&buf);
> !
>   /* Do not echo failed password to logs, for security. */
>   elog(DEBUG5, "received PAM packet");
>
> --- 662,668 ----
>
>   initStringInfo(&buf);
>   pq_getstr(&buf);
> !
>   /* Do not echo failed password to logs, for security. */
>   elog(DEBUG5, "received PAM packet");
>
> ***************
> *** 810,832 ****
>   /* Do not echo failed password to logs, for security. */
>   elog(DEBUG5, "received password packet");
>
> ! result = checkPassword(port, port->user, buf.data);
>   pfree(buf.data);
>   return result;
> - }
> -
> -
> - /*
> -  * Handle `password' and `crypt' records. If an auth argument was
> -  * specified, use the respective file. Else use pg_shadow
passwords.
> -  */
> - static int
> - checkPassword(Port *port, char *user, char *password)
> - {
> - if (port->auth_arg[0] != '\0')
> - return verify_password(port, user, password);
> -
> - return md5_crypt_verify(port, user, password);
>   }
>
>
> --- 809,818 ----
>   /* Do not echo failed password to logs, for security. */
>   elog(DEBUG5, "received password packet");
>
> ! result = md5_crypt_verify(port, port->user, buf.data);
> !
>   pfree(buf.data);
>   return result;
>   }
>
>
> Index: src/backend/libpq/hba.c
> ===================================================================
> RCS file: /cvsroot/pgsql/src/backend/libpq/hba.c,v
> retrieving revision 1.80
> diff -c -r1.80 hba.c
> *** src/backend/libpq/hba.c 4 Mar 2002 01:46:03 -0000 1.80
> --- src/backend/libpq/hba.c 19 Mar 2002 05:51:58 -0000
> ***************
> *** 54,59 ****
> --- 54,60 ----
>   static List *hba_lines = NIL; /* pre-parsed contents of hba file
*/
>   static List *ident_lines = NIL; /* pre-parsed contents of ident
file */
>
> + static List *tokenize_file(FILE *file);
>
>   /*
>    * Some standard C libraries, including GNU, have an isblank()
function.
> ***************
> *** 79,111 ****
>   next_token(FILE *fp, char *buf, const int bufsz)
>   {
>   int c;
> ! char    *eb = buf + (bufsz - 1);
>
> ! /* Move over initial token-delimiting blanks */
> ! while ((c = getc(fp)) != EOF && isblank(c))
> ! ;
> !
> ! if (c != EOF && c != '\n')
>   {
> ! /*
> ! * build a token in buf of next characters up to EOF, eol, or
> ! * blank.  If the token gets too long, we still parse it
> ! * correctly, but the excess characters are not stored into *buf.
> ! */
> ! while (c != EOF && c != '\n' && !isblank(c))
>   {
> ! if (buf < eb)
> ! *buf++ = c;
> ! c = getc(fp);
>   }
>
> ! /*
> ! * Put back the char right after the token (critical in case it is
> ! * eol, since we need to detect end-of-line at next call).
> ! */
> ! if (c != EOF)
> ! ungetc(c, fp);
> ! }
>   *buf = '\0';
>   }
>
> --- 80,136 ----
>   next_token(FILE *fp, char *buf, const int bufsz)
>   {
>   int c;
> ! char    *end_buf = buf + (bufsz - 1);
> ! char quote = '\0';
> ! bool is_quote;
>
> ! do
>   {
> ! /* Move over initial token-delimiting blanks */
> ! while ((c = getc(fp)) != EOF && isblank(c))
> ! ;
> !
> ! if (c != EOF && c != '\n')
>   {
> ! /*
> ! * build a token in buf of next characters up to EOF, eol, or
> ! * blank.  If the token gets too long, we still parse it
> ! * correctly, but the excess characters are not stored into *buf.
> ! */
> ! while (c != EOF && c != '\n' && (!isblank(c) || quote != '\0'))
> ! {
> ! is_quote = false;
> ! if (c == '"' || c == '\'')
> ! {
> ! /* Allow single or double quoted strings, strip quotes */
> ! if (quote == '\0')
> ! {
> ! quote = c;
> ! is_quote = true;
> ! }
> ! else if (c == quote)
> ! {
> ! quote = '\0';
> ! is_quote = true;
> ! }
> ! }
> !
> ! if (!is_quote && buf < end_buf)
> ! *buf++ = c;
> ! c = getc(fp);
> ! }
> !
> ! /*
> ! * Put back the char right after the token (critical in case it is
> ! * eol, since we need to detect end-of-line at next call).
> ! */
> ! if (c != EOF)
> ! ungetc(c, fp);
>   }
>
> ! /* If the token has a trailing comma, get another token */
> ! } while (*buf == ',' && c != EOF && c != '\n');
> !
>   *buf = '\0';
>   }
>
> ***************
> *** 121,126 ****
> --- 146,241 ----
>
>
>   /*
> +  * Free memory used by lines/tokens (ie, structure built by
tokenize_file)
> +  */
> + static void
> + free_lines(List **lines)
> + {
> + if (*lines)
> + {
> + List    *line,
> +    *token;
> +
> + foreach(line, *lines)
> + {
> + List    *ln = lfirst(line);
> +
> + /* free the pstrdup'd tokens (don't try it on the line number) */
> + foreach(token, lnext(ln))
> + pfree(lfirst(token));
> + /* free the sublist structure itself */
> + freeList(ln);
> + }
> + /* free the list structure itself */
> + freeList(*lines);
> + /* clear the static variable */
> + *lines = NIL;
> + }
> + }
> +
> +
> + static char *
> + tokenize_at_file(const char *at_filename)
> + {
> + char    *at_fullname;
> + FILE    *at_file;
> + List    *at_lines;
> + List    *line;
> + char    *comma_str = NULL;
> + List    *token;
> +
> + at_fullname = (char *) palloc(strlen(DataDir) +
> + strlen(at_filename) + 2);
> + strcpy(at_fullname, DataDir);
> + strcat(at_fullname, "/");
> + strcat(at_fullname, at_filename);
> +
> + at_file = AllocateFile(at_fullname, PG_BINARY_R);
> + if (!at_file)
> + {
> + elog(LOG, "tokenize_at_file: Unable to open secondary
authentication file \"@%s\" as \"%s\": %m",
> + at_filename, at_fullname);
> + pfree(at_fullname);
> +
> + /* return empty string, it matches nothing */
> + return pstrdup("");
> + }
> + pfree(at_fullname);
> +
> + /* There is possible recursion here if the file contains @ */
> + at_lines = tokenize_file(at_file);
> +
> + /* Create comma-separate string from List */
> + foreach(line, at_lines)
> + {
> + List    *ln = lfirst(line);
> +
> + /* First entry is line number */
> + foreach(token, lnext(ln))
> + {
> + if (comma_str != NULL)
> + {
> + comma_str = repalloc(comma_str,
> + strlen(comma_str) + strlen(lfirst(token)) + 2);
> + strcat(comma_str, ",");
> + strcat(comma_str, lfirst(token));
> + }
> + else
> + {
> + comma_str = palloc(strlen(lfirst(token))+1);
> + strcpy(comma_str, lfirst(token));
> + }
> +
> + }
> + }
> + free_lines(&at_lines);
> + FreeFile(at_file);
> +
> + return comma_str;
> + }
> +
> +
> + /*
>    * Read the given file and create a list of line sublists.
>    */
>   static List *
> ***************
> *** 150,157 ****
>   next_line = makeListi1(line_number);
>   lines = lappend(lines, next_line);
>   }
> ! /* append token to current line's list */
> ! next_line = lappend(next_line, pstrdup(buf));
>   }
>   else
>   {
> --- 265,277 ----
>   next_line = makeListi1(line_number);
>   lines = lappend(lines, next_line);
>   }
> ! /* Is this referencing a file? */
> ! if (buf[0] != '@')
> ! /* append token to current line's list */
> ! next_line = lappend(next_line, pstrdup(buf));
> ! else
> ! /* Already palloc'ed */
> ! next_line = lappend(next_line, tokenize_at_file(buf+1));
>   }
>   else
>   {
> ***************
> *** 175,206 ****
>   }
>
>
> ! /*
> !  * Free memory used by lines/tokens (ie, structure built by
tokenize_file)
> !  */
> ! static void
> ! free_lines(List **lines)
>   {
> ! if (*lines)
>   {
> ! List    *line,
> !    *token;
>
> - foreach(line, *lines)
> - {
> - List    *ln = lfirst(line);
>
> ! /* free the pstrdup'd tokens (don't try it on the line number) */
> ! foreach(token, lnext(ln))
> ! pfree(lfirst(token));
> ! /* free the sublist structure itself */
> ! freeList(ln);
> ! }
> ! /* free the list structure itself */
> ! freeList(*lines);
> ! /* clear the static variable */
> ! *lines = NIL;
>   }
>   }
>
>
> --- 295,329 ----
>   }
>
>
> ! static int
> ! check_db(char *dbname, char *user, char *param_str)
>   {
> ! char *tok;
> !
> ! for (tok = strtok(param_str, ","); tok != NULL; tok = strtok(NULL,
","))
>   {
> ! if (strcmp(tok, dbname) == 0 ||
> ! strcmp(tok, "all") == 0 ||
> ! (strcmp(tok, "sameuser") == 0 &&
> ! strcmp(dbname, user) == 0))
> ! return 1;
> ! }
> ! return 0;
> ! }
>
>
> ! static int
> ! check_user(char *user, char *param_str)
> ! {
> ! char *tok;
> !
> ! for (tok = strtok(param_str, ","); tok != NULL; tok = strtok(NULL,
","))
> ! {
> ! if (strcmp(tok, user) == 0 ||
> ! strcmp(tok, "all") == 0)
> ! return 1;
>   }
> + return 0;
>   }
>
>
> ***************
> *** 278,283 ****
> --- 401,407 ----
>   int line_number;
>   char    *token;
>   char    *db;
> + char    *user;
>
>   Assert(line != NIL);
>   line_number = lfirsti(line);
> ***************
> *** 293,302 ****
>   goto hba_syntax;
>   db = lfirst(line);
>
> ! /* Read the rest of the line. */
>   line = lnext(line);
>   if (!line)
>   goto hba_syntax;
>   parse_hba_auth(line, &port->auth_method, port->auth_arg, error_p);
>   if (*error_p)
>   goto hba_syntax;
> --- 417,433 ----
>   goto hba_syntax;
>   db = lfirst(line);
>
> ! /* Get the user. */
> ! line = lnext(line);
> ! if (!line)
> ! goto hba_syntax;
> ! user = lfirst(line);
> !
>   line = lnext(line);
>   if (!line)
>   goto hba_syntax;
> +
> + /* Read the rest of the line. */
>   parse_hba_auth(line, &port->auth_method, port->auth_arg, error_p);
>   if (*error_p)
>   goto hba_syntax;
> ***************
> *** 308,322 ****
>   port->auth_method == uaKrb5)
>   goto hba_syntax;
>
> ! /*
> ! * If this record doesn't match the parameters of the connection
> ! * attempt, ignore it.
> ! */
> ! if ((strcmp(db, port->database) != 0 &&
> ! strcmp(db, "all") != 0 &&
> ! (strcmp(db, "sameuser") != 0 ||
> !   strcmp(port->database, port->user) != 0)) ||
> ! port->raddr.sa.sa_family != AF_UNIX)
>   return;
>   }
>   else if (strcmp(token, "host") == 0 || strcmp(token, "hostssl") ==
0)
> --- 439,445 ----
>   port->auth_method == uaKrb5)
>   goto hba_syntax;
>
> ! if (port->raddr.sa.sa_family != AF_UNIX)
>   return;
>   }
>   else if (strcmp(token, "host") == 0 || strcmp(token, "hostssl") ==
0)
> ***************
> *** 347,352 ****
> --- 470,481 ----
>   goto hba_syntax;
>   db = lfirst(line);
>
> + /* Get the user. */
> + line = lnext(line);
> + if (!line)
> + goto hba_syntax;
> + user = lfirst(line);
> +
>   /* Read the IP address field. */
>   line = lnext(line);
>   if (!line)
> ***************
> *** 371,390 ****
>   if (*error_p)
>   goto hba_syntax;
>
> ! /*
> ! * If this record doesn't match the parameters of the connection
> ! * attempt, ignore it.
> ! */
> ! if ((strcmp(db, port->database) != 0 &&
> ! strcmp(db, "all") != 0 &&
> ! (strcmp(db, "sameuser") != 0 ||
> !   strcmp(port->database, port->user) != 0)) ||
> ! port->raddr.sa.sa_family != AF_INET ||
>   ((file_ip_addr.s_addr ^ port->raddr.in.sin_addr.s_addr) &
mask.s_addr) != 0)
>   return;
>   }
>   else
>   goto hba_syntax;
>
>   /* Success */
>   *found_p = true;
> --- 500,517 ----
>   if (*error_p)
>   goto hba_syntax;
>
> ! /* Must meet network restrictions */
> ! if (port->raddr.sa.sa_family != AF_INET ||
>   ((file_ip_addr.s_addr ^ port->raddr.in.sin_addr.s_addr) &
mask.s_addr) != 0)
>   return;
>   }
>   else
>   goto hba_syntax;
> +
> + if (!check_db(port->database, port->user, db))
> + return;
> + if (!check_user(port->user, user))
> + return;
>
>   /* Success */
>   *found_p = true;
> Index: src/backend/libpq/pg_hba.conf.sample
> ===================================================================
> RCS file: /cvsroot/pgsql/src/backend/libpq/pg_hba.conf.sample,v
> retrieving revision 1.35
> diff -c -r1.35 pg_hba.conf.sample
> *** src/backend/libpq/pg_hba.conf.sample 8 Mar 2002 20:36:58 -0000
1.35
> --- src/backend/libpq/pg_hba.conf.sample 19 Mar 2002 05:51:58 -0000
> ***************
> *** 42,63 ****
>   #
>   # Format:
>   #
> ! #   host  DBNAME  IP_ADDRESS  ADDRESS_MASK  AUTH_TYPE
[AUTH_ARGUMENT]
>   #
> ! # DBNAME can be:
> ! # o a database name
> ! # o "all", which means the record matches all databases
> ! #   o "sameuser", which means users can only access databases
whose name
> ! #     is the same as their username
>   #
> ! # IP_ADDRESS and ADDRESS_MASK are standard dotted decimal IP
address and
>   # mask values. IP addresses can only be specified numerically, not
as
>   # domain or host names.
>   #
>   # Do not prevent the superuser from accessing the template1
database.
>   # Various utility commands need access to template1.
>   #
> ! # AUTH_TYPE and AUTH_ARGUMENT are described below.
>   #
>   #
>   # hostssl
> --- 42,74 ----
>   #
>   # Format:
>   #
> ! #   host       DATABASE    USER      IP_ADDRESS    MASK
AUTH_TYPE
>   #
> ! # DATABASE can be:
> ! # o a database name
> ! # o "sameuser", which means users can only access databases with
the
> ! #   same name as their user name
> ! # o "all", which matches all databases
> ! # o a list of database names, separated by commas
> ! # o a file name containing database names, starting with '@'
> ! #
> ! # USER can be:
> ! # o a user name
> ! # o "all", which matches all users
> ! # o a list of user names, separated by commas
> ! # o a file name containing user names, starting with '@'
>   #
> ! # Files read using '@' can contain comma-separated database/user
names,
> ! # or one name per line.  The files can also contain comments using
'#'.
> ! #
> ! # IP_ADDRESS and MASK are standard dotted decimal IP address and
>   # mask values. IP addresses can only be specified numerically, not
as
>   # domain or host names.
>   #
>   # Do not prevent the superuser from accessing the template1
database.
>   # Various utility commands need access to template1.
>   #
> ! # AUTH_TYPE is described below.
>   #
>   #
>   # hostssl
> ***************
> *** 65,74 ****
>   #
>   # The format of this record is identical to "host".
>   #
> ! #
> ! #
> ! # It specifies hosts that required connection via secure SSL.
"host"
> ! # records allow SSL connections too, but "hostssl" only allows
SSL-secured
>   # connections.
>   #
>   # This keyword is only available if the server was compiled with
SSL
> --- 76,83 ----
>   #
>   # The format of this record is identical to "host".
>   #
> ! # It specifies hosts that require connection via secure SSL.
"host"
> ! # allows SSL connections too, but "hostssl" requires SSL-secured
>   # connections.
>   #
>   # This keyword is only available if the server was compiled with
SSL
> ***************
> *** 82,91 ****
>   # connections. Without this record, UNIX-socket connections are
disallowed
>   #
>   # Format:
> ! #   local  DBNAME  AUTH_TYPE  [AUTH_ARGUMENT]
>   #
>   # This format is identical to the "host" record type except there
are no
> ! # IP_ADDRESS and ADDRESS_MASK fields.
>   #
>   #
>   #
> --- 91,100 ----
>   # connections. Without this record, UNIX-socket connections are
disallowed
>   #
>   # Format:
> ! #   local      DATABASE    USER      AUTH_TYPE
>   #
>   # This format is identical to the "host" record type except there
are no
> ! # IP_ADDRESS and MASK fields.
>   #
>   #
>   #
> ***************
> *** 96,152 ****
>   # has an AUTH_TYPE.
>   #
>   #   trust:
> ! # No authentication is done. Any valid username is accepted,
>   # including the PostgreSQL superuser. This option should
>   # be used only for hosts where all users are trusted.
>   #
> - #   password:
> - # Authentication is done by matching a password supplied
> - # in clear by the host. If no AUTH_ARGUMENT is used, the
> - # password is compared with the user's entry in the
> - # pg_shadow table.
> - #
> - # If AUTH_ARGUMENT is specified, the username is looked up
> - # in that file in the $PGDATA directory. If the username
> - # is found but there is no password, the password is looked
> - # up in pg_shadow. If a password exists in the file, it is
> - # used instead. These secondary files allow fine-grained
> - # control over who can access which databases and whether
> - # a non-default password is required. The same file can be
> - # used in multiple records for easier administration.
> - # Password files can be maintained with the pg_passwd(1)
> - # utility. Remember, these passwords override pg_shadow
> - # passwords.  Also, such passwords are passed over the network
> - # in cleartext, meaning this should not be used on untrusted
> - # networks.
> - #
>   #   md5:
> ! #   Same as "password", except the password is encrypted over the
> ! #   network. This method is preferable to "password" and "crypt"
> ! #   except for pre-7.2 clients that don't support it. NOTE: md5
can
> ! #   use usernames stored in secondary password files but ignores
> ! #   passwords stored there. The pg_shadow password will always be
> ! #   used.
>   #
>   #   crypt:
> ! #   Same as "md5", but uses crypt for pre-7.2 clients.  You can
> ! # not store encrypted passwords in pg_shadow if you use this
> ! # method.
>   #
>   #   ident:
>   # For TCP/IP connections, authentication is done by contacting the
>   # ident server on the client host. This is only as secure as the
> ! # client machine. On machines that support unix-domain socket
> ! # credentials (currently Linux, FreeBSD, NetBSD, and BSD/OS), this
> ! # method also works for "local" connections.
> ! #
> ! # AUTH_ARGUMENT is required. It determines how to map remote user
> ! # names to PostgreSQL user names. If you use "sameuser", the user
> ! # names are assumed to be the identical. If not, AUTH_ARGUMENT is
> ! # assumed to be a map name found in the $PGDATA/pg_ident.conf
> ! # file. The connection is accepted if that file contains an entry
> ! # for this map name with the ident-supplied username and the
> ! # requested PostgreSQL username.
>   #
>   #   krb4:
>   # Kerberos V4 authentication is used.  Allowed only for
> --- 105,142 ----
>   # has an AUTH_TYPE.
>   #
>   #   trust:
> ! # No authentication is done. Any valid user name is accepted,
>   # including the PostgreSQL superuser. This option should
>   # be used only for hosts where all users are trusted.
>   #
>   #   md5:
> ! #   Requires the client to supply an MD5 encrypted password for
> ! # authentication.  This is the only method that allows encrypted
> ! # passwords to be stored in pg_shadow.
>   #
>   #   crypt:
> ! #   Same as "md5", but uses crypt for pre-7.2 clients.
>   #
> + #   password:
> + # Same as "md5", but the password is sent in cleartext over
> + # the network.  This should not be used on untrusted
> + # networks.
> + #
>   #   ident:
>   # For TCP/IP connections, authentication is done by contacting the
>   # ident server on the client host. This is only as secure as the
> ! # client machine. You must specify the map name after the 'ident'
> ! # keyword. It determines how to map remote user names to
> ! # PostgreSQL user names. If you use "sameuser", the user names are
> ! # assumed to be identical. If not, the map name is looked up
> ! # in the $PGDATA/pg_ident.conf file. The connection is accepted if
> ! # that file contains an entry for this map name with the
> ! # ident-supplied username and the requested PostgreSQL username.
> ! #
> ! # On machines that support unix-domain socket credentials
> ! # (currently Linux, FreeBSD, NetBSD, and BSD/OS), ident allows
> ! # reliable authentication of 'local' connections without ident
> ! # running on the local machine.
>   #
>   #   krb4:
>   # Kerberos V4 authentication is used.  Allowed only for
> ***************
> *** 157,166 ****
>   # TCP/IP connections, not for local UNIX-domain sockets.
>   #
>   #   pam:
> ! # Authentication is passed off to PAM (PostgreSQL must be
> ! # configured --with-pam), using the default service name
> ! # "postgresql" - you can specify your own service name by
> ! # setting AUTH_ARGUMENT to the desired service name.
>   #
>   #   reject:
>   # Reject the connection. This is used to reject certain hosts
> --- 147,156 ----
>   # TCP/IP connections, not for local UNIX-domain sockets.
>   #
>   #   pam:
> ! # Authentication is done by PAM using the default service name
> ! # "postgresql". You can specify your own service name by adding
> ! # the service name after the 'pam' keyword. To use this option,
> ! # PostgreSQL must be configured --with-pam.
>   #
>   #   reject:
>   # Reject the connection. This is used to reject certain hosts
> ***************
> *** 177,236 ****
>   # Allow any user on the local system to connect to any database
under any
>   # username using Unix-domain sockets (the default for local
connections):
>   #
> ! # TYPE       DATABASE    IP_ADDRESS    MASK
AUTH_TYPE  AUTH_ARGUMENT
> ! # local      all                                          trust
>   #
>   # The same using local loopback TCP/IP connections:
>   #
> ! # TYPE       DATABASE    IP_ADDRESS    MASK
AUTH_TYPE  AUTH_ARGUMENT
> ! # host       all         127.0.0.1     255.255.255.255    trust
>   #
>   # Allow any user from any host with IP address 192.168.93.x to
>   # connect to database "template1" as the same username that ident
reports
>   # for the connection (typically his Unix username):
>   #
> ! # TYPE       DATABASE    IP_ADDRESS    MASK
AUTH_TYPE  AUTH_ARGUMENT
> ! # host       template1   192.168.93.0  255.255.255.0      ident
sameuser
>   #
>   # Allow a user from host 192.168.12.10 to connect to database
"template1"
> ! # if the user's password in pg_shadow is correctly supplied:
>   #
> ! # TYPE       DATABASE    IP_ADDRESS    MASK
AUTH_TYPE  AUTH_ARGUMENT
> ! # host       template1   192.168.12.10 255.255.255.255    md5
>   #
>   # In the absence of preceding "host" lines, these two lines will
reject
>   # all connection from 192.168.54.1 (since that entry will be
matched
>   # first), but allow Kerberos V5 connections from anywhere else on
the
>   # Internet. The zero mask means that no bits of the host IP
address are
> ! # considered, so it matches any host:
>   #
>   #
> ! # TYPE       DATABASE    IP_ADDRESS    MASK
AUTH_TYPE  AUTH_ARGUMENT
> ! # host       all        192.168.54.1   255.255.255.255    reject
> ! # host       all        0.0.0.0        0.0.0.0            krb5
>   #
>   # Allow users from 192.168.x.x hosts to connect to any database if
they
>   # pass the ident check. For example, if ident says the user is
"james" and
>   # he requests to connect as PostgreSQL user "guest", the
connection is
>   # allowed if there is an entry in $PGDATA/pg_ident.conf with map
name
>   # "phoenix" that says "james" is allowed to connect as "guest":
>   #
> ! # TYPE       DATABASE    IP_ADDRESS    MASK
AUTH_TYPE  AUTH_ARGUMENT
> ! # host       all        192.168.0.0    255.255.0.0        ident
phoenix
>   #
>   # If these are the only two lines for local connections, they will
allow
>   # local users to connect only to their own databases (databases
with the
>   # same name as their user name) except for administrators who may
connect
>   # to all databases. The file $PGDATA/admins lists the user names
who are
>   # permitted to connect to all databases. Passwords are required in
all
> ! # cases. (If you prefer to use ident authorization, an ident map
can
> ! # serve a parallel purpose to the password list file used here.)
>   #
> ! # TYPE       DATABASE    IP_ADDRESS    MASK
AUTH_TYPE  AUTH_ARGUMENT
> ! # local      sameuser                                     md5
> ! # local      all                                          md5
admins
>   #
> - # See $PGDATA/pg_ident.conf for more information on Ident maps.
>   #
>   #
>   #
> --- 167,225 ----
>   # Allow any user on the local system to connect to any database
under any
>   # username using Unix-domain sockets (the default for local
connections):
>   #
> ! # TYPE       DATABASE    USER       IP_ADDRESS    MASK
AUTH_TYPE
> ! # local      all         all
trust
>   #
>   # The same using local loopback TCP/IP connections:
>   #
> ! # TYPE      DATABASE     USER    IP_ADDRESS    MASK
AUTH_TYPE
> ! # host      all          all     127.0.0.1     255.255.255.255
trust
>   #
>   # Allow any user from any host with IP address 192.168.93.x to
>   # connect to database "template1" as the same username that ident
reports
>   # for the connection (typically his Unix username):
>   #
> ! # TYPE       DATABASE    USER    IP_ADDRESS    MASK
AUTH_TYPE
> ! # host       template1   all     192.168.93.0  255.255.255.0
ident sameuser
>   #
>   # Allow a user from host 192.168.12.10 to connect to database
"template1"
> ! # if the user's password is correctly supplied:
>   #
> ! # TYPE       DATABASE    USER     IP_ADDRESS    MASK
AUTH_TYPE
> ! # host       template1   all      192.168.12.10 255.255.255.255
md5
>   #
>   # In the absence of preceding "host" lines, these two lines will
reject
>   # all connection from 192.168.54.1 (since that entry will be
matched
>   # first), but allow Kerberos V5 connections from anywhere else on
the
>   # Internet. The zero mask means that no bits of the host IP
address are
> ! # considered so it matches any host:
>   #
>   #
> ! # TYPE       DATABASE    USER     IP_ADDRESS    MASK
AUTH_TYPE
> ! # host       all         all      192.168.54.1  255.255.255.255
reject
> ! # host       all         all      0.0.0.0       0.0.0.0
krb5
>   #
>   # Allow users from 192.168.x.x hosts to connect to any database if
they
>   # pass the ident check. For example, if ident says the user is
"james" and
>   # he requests to connect as PostgreSQL user "guest", the
connection is
>   # allowed if there is an entry in $PGDATA/pg_ident.conf with map
name
>   # "phoenix" that says "james" is allowed to connect as "guest":
> + # See $PGDATA/pg_ident.conf for more information on Ident maps.
>   #
> ! # TYPE       DATABASE    USER     IP_ADDRESS    MASK
AUTH_TYPE
> ! # host       all         all      192.168.0.0    255.255.0.0
ident phoenix
>   #
>   # If these are the only two lines for local connections, they will
allow
>   # local users to connect only to their own databases (databases
with the
>   # same name as their user name) except for administrators who may
connect
>   # to all databases. The file $PGDATA/admins lists the user names
who are
>   # permitted to connect to all databases. Passwords are required in
all
> ! # cases.
>   #
> ! # TYPE       DATABASE    USER      IP_ADDRESS    MASK
AUTH_TYPE
> ! # local      sameuser    all
md5
> ! # local      all         @admins
md5
>   #
>   #
>   #
>   #
> ***************
> *** 250,256 ****
>   # configuration is probably too liberal for you. Change it to use
>   # something other than "trust" authentication.
>   #
> ! # TYPE     DATABASE    IP_ADDRESS    MASK               AUTH_TYPE
AUTH_ARGUMENT
>
> ! local      all                                          trust
> ! host       all         127.0.0.1     255.255.255.255    trust
> --- 239,245 ----
>   # configuration is probably too liberal for you. Change it to use
>   # something other than "trust" authentication.
>   #
> ! # TYPE       DATABASE      USER      IP_ADDRESS    MASK
AUTH_TYPE
>
> ! local        all           all
trust
> ! host         all           all       127.0.0.1     255.255.255.255
trust
> Index: src/bin/Makefile
> ===================================================================
> RCS file: /cvsroot/pgsql/src/bin/Makefile,v
> retrieving revision 1.34
> diff -c -r1.34 Makefile
> *** src/bin/Makefile 18 Feb 2001 18:33:59 -0000 1.34
> --- src/bin/Makefile 19 Mar 2002 05:51:59 -0000
> ***************
> *** 14,20 ****
>   include $(top_builddir)/src/Makefile.global
>
>   DIRS := initdb initlocation ipcclean pg_ctl pg_dump pg_id \
> ! pg_passwd psql scripts pg_config
>
>   ifdef MULTIBYTE
>   DIRS += pg_encoding
> --- 14,20 ----
>   include $(top_builddir)/src/Makefile.global
>
>   DIRS := initdb initlocation ipcclean pg_ctl pg_dump pg_id \
> ! psql scripts pg_config
>
>   ifdef MULTIBYTE
>   DIRS += pg_encoding
>


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


>
> ---------------------------(end of
broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>     (send "unregister YourEmailAddressHere" to
majordomo@postgresql.org)
>


Re: Adding usernames to pg_hba.conf

From
Bruce Momjian
Date:
Rod Taylor wrote:
> I see.. @ denotes a list of users in a file.
>
> Wouldn't it make more sense to simply allow groups to be specified
> (groups from pg_group)?
>
> In my case any group I would specify for connection purposes I've
> already created for permission purposes.

Yes, groups would be a very logical thing to have in pg_hba.conf.
Unfortunately, we don't have pg_group information available to the
postmaster.

The only thing I can think of is to dump the groups out as files and
enable those in pg_hba.conf, perhaps just like we allow @file includes.
I would probably use % for group names and dump them in data/global.

How does that sound?

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Re: Adding usernames to pg_hba.conf

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> The only thing I can think of is to dump the groups out as files and
> enable those in pg_hba.conf, perhaps just like we allow @file includes.
> I would probably use % for group names and dump them in data/global.

> How does that sound?

You mean as files named after groups?  That would add a large pile of
synchronization and security issues.  (If you don't think there's a
security issue, consider a group named "../pg_hba.conf".)

My advice is not to do it.

            regards, tom lane

Re: Adding usernames to pg_hba.conf

From
Peter Eisentraut
Date:
Bruce Momjian writes:

>     o  removes secondary password file support
>     o  adds a user name column just after the database column
>     o  allows a comma separated list of usernames or databases
>     o  allows another file to contain a list of username/databases
>        by preceding the pg_hba.conf entry with '@'
>     o  allow single or double-quoting of user/database names

How do you plan to get around the compatibility issues?

--
Peter Eisentraut   peter_e@gmx.net


Re: Adding usernames to pg_hba.conf

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > The only thing I can think of is to dump the groups out as files and
> > enable those in pg_hba.conf, perhaps just like we allow @file includes.
> > I would probably use % for group names and dump them in data/global.
>
> > How does that sound?
>
> You mean as files named after groups?  That would add a large pile of
> synchronization and security issues.  (If you don't think there's a
> security issue, consider a group named "../pg_hba.conf".)
>
> My advice is not to do it.

I have been thinking about it and I think one file in data/global/
similar to pg_pwd will work.  It will contain "groupname<tab>username"
and can be read in with a limited amount of code and dumped out like we
do pg_pwd.  It will basically expand to the comma-separated list of
users in the current code.

We can mark group names with "+", e.g. +staff.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Re: Adding usernames to pg_hba.conf

From
Bruce Momjian
Date:
Peter Eisentraut wrote:
> Bruce Momjian writes:
>
> >     o  removes secondary password file support
> >     o  adds a user name column just after the database column
> >     o  allows a comma separated list of usernames or databases
> >     o  allows another file to contain a list of username/databases
> >        by preceding the pg_hba.conf entry with '@'
> >     o  allow single or double-quoting of user/database names
>
> How do you plan to get around the compatibility issues?

Good question.  We could just announce in the 7.3 release notes that
people have to add a new column after DATABASE for user, and default it
to "all".  We could move the USER column to the end, which would present
less of a compatibility issue, but does cause problems with the optional
auth_argument.  I can write a script to convert old pg_hba.conf files.
We could also throw a more helpful error if old files are used.  Do you
have a suggestion?

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Re: Adding usernames to pg_hba.conf

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> I have been thinking about it and I think one file in data/global/
> similar to pg_pwd will work.

Yeah, if you model it on the pg_shadow trigger then at least it's no worse
than it is now ;-).  Note the checks that exist in the pg_shadow trigger
to require usernames not to contain any characters that would break the
file formatting; this will have to be done for groupnames now too.

Also note that (if you plan to write user names and not just user IDs)
an update of pg_shadow will need to force rewrite of the group file not
only the shadow file.

Thinking about that, I wonder why not stick to just one file: extend the
content of pg_pwd to include group membership info, and rewrite it when
either pg_shadow or pg_group changes.

            regards, tom lane

Re: Adding usernames to pg_hba.conf

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > I have been thinking about it and I think one file in data/global/
> > similar to pg_pwd will work.
>
> Yeah, if you model it on the pg_shadow trigger then at least it's no worse
> than it is now ;-).  Note the checks that exist in the pg_shadow trigger
> to require usernames not to contain any characters that would break the
> file formatting; this will have to be done for groupnames now too.

Yes, got it.

> Also note that (if you plan to write user names and not just user IDs)
> an update of pg_shadow will need to force rewrite of the group file not
> only the shadow file.

Good point.

> Thinking about that, I wonder why not stick to just one file: extend the
> content of pg_pwd to include group membership info, and rewrite it when
> either pg_shadow or pg_group changes.

Well, pg_pwd is really there for passwords, and hba.c doesn't touch it.
It only gets read as part of actual authentication, while the group file
is used only in hba.c to load the connection patterns.  Seems like
mixing them would cause more confusion than it is worth.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026