Re: Adding usernames to pg_hba.conf - Mailing list pgsql-patches
From | Bruce Momjian |
---|---|
Subject | Re: Adding usernames to pg_hba.conf |
Date | |
Msg-id | 200203190606.g2J66eH16215@candle.pha.pa.us Whole thread Raw |
In response to | Adding usernames to pg_hba.conf (Bruce Momjian <pgman@candle.pha.pa.us>) |
List | pgsql-patches |
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
pgsql-patches by date: