diff options
author | Bruce Momjian <bruce@momjian.us> | 2002-04-04 04:25:54 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2002-04-04 04:25:54 +0000 |
commit | 43a3543a4eb412a895df911eba9d8671ded45c54 (patch) | |
tree | 0ff55e96c81086081325b8e41b444915f99114f1 /src/backend/libpq/crypt.c | |
parent | af10378ab05f7979f0051c09f694709edcee8413 (diff) | |
download | postgresql-43a3543a4eb412a895df911eba9d8671ded45c54.tar.gz postgresql-43a3543a4eb412a895df911eba9d8671ded45c54.zip |
Authentication improvements:
A new pg_hba.conf column, USER
Allow specifiction of lists of users separated by commas
Allow group names specified by +
Allow include files containing lists of users specified by @
Allow lists of databases, and database files
Allow samegroup in database column to match group name matching dbname
Removal of secondary password files
Remove pg_passwd utility
Lots of code cleanup in user.c and hba.c
New data/global/pg_pwd format
New data/global/pg_group file
Diffstat (limited to 'src/backend/libpq/crypt.c')
-rw-r--r-- | src/backend/libpq/crypt.c | 232 |
1 files changed, 7 insertions, 225 deletions
diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c index 6ab63ddffe0..7c665300c85 100644 --- a/src/backend/libpq/crypt.c +++ b/src/backend/libpq/crypt.c @@ -9,13 +9,12 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/libpq/crypt.c,v 1.44 2002/03/04 01:46:03 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/crypt.c,v 1.45 2002/04/04 04:25:47 momjian Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" -#include <errno.h> #include <unistd.h> #ifdef HAVE_CRYPT_H #include <crypt.h> @@ -25,231 +24,10 @@ #include "libpq/libpq.h" #include "miscadmin.h" #include "storage/fd.h" +#include "nodes/pg_list.h" #include "utils/nabstime.h" -#define CRYPT_PWD_FILE "pg_pwd" - - -static char **pwd_cache = NULL; -static int pwd_cache_count = 0; - -/* - * crypt_getpwdfilename --- get full pathname of password file - * - * Note that result string is palloc'd, and should be freed by the caller. - */ -char * -crypt_getpwdfilename(void) -{ - int bufsize; - char *pfnam; - - bufsize = strlen(DataDir) + 8 + strlen(CRYPT_PWD_FILE) + 1; - pfnam = (char *) palloc(bufsize); - snprintf(pfnam, bufsize, "%s/global/%s", DataDir, CRYPT_PWD_FILE); - - return pfnam; -} - -/* - * Open the password file if possible (return NULL if not) - */ -static FILE * -crypt_openpwdfile(void) -{ - char *filename; - FILE *pwdfile; - - filename = crypt_getpwdfilename(); - pwdfile = AllocateFile(filename, "r"); - - if (pwdfile == NULL && errno != ENOENT) - elog(LOG, "could not open %s: %m", filename); - - pfree(filename); - - return pwdfile; -} - -/* - * Compare two password-file lines on the basis of their usernames. - * - * Can also be used to compare just a username against a password-file - * line (for bsearch). - */ -static int -compar_user(const void *user_a, const void *user_b) -{ - char *login_a; - char *login_b; - int len_a, - len_b, - result; - - login_a = *((char **) user_a); - login_b = *((char **) user_b); - - /* - * We only really want to compare the user logins which are first and - * are terminated by CRYPT_PWD_FILE_SEPSTR. (NB: this code - * effectively assumes that CRYPT_PWD_FILE_SEPSTR is just one char.) - */ - len_a = strcspn(login_a, CRYPT_PWD_FILE_SEPSTR); - len_b = strcspn(login_b, CRYPT_PWD_FILE_SEPSTR); - - result = strncmp(login_a, login_b, Min(len_a, len_b)); - - if (result == 0) /* one could be a prefix of the other */ - result = (len_a - len_b); - - return result; -} - -/* - * Load or reload the password-file cache - */ -void -load_password_cache(void) -{ - FILE *pwd_file; - char buffer[1024]; - - /* - * If for some reason we fail to open the password file, preserve the - * old cache contents; this seems better than dropping the cache if, - * say, we are temporarily out of filetable slots. - */ - if (!(pwd_file = crypt_openpwdfile())) - return; - - /* free any old data */ - if (pwd_cache) - { - while (--pwd_cache_count >= 0) - pfree(pwd_cache[pwd_cache_count]); - pfree(pwd_cache); - pwd_cache = NULL; - pwd_cache_count = 0; - } - - /* - * 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) - { - int blen; - - /* - * We must remove the return char at the end of the string, as - * this will affect the correct parsing of the password entry. - */ - if (buffer[(blen = strlen(buffer) - 1)] == '\n') - buffer[blen] = '\0'; - - if (pwd_cache == NULL) - pwd_cache = (char **) - palloc(sizeof(char *) * (pwd_cache_count + 1)); - else - pwd_cache = (char **) - repalloc((void *) pwd_cache, - sizeof(char *) * (pwd_cache_count + 1)); - pwd_cache[pwd_cache_count++] = pstrdup(buffer); - } - - FreeFile(pwd_file); - - /* - * Now sort the entries in the cache for faster searching later. - */ - 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 bool -crypt_parsepwdentry(char *buffer, char **pwd, char **valdate) -{ - char *parse = buffer; - int count, - i; - - *pwd = NULL; - *valdate = NULL; - - /* - * skip to the password field - */ - for (i = 0; i < 6; i++) - { - parse += strcspn(parse, CRYPT_PWD_FILE_SEPSTR); - if (*parse == '\0') - return false; - parse++; - } - - /* - * store a copy of user password to return - */ - count = strcspn(parse, CRYPT_PWD_FILE_SEPSTR); - *pwd = (char *) palloc(count + 1); - memcpy(*pwd, parse, count); - (*pwd)[count] = '\0'; - parse += count; - if (*parse == '\0') - { - pfree(*pwd); - *pwd = NULL; - return false; - } - parse++; - - /* - * store a copy of the date login becomes invalid - */ - count = strcspn(parse, CRYPT_PWD_FILE_SEPSTR); - *valdate = (char *) palloc(count + 1); - memcpy(*valdate, parse, count); - (*valdate)[count] = '\0'; - - return true; -} - -/* - * Lookup a username in the password-file cache, - * return his password and valid-until date. - */ -static bool -crypt_getloginfo(const char *user, char **passwd, char **valuntil) -{ - *passwd = NULL; - *valuntil = NULL; - - if (pwd_cache) - { - char **pwd_entry; - - pwd_entry = (char **) bsearch((void *) &user, - (void *) pwd_cache, - pwd_cache_count, - sizeof(char *), - compar_user); - if (pwd_entry) - { - if (crypt_parsepwdentry(*pwd_entry, passwd, valuntil)) - return true; - } - } - - return false; -} - -/*-------------------------------------------------------------------------*/ - int md5_crypt_verify(const Port *port, const char *user, const char *pgpass) { @@ -257,10 +35,14 @@ md5_crypt_verify(const Port *port, const char *user, const char *pgpass) *valuntil, *crypt_pwd; int retval = STATUS_ERROR; + List **line; - if (!crypt_getloginfo(user, &passwd, &valuntil)) + if ((line = get_user_line(user)) == NULL) return STATUS_ERROR; + passwd = lfirst(lnext(lnext(*line))); + valuntil = lfirst(lnext(lnext(lnext(*line)))); + if (passwd == NULL || *passwd == '\0') { if (passwd) |