Commit 98723810 authored by Magnus Hagander's avatar Magnus Hagander

Parse pg_hba.conf in postmaster, instead of once in each backend for

each connection. This makes it possible to catch errors in the pg_hba
file when it's being reloaded, instead of silently reloading a broken
file and failing only when a user tries to connect.

This patch also makes the "sameuser" argument to ident authentication
optional.
parent b850cf61
<!-- $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.106 2008/01/05 13:17:00 petere Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.107 2008/09/15 12:32:56 mha Exp $ -->
<chapter id="client-authentication">
<title>Client Authentication</title>
......@@ -509,7 +509,7 @@ host all all 127.0.0.1 255.255.255.255 trust
# the connection (typically the Unix user name).
#
# TYPE DATABASE USER CIDR-ADDRESS METHOD
host postgres all 192.168.93.0/24 ident sameuser
host postgres all 192.168.93.0/24 ident
# Allow a user from host 192.168.12.10 to connect to database
# "postgres" if the user's password is correctly supplied.
......@@ -839,8 +839,8 @@ local db1,db2,@demodbs all md5
<para>
The ident authentication method works by obtaining the client's
operating system user name, then determining the allowed database
user names using a map file that lists the permitted
operating system user name, then optionally determining the allowed
database user names using a map file that lists the permitted
corresponding pairs of names. The determination of the client's
user name is the security-critical point, and it works differently
depending on the connection type.
......@@ -928,15 +928,13 @@ local db1,db2,@demodbs all md5
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</> key word 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.
file. If an ident map is not specified, the database user will be
checked with the same name as the operating system user. Other maps
must be created manually.
</para>
<para>
Ident maps other than <literal>sameuser</literal> are defined in the
ident map file, which by default is named
Ident maps are defined in the ident map file, which by default is named
<filename>pg_ident.conf</><indexterm><primary>pg_ident.conf</primary></indexterm>
and is stored in the
cluster's data directory. (It is possible to place the map file
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.167 2008/08/01 11:41:12 mha Exp $
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.168 2008/09/15 12:32:56 mha Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -211,7 +211,7 @@ auth_failed(Port *port, int status)
if (status == STATUS_EOF)
proc_exit(0);
switch (port->auth_method)
switch (port->hba->auth_method)
{
case uaReject:
errstr = gettext_noop("authentication failed for user \"%s\": host rejected");
......@@ -279,7 +279,7 @@ ClientAuthentication(Port *port)
errmsg("missing or erroneous pg_hba.conf file"),
errhint("See server log for details.")));
switch (port->auth_method)
switch (port->hba->auth_method)
{
case uaReject:
......@@ -1761,7 +1761,7 @@ ident_unix(int sock, char *ident_user)
/*
* Determine the username of the initiator of the connection described
* by "port". Then look in the usermap file under the usermap
* port->auth_arg and see if that user is equivalent to Postgres user
* port->hba->usermap and see if that user is equivalent to Postgres user
* port->user.
*
* Return STATUS_OK if yes, STATUS_ERROR if no match (or couldn't get info).
......@@ -1799,7 +1799,7 @@ authident(hbaPort *port)
(errmsg("Ident protocol identifies remote user as \"%s\"",
ident_user)));
if (check_ident_usermap(port->auth_arg, port->user_name, ident_user))
if (check_ident_usermap(port->hba->usermap, port->user_name, ident_user))
return STATUS_OK;
else
return STATUS_ERROR;
......@@ -1913,8 +1913,8 @@ CheckPAMAuth(Port *port, char *user, char *password)
* not allocated */
/* Optionally, one can set the service name in pg_hba.conf */
if (port->auth_arg && port->auth_arg[0] != '\0')
retval = pam_start(port->auth_arg, "pgsql@",
if (port->hba->auth_arg && port->hba->auth_arg[0] != '\0')
retval = pam_start(port->hba->auth_arg, "pgsql@",
&pam_passw_conv, &pamh);
else
retval = pam_start(PGSQL_PAM_SERVICE, "pgsql@",
......@@ -2011,7 +2011,7 @@ CheckLDAPAuth(Port *port)
int ldapport = LDAP_PORT;
char fulluser[NAMEDATALEN + 256 + 1];
if (!port->auth_arg || port->auth_arg[0] == '\0')
if (!port->hba->auth_arg || port->hba->auth_arg[0] == '\0')
{
ereport(LOG,
(errmsg("LDAP configuration URL not specified")));
......@@ -2035,13 +2035,13 @@ CheckLDAPAuth(Port *port)
suffix[0] = '\0';
/* ldap, including port number */
r = sscanf(port->auth_arg,
r = sscanf(port->hba->auth_arg,
"ldap://%127[^:]:%d/%127[^;];%127[^;];%127[^\n]",
server, &ldapport, basedn, prefix, suffix);
if (r < 3)
{
/* ldaps, including port number */
r = sscanf(port->auth_arg,
r = sscanf(port->hba->auth_arg,
"ldaps://%127[^:]:%d/%127[^;];%127[^;];%127[^\n]",
server, &ldapport, basedn, prefix, suffix);
if (r >= 3)
......@@ -2050,14 +2050,14 @@ CheckLDAPAuth(Port *port)
if (r < 3)
{
/* ldap, no port number */
r = sscanf(port->auth_arg,
r = sscanf(port->hba->auth_arg,
"ldap://%127[^/]/%127[^;];%127[^;];%127[^\n]",
server, basedn, prefix, suffix);
}
if (r < 2)
{
/* ldaps, no port number */
r = sscanf(port->auth_arg,
r = sscanf(port->hba->auth_arg,
"ldaps://%127[^/]/%127[^;];%127[^;];%127[^\n]",
server, basedn, prefix, suffix);
if (r >= 2)
......@@ -2067,7 +2067,7 @@ CheckLDAPAuth(Port *port)
{
ereport(LOG,
(errmsg("invalid LDAP URL: \"%s\"",
port->auth_arg)));
port->hba->auth_arg)));
return STATUS_ERROR;
}
......
......@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/libpq/crypt.c,v 1.74 2008/01/01 19:45:49 momjian Exp $
* $PostgreSQL: pgsql/src/backend/libpq/crypt.c,v 1.75 2008/09/15 12:32:56 mha Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -54,7 +54,7 @@ md5_crypt_verify(const Port *port, const char *role, char *client_pass)
return STATUS_ERROR;
/* We can't do crypt with MD5 passwords */
if (isMD5(shadow_pass) && port->auth_method == uaCrypt)
if (isMD5(shadow_pass) && port->hba->auth_method == uaCrypt)
{
ereport(LOG,
(errmsg("cannot use authentication method \"crypt\" because password is MD5-encrypted")));
......@@ -65,7 +65,7 @@ md5_crypt_verify(const Port *port, const char *role, char *client_pass)
* Compare with the encrypted or plain password depending on the
* authentication method being used for this connection.
*/
switch (port->auth_method)
switch (port->hba->auth_method)
{
case uaMD5:
crypt_pwd = palloc(MD5_PASSWD_LEN + 1);
......@@ -155,7 +155,7 @@ md5_crypt_verify(const Port *port, const char *role, char *client_pass)
}
}
if (port->auth_method == uaMD5)
if (port->hba->auth_method == uaMD5)
pfree(crypt_pwd);
if (crypt_client_pass != client_pass)
pfree(crypt_client_pass);
......
This diff is collapsed.
......@@ -30,7 +30,6 @@
#
# No map names are defined in the default configuration. If all ident
# user names and PostgreSQL user names are the same, you don't need
# this file. Instead, use the special map name "sameuser" in
# pg_hba.conf.
# this file.
# MAPNAME IDENT-USERNAME PG-USERNAME
......@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.562 2008/08/25 15:11:01 mha Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.563 2008/09/15 12:32:57 mha Exp $
*
* NOTES
*
......@@ -888,7 +888,15 @@ PostmasterMain(int argc, char *argv[])
/*
* Load configuration files for client authentication.
*/
load_hba();
if (!load_hba())
{
/*
* It makes no sense continue if we fail to load the HBA file, since
* there is no way to connect to the database in this case.
*/
ereport(FATAL,
(errmsg("could not load pg_hba.conf")));
}
load_ident();
/*
......@@ -1927,7 +1935,10 @@ SIGHUP_handler(SIGNAL_ARGS)
signal_child(PgStatPID, SIGHUP);
/* Reload authentication config files too */
load_hba();
if (!load_hba())
ereport(WARNING,
(errmsg("pg_hba.conf not reloaded")));
load_ident();
#ifdef EXEC_BACKEND
......@@ -3081,7 +3092,15 @@ BackendInitialize(Port *port)
ALLOCSET_DEFAULT_MAXSIZE);
MemoryContextSwitchTo(PostmasterContext);
load_hba();
if (!load_hba())
{
/*
* It makes no sense continue if we fail to load the HBA file, since
* there is no way to connect to the database in this case.
*/
ereport(FATAL,
(errmsg("could not load pg_hba.conf")));
}
load_ident();
load_role();
#endif
......
......@@ -4,7 +4,7 @@
* Interface to hba.c
*
*
* $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.48 2008/08/01 09:09:48 mha Exp $
* $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.49 2008/09/15 12:32:57 mha Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -12,6 +12,7 @@
#define HBA_H
#include "nodes/pg_list.h"
#include "libpq/pqcomm.h"
typedef enum UserAuth
......@@ -33,10 +34,31 @@ typedef enum UserAuth
#endif
} UserAuth;
typedef enum ConnType
{
ctLocal,
ctHost,
ctHostSSL,
ctHostNoSSL
} ConnType;
typedef struct
{
int linenumber;
ConnType conntype;
char *database;
char *role;
struct sockaddr_storage addr;
struct sockaddr_storage mask;
UserAuth auth_method;
char *usermap;
char *auth_arg;
} HbaLine;
typedef struct Port hbaPort;
extern List **get_role_line(const char *role);
extern void load_hba(void);
extern bool load_hba(void);
extern void load_ident(void);
extern void load_role(void);
extern int hba_getauthmethod(hbaPort *port);
......
......@@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/libpq/libpq-be.h,v 1.66 2008/04/26 22:47:40 tgl Exp $
* $PostgreSQL: pgsql/src/include/libpq/libpq-be.h,v 1.67 2008/09/15 12:32:57 mha Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -121,8 +121,7 @@ typedef struct Port
/*
* Information that needs to be held during the authentication cycle.
*/
UserAuth auth_method;
char *auth_arg;
HbaLine *hba;
char md5Salt[4]; /* Password salt */
char cryptSalt[2]; /* Password salt */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment