mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-01 07:12:33 +02:00
Fix pg_pwd caching mechanism, which was broken by changes to fork
postmaster children before client auth step. Postmaster now rereads pg_pwd on receipt of SIGHUP, the same way that pg_hba.conf is handled. No cycles need be expended to validate password cache validity during connection startup.
This commit is contained in:
parent
6babf6eab7
commit
8a069abd18
@ -1,4 +1,4 @@
|
|||||||
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/client-auth.sgml,v 1.22 2001/10/04 22:27:18 petere Exp $ -->
|
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/client-auth.sgml,v 1.23 2001/11/02 18:39:57 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="client-authentication">
|
<chapter id="client-authentication">
|
||||||
<title>Client Authentication</title>
|
<title>Client Authentication</title>
|
||||||
@ -67,6 +67,19 @@
|
|||||||
tabs. Records cannot be continued across lines.
|
tabs. Records cannot be continued across lines.
|
||||||
</para>
|
</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>
|
<para>
|
||||||
A record may have one of the three formats
|
A record may have one of the three formats
|
||||||
<synopsis>
|
<synopsis>
|
||||||
@ -107,7 +120,9 @@ hostssl <replaceable>database</replaceable> <replaceable>IP-address</replaceable
|
|||||||
TCP/IP. To make use of this option the server must be
|
TCP/IP. To make use of this option the server must be
|
||||||
built with SSL support enabled. Furthermore, SSL must be
|
built with SSL support enabled. Furthermore, SSL must be
|
||||||
enabled with the <option>-l</> option or equivalent configuration
|
enabled with the <option>-l</> option or equivalent configuration
|
||||||
setting when the server is started.
|
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>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -131,8 +146,9 @@ hostssl <replaceable>database</replaceable> <replaceable>IP-address</replaceable
|
|||||||
<term><replaceable>IP mask</replaceable></term>
|
<term><replaceable>IP mask</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
These two fields control to which hosts a
|
These two fields specify to which client machines a
|
||||||
<literal>host</literal> record applies, based on their IP
|
<literal>host</literal> or <literal>hostssl</literal>
|
||||||
|
record applies, based on their IP
|
||||||
address. (Of course IP addresses can be spoofed but this
|
address. (Of course IP addresses can be spoofed but this
|
||||||
consideration is beyond the scope of
|
consideration is beyond the scope of
|
||||||
<productname>Postgres</productname>.) The precise logic is that
|
<productname>Postgres</productname>.) The precise logic is that
|
||||||
@ -151,7 +167,8 @@ hostssl <replaceable>database</replaceable> <replaceable>IP-address</replaceable
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Specifies the method that users must use to authenticate themselves
|
Specifies the method that users must use to authenticate themselves
|
||||||
when connecting to that database. The possible choices follow,
|
when connecting under the control of this authentication record.
|
||||||
|
The possible choices are summarized here,
|
||||||
details are in <xref linkend="auth-methods">.
|
details are in <xref linkend="auth-methods">.
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
@ -322,17 +339,27 @@ hostssl <replaceable>database</replaceable> <replaceable>IP-address</replaceable
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
The first record that matches the client IP 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>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <filename>pg_hba.conf</filename> file is loaded only on startup
|
Since the <filename>pg_hba.conf</filename> records are examined
|
||||||
|
sequentially for each connection attempt, 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
|
and when the <application>postmaster</> receives a
|
||||||
<systemitem>SIGHUP</systemitem> signal. If you edit the file on an
|
<systemitem>SIGHUP</systemitem> signal. If you edit the file on an
|
||||||
active system, you will need to signal the <application>postmaster</>
|
active system, you will need to signal the <application>postmaster</>
|
||||||
@ -632,7 +659,7 @@ host all 192.168.0.0 255.255.0.0 ident omicron
|
|||||||
to connect as the database user he is requesting to connect as.
|
to connect as the database user he is requesting to connect as.
|
||||||
This is controlled by the ident map
|
This is controlled by the ident map
|
||||||
argument that follows the <literal>ident</> keyword in the
|
argument that follows the <literal>ident</> keyword in the
|
||||||
<filename>pg_hba.conf</filename> file. The simplest ident map is
|
<filename>pg_hba.conf</filename> file. There is a predefined ident map
|
||||||
<literal>sameuser</literal>, which allows any operating system
|
<literal>sameuser</literal>, which allows any operating system
|
||||||
user to connect as the database user of the same name (if the
|
user to connect as the database user of the same name (if the
|
||||||
latter exists). Other maps must be created manually.
|
latter exists). Other maps must be created manually.
|
||||||
@ -640,7 +667,8 @@ host all 192.168.0.0 255.255.0.0 ident omicron
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
<indexterm><primary>pg_ident.conf</primary></indexterm>
|
<indexterm><primary>pg_ident.conf</primary></indexterm>
|
||||||
Ident maps are held in the file <filename>pg_ident.conf</filename>
|
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:
|
in the data directory, which contains lines of the general form:
|
||||||
<synopsis>
|
<synopsis>
|
||||||
<replaceable>map-name</> <replaceable>ident-username</> <replaceable>database-username</>
|
<replaceable>map-name</> <replaceable>ident-username</> <replaceable>database-username</>
|
||||||
@ -657,6 +685,18 @@ host all 192.168.0.0 255.255.0.0 ident omicron
|
|||||||
versa.
|
versa.
|
||||||
</para>
|
</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 <application>pg_ctl reload</> or <application>kill -HUP</>)
|
||||||
|
to make it re-read the file.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
A <filename>pg_ident.conf</filename> file that could be used in
|
A <filename>pg_ident.conf</filename> file that could be used in
|
||||||
conjunction with the <filename>pg_hba.conf</> file in <xref
|
conjunction with the <filename>pg_hba.conf</> file in <xref
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.91 2001/10/31 20:35:02 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.92 2001/11/02 18:39:57 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<Chapter Id="runtime">
|
<Chapter Id="runtime">
|
||||||
@ -479,8 +479,10 @@ syslog = 2
|
|||||||
<primary>SIGHUP</primary>
|
<primary>SIGHUP</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
The configuration file is reread whenever the postmaster receives
|
The configuration file is reread whenever the postmaster receives
|
||||||
a <systemitem>SIGHUP</> signal. This signal is also propagated to all running
|
a <systemitem>SIGHUP</> signal (which is most easily sent by means
|
||||||
backend processes, so that running sessions get the new default.
|
of <application>pg_ctl reload</>). The postmaster also propagates
|
||||||
|
this signal to all already-running backend processes, so that
|
||||||
|
existing sessions also get the new default.
|
||||||
Alternatively, you can send the signal to only one backend process
|
Alternatively, you can send the signal to only one backend process
|
||||||
directly.
|
directly.
|
||||||
</para>
|
</para>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.87 2001/11/01 18:09:58 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.88 2001/11/02 18:39:57 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -15,6 +15,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
@ -33,14 +34,15 @@
|
|||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
|
||||||
static void CheckPgUserAclNotNull(void);
|
|
||||||
extern bool Password_encryption;
|
extern bool Password_encryption;
|
||||||
|
|
||||||
|
static void CheckPgUserAclNotNull(void);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------
|
/*---------------------------------------------------------------------
|
||||||
* write_password_file / update_pg_pwd
|
* write_password_file / update_pg_pwd
|
||||||
*
|
*
|
||||||
* copy the modified contents of pg_shadow to a file used by the postmaster
|
* copy the modified contents of pg_shadow to a file used by the postmaster
|
||||||
* for user authentication. The file is stored as $PGDATA/pg_pwd.
|
* for user authentication. The file is stored as $PGDATA/global/pg_pwd.
|
||||||
*
|
*
|
||||||
* This function set is both a trigger function for direct updates to pg_shadow
|
* This function set is both a trigger function for direct updates to pg_shadow
|
||||||
* as well as being called directly from create/alter/drop user.
|
* as well as being called directly from create/alter/drop user.
|
||||||
@ -57,7 +59,6 @@ write_password_file(Relation rel)
|
|||||||
*tempname;
|
*tempname;
|
||||||
int bufsize;
|
int bufsize;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int flagfd;
|
|
||||||
mode_t oumask;
|
mode_t oumask;
|
||||||
HeapScanDesc scan;
|
HeapScanDesc scan;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
@ -133,7 +134,7 @@ write_password_file(Relation rel)
|
|||||||
/*
|
/*
|
||||||
* The extra columns we emit here are not really necessary. To remove
|
* The extra columns we emit here are not really necessary. To remove
|
||||||
* them, the parser in backend/libpq/crypt.c would need to be
|
* them, the parser in backend/libpq/crypt.c would need to be
|
||||||
* adjusted. Initdb might also need adjustments.
|
* adjusted.
|
||||||
*/
|
*/
|
||||||
fprintf(fp,
|
fprintf(fp,
|
||||||
"%s"
|
"%s"
|
||||||
@ -168,6 +169,7 @@ write_password_file(Relation rel)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Rename the temp file to its final name, deleting the old pg_pwd.
|
* Rename the temp file to its final name, deleting the old pg_pwd.
|
||||||
|
* We expect that rename(2) is an atomic action.
|
||||||
*/
|
*/
|
||||||
if (rename(tempname, filename))
|
if (rename(tempname, filename))
|
||||||
elog(ERROR, "rename %s to %s: %m", tempname, filename);
|
elog(ERROR, "rename %s to %s: %m", tempname, filename);
|
||||||
@ -176,19 +178,10 @@ write_password_file(Relation rel)
|
|||||||
pfree((void *) filename);
|
pfree((void *) filename);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a flag file the postmaster will detect the next time it
|
* Signal the postmaster to reload its password-file cache.
|
||||||
* tries to authenticate a user. The postmaster will know to reload
|
|
||||||
* the pg_pwd file contents. Note: we used to elog(ERROR) if the file
|
|
||||||
* creation failed, but it's a little silly to abort the transaction
|
|
||||||
* at this point, so let's just make it a NOTICE.
|
|
||||||
*/
|
*/
|
||||||
filename = crypt_getpwdreloadfilename();
|
if (IsUnderPostmaster)
|
||||||
flagfd = BasicOpenFile(filename, O_WRONLY | O_CREAT, 0600);
|
kill(getppid(), SIGHUP);
|
||||||
if (flagfd < 0)
|
|
||||||
elog(NOTICE, "write_password_file: unable to write %s: %m", filename);
|
|
||||||
else
|
|
||||||
close(flagfd);
|
|
||||||
pfree((void *) filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/backend/libpq/crypt.c,v 1.40 2001/11/01 18:10:48 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/libpq/crypt.c,v 1.41 2001/11/02 18:39:57 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -17,6 +17,9 @@
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#ifdef HAVE_CRYPT_H
|
||||||
|
#include <crypt.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libpq/crypt.h"
|
#include "libpq/crypt.h"
|
||||||
#include "libpq/libpq.h"
|
#include "libpq/libpq.h"
|
||||||
@ -24,15 +27,15 @@
|
|||||||
#include "storage/fd.h"
|
#include "storage/fd.h"
|
||||||
#include "utils/nabstime.h"
|
#include "utils/nabstime.h"
|
||||||
|
|
||||||
#ifdef HAVE_CRYPT_H
|
|
||||||
#include <crypt.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char **pwd_cache = NULL;
|
#define CRYPT_PWD_FILE "pg_pwd"
|
||||||
int pwd_cache_count = 0;
|
|
||||||
|
|
||||||
|
static char **pwd_cache = NULL;
|
||||||
|
static int pwd_cache_count = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* crypt_getpwdfilename --- get name of password file
|
* crypt_getpwdfilename --- get full pathname of password file
|
||||||
*
|
*
|
||||||
* Note that result string is palloc'd, and should be freed by the caller.
|
* Note that result string is palloc'd, and should be freed by the caller.
|
||||||
*/
|
*/
|
||||||
@ -50,28 +53,8 @@ crypt_getpwdfilename(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* crypt_getpwdreloadfilename --- get name of password-reload-needed flag file
|
* Open the password file if possible (return NULL if not)
|
||||||
*
|
|
||||||
* Note that result string is palloc'd, and should be freed by the caller.
|
|
||||||
*/
|
*/
|
||||||
char *
|
|
||||||
crypt_getpwdreloadfilename(void)
|
|
||||||
{
|
|
||||||
char *pwdfilename;
|
|
||||||
int bufsize;
|
|
||||||
char *rpfnam;
|
|
||||||
|
|
||||||
pwdfilename = crypt_getpwdfilename();
|
|
||||||
bufsize = strlen(pwdfilename) + strlen(CRYPT_PWD_RELOAD_SUFX) + 1;
|
|
||||||
rpfnam = (char *) palloc(bufsize);
|
|
||||||
snprintf(rpfnam, bufsize, "%s%s", pwdfilename, CRYPT_PWD_RELOAD_SUFX);
|
|
||||||
pfree(pwdfilename);
|
|
||||||
|
|
||||||
return rpfnam;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static FILE *
|
static FILE *
|
||||||
crypt_openpwdfile(void)
|
crypt_openpwdfile(void)
|
||||||
{
|
{
|
||||||
@ -123,58 +106,60 @@ compar_user(const void *user_a, const void *user_b)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*
|
||||||
|
* Load or reload the password-file cache
|
||||||
static void
|
*/
|
||||||
crypt_loadpwdfile(void)
|
void
|
||||||
|
load_password_cache(void)
|
||||||
{
|
{
|
||||||
char *filename;
|
|
||||||
int result;
|
|
||||||
FILE *pwd_file;
|
FILE *pwd_file;
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
|
|
||||||
filename = crypt_getpwdreloadfilename();
|
|
||||||
result = unlink(filename);
|
|
||||||
pfree(filename);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want to delete the flag file before reading the contents of the
|
* If for some reason we fail to open the password file, preserve the
|
||||||
* pg_pwd file. If result == 0 then the unlink of the reload file was
|
* old cache contents; this seems better than dropping the cache if,
|
||||||
* successful. This means that a backend performed a COPY of the
|
* say, we are temporarily out of filetable slots.
|
||||||
* pg_shadow file to pg_pwd. Therefore we must now do a reload.
|
|
||||||
*/
|
*/
|
||||||
if (!pwd_cache || result == 0)
|
if (!(pwd_file = crypt_openpwdfile()))
|
||||||
{
|
return;
|
||||||
/* free the old data only if this is a reload */
|
|
||||||
|
/* free any old data */
|
||||||
if (pwd_cache)
|
if (pwd_cache)
|
||||||
{
|
{
|
||||||
while (pwd_cache_count--)
|
while (--pwd_cache_count >= 0)
|
||||||
free((void *) pwd_cache[pwd_cache_count]);
|
pfree(pwd_cache[pwd_cache_count]);
|
||||||
free((void *) pwd_cache);
|
pfree(pwd_cache);
|
||||||
pwd_cache = NULL;
|
pwd_cache = NULL;
|
||||||
pwd_cache_count = 0;
|
pwd_cache_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pwd_file = crypt_openpwdfile()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Here is where we load the data from pg_pwd.
|
* Read the file and store its lines in current memory context,
|
||||||
|
* which we expect will be PostmasterContext. That context will
|
||||||
|
* live as long as we need the cache to live, ie, until just after
|
||||||
|
* each postmaster child has completed client authentication.
|
||||||
*/
|
*/
|
||||||
while (fgets(buffer, sizeof(buffer), pwd_file) != NULL)
|
while (fgets(buffer, sizeof(buffer), pwd_file) != NULL)
|
||||||
{
|
{
|
||||||
|
int blen;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must remove the return char at the end of the string, as
|
* We must remove the return char at the end of the string, as
|
||||||
* this will affect the correct parsing of the password entry.
|
* this will affect the correct parsing of the password entry.
|
||||||
*/
|
*/
|
||||||
if (buffer[(result = strlen(buffer) - 1)] == '\n')
|
if (buffer[(blen = strlen(buffer) - 1)] == '\n')
|
||||||
buffer[result] = '\0';
|
buffer[blen] = '\0';
|
||||||
|
|
||||||
|
if (pwd_cache == NULL)
|
||||||
pwd_cache = (char **)
|
pwd_cache = (char **)
|
||||||
realloc((void *) pwd_cache,
|
palloc(sizeof(char *) * (pwd_cache_count + 1));
|
||||||
|
else
|
||||||
|
pwd_cache = (char **)
|
||||||
|
repalloc((void *) pwd_cache,
|
||||||
sizeof(char *) * (pwd_cache_count + 1));
|
sizeof(char *) * (pwd_cache_count + 1));
|
||||||
pwd_cache[pwd_cache_count++] = strdup(buffer);
|
pwd_cache[pwd_cache_count++] = pstrdup(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeFile(pwd_file);
|
FreeFile(pwd_file);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -182,48 +167,67 @@ crypt_loadpwdfile(void)
|
|||||||
*/
|
*/
|
||||||
qsort((void *) pwd_cache, pwd_cache_count, sizeof(char *), compar_user);
|
qsort((void *) pwd_cache, pwd_cache_count, sizeof(char *), compar_user);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*
|
||||||
|
* Parse a line of the password file to extract password and valid-until date.
|
||||||
static void
|
*/
|
||||||
|
static bool
|
||||||
crypt_parsepwdentry(char *buffer, char **pwd, char **valdate)
|
crypt_parsepwdentry(char *buffer, char **pwd, char **valdate)
|
||||||
{
|
{
|
||||||
char *parse = buffer;
|
char *parse = buffer;
|
||||||
int count,
|
int count,
|
||||||
i;
|
i;
|
||||||
|
|
||||||
|
*pwd = NULL;
|
||||||
|
*valdate = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* skip to the password field
|
* skip to the password field
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
parse += (strcspn(parse, CRYPT_PWD_FILE_SEPSTR) + 1);
|
{
|
||||||
|
parse += strcspn(parse, CRYPT_PWD_FILE_SEPSTR);
|
||||||
|
if (*parse == '\0')
|
||||||
|
return false;
|
||||||
|
parse++;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* store a copy of user password to return
|
* store a copy of user password to return
|
||||||
*/
|
*/
|
||||||
count = strcspn(parse, CRYPT_PWD_FILE_SEPSTR);
|
count = strcspn(parse, CRYPT_PWD_FILE_SEPSTR);
|
||||||
*pwd = (char *) palloc(count + 1);
|
*pwd = (char *) palloc(count + 1);
|
||||||
strncpy(*pwd, parse, count);
|
memcpy(*pwd, parse, count);
|
||||||
(*pwd)[count] = '\0';
|
(*pwd)[count] = '\0';
|
||||||
parse += (count + 1);
|
parse += count;
|
||||||
|
if (*parse == '\0')
|
||||||
|
{
|
||||||
|
pfree(*pwd);
|
||||||
|
*pwd = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
parse++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* store a copy of the date login becomes invalid
|
* store a copy of the date login becomes invalid
|
||||||
*/
|
*/
|
||||||
count = strcspn(parse, CRYPT_PWD_FILE_SEPSTR);
|
count = strcspn(parse, CRYPT_PWD_FILE_SEPSTR);
|
||||||
*valdate = (char *) palloc(count + 1);
|
*valdate = (char *) palloc(count + 1);
|
||||||
strncpy(*valdate, parse, count);
|
memcpy(*valdate, parse, count);
|
||||||
(*valdate)[count] = '\0';
|
(*valdate)[count] = '\0';
|
||||||
parse += (count + 1);
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*
|
||||||
|
* Lookup a username in the password-file cache,
|
||||||
static int
|
* return his password and valid-until date.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
crypt_getloginfo(const char *user, char **passwd, char **valuntil)
|
crypt_getloginfo(const char *user, char **passwd, char **valuntil)
|
||||||
{
|
{
|
||||||
crypt_loadpwdfile();
|
*passwd = NULL;
|
||||||
|
*valuntil = NULL;
|
||||||
|
|
||||||
if (pwd_cache)
|
if (pwd_cache)
|
||||||
{
|
{
|
||||||
@ -236,14 +240,12 @@ crypt_getloginfo(const char *user, char **passwd, char **valuntil)
|
|||||||
compar_user);
|
compar_user);
|
||||||
if (pwd_entry)
|
if (pwd_entry)
|
||||||
{
|
{
|
||||||
crypt_parsepwdentry(*pwd_entry, passwd, valuntil);
|
if (crypt_parsepwdentry(*pwd_entry, passwd, valuntil))
|
||||||
return STATUS_OK;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*passwd = NULL;
|
return false;
|
||||||
*valuntil = NULL;
|
|
||||||
return STATUS_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
@ -256,7 +258,7 @@ md5_crypt_verify(const Port *port, const char *user, const char *pgpass)
|
|||||||
*crypt_pwd;
|
*crypt_pwd;
|
||||||
int retval = STATUS_ERROR;
|
int retval = STATUS_ERROR;
|
||||||
|
|
||||||
if (crypt_getloginfo(user, &passwd, &valuntil) == STATUS_ERROR)
|
if (!crypt_getloginfo(user, &passwd, &valuntil))
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
|
|
||||||
if (passwd == NULL || *passwd == '\0')
|
if (passwd == NULL || *passwd == '\0')
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.253 2001/10/28 06:25:47 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.254 2001/11/02 18:39:57 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -746,6 +746,12 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
if (pgstat_start() < 0)
|
if (pgstat_start() < 0)
|
||||||
ExitPostmaster(1);
|
ExitPostmaster(1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load cached files for client authentication.
|
||||||
|
*/
|
||||||
|
load_hba_and_ident();
|
||||||
|
load_password_cache();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're ready to rock and roll...
|
* We're ready to rock and roll...
|
||||||
*/
|
*/
|
||||||
@ -852,8 +858,6 @@ ServerLoop(void)
|
|||||||
later;
|
later;
|
||||||
struct timezone tz;
|
struct timezone tz;
|
||||||
|
|
||||||
load_hba_and_ident();
|
|
||||||
|
|
||||||
gettimeofday(&now, &tz);
|
gettimeofday(&now, &tz);
|
||||||
|
|
||||||
nSockets = initMasks(&readmask, &writemask);
|
nSockets = initMasks(&readmask, &writemask);
|
||||||
@ -925,6 +929,7 @@ ServerLoop(void)
|
|||||||
got_SIGHUP = false;
|
got_SIGHUP = false;
|
||||||
ProcessConfigFile(PGC_SIGHUP);
|
ProcessConfigFile(PGC_SIGHUP);
|
||||||
load_hba_and_ident();
|
load_hba_and_ident();
|
||||||
|
load_password_cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* crypt.h
|
* crypt.h
|
||||||
* Interface to hba.c
|
* Interface to libpq/crypt.c
|
||||||
*
|
*
|
||||||
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
* $Id: crypt.h,v 1.17 2001/11/02 18:39:57 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -11,27 +15,22 @@
|
|||||||
|
|
||||||
#include "libpq/libpq-be.h"
|
#include "libpq/libpq-be.h"
|
||||||
|
|
||||||
#define CRYPT_PWD_FILE "pg_pwd"
|
|
||||||
#define CRYPT_PWD_FILE_SEPCHAR "'\\t'"
|
|
||||||
#define CRYPT_PWD_FILE_SEPSTR "\t"
|
#define CRYPT_PWD_FILE_SEPSTR "\t"
|
||||||
#define CRYPT_PWD_RELOAD_SUFX ".reload"
|
|
||||||
|
|
||||||
extern char **pwd_cache;
|
|
||||||
extern int pwd_cache_count;
|
|
||||||
|
|
||||||
extern char *crypt_getpwdfilename(void);
|
|
||||||
extern char *crypt_getpwdreloadfilename(void);
|
|
||||||
|
|
||||||
extern int md5_crypt_verify(const Port *port, const char *user, const char *pgpass);
|
|
||||||
|
|
||||||
extern bool md5_hash(const void *buff, size_t len, char *hexsum);
|
|
||||||
extern bool CheckMD5Pwd(char *passwd, char *storedpwd, char *seed);
|
|
||||||
extern bool EncryptMD5(const char *passwd, const char *salt,
|
|
||||||
size_t salt_len, char *buf);
|
|
||||||
|
|
||||||
#define MD5_PASSWD_LEN 35
|
#define MD5_PASSWD_LEN 35
|
||||||
|
|
||||||
#define isMD5(passwd) (strncmp((passwd),"md5",3) == 0 && \
|
#define isMD5(passwd) (strncmp((passwd),"md5",3) == 0 && \
|
||||||
strlen(passwd) == MD5_PASSWD_LEN)
|
strlen(passwd) == MD5_PASSWD_LEN)
|
||||||
|
|
||||||
|
|
||||||
|
extern char *crypt_getpwdfilename(void);
|
||||||
|
extern void load_password_cache(void);
|
||||||
|
|
||||||
|
extern int md5_crypt_verify(const Port *port, const char *user,
|
||||||
|
const char *pgpass);
|
||||||
|
extern bool md5_hash(const void *buff, size_t len, char *hexsum);
|
||||||
|
extern bool CheckMD5Pwd(char *passwd, char *storedpwd, char *seed);
|
||||||
|
extern bool EncryptMD5(const char *passwd, const char *salt,
|
||||||
|
size_t salt_len, char *buf);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user