diff options
author | Marc G. Fournier <scrappy@hub.org> | 1997-12-04 00:34:01 +0000 |
---|---|---|
committer | Marc G. Fournier <scrappy@hub.org> | 1997-12-04 00:34:01 +0000 |
commit | a91ad1af090d316e710965b670ef399bdbd80b82 (patch) | |
tree | 24cdf0f69e6f73a09194dc5ded68eac938ef9837 /src/backend/libpq/crypt.c | |
parent | 4c04f7724ed4b9aa798810f2cd016b6520a4f2a6 (diff) | |
download | postgresql-a91ad1af090d316e710965b670ef399bdbd80b82.tar.gz postgresql-a91ad1af090d316e710965b670ef399bdbd80b82.zip |
Missed a few files from Todd's patch...oops :)
Diffstat (limited to 'src/backend/libpq/crypt.c')
-rw-r--r-- | src/backend/libpq/crypt.c | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c new file mode 100644 index 00000000000..c75d8ac4590 --- /dev/null +++ b/src/backend/libpq/crypt.c @@ -0,0 +1,182 @@ +/*------------------------------------------------------------------------- + * + * crypt.c-- + * Look into pg_user and check the encrypted password with the one + * passed in from the frontend. + * + * + *------------------------------------------------------------------------- + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#ifdef HAVE_CRYPT_H +#include <crypt.h> +#endif + +#include <postgres.h> +#include <libpq/crypt.h> +#include <utils/nabstime.h> + +char* crypt_getpwdfilename() { + + static char* filename = NULL; + + if (!filename) { + char* env; + + env = getenv("PGDATA"); + filename = (char*)malloc(strlen(env) + strlen(CRYPT_PWD_FILE) + 2); + sprintf(filename, "%s/%s", env, CRYPT_PWD_FILE); + } + + return filename; +} + +/*-------------------------------------------------------------------------*/ + +static +FILE* crypt_openpwdfile() { + + char* filename; + + filename = crypt_getpwdfilename(); + return (fopen(filename, "r")); +} + +/*-------------------------------------------------------------------------*/ + +static +void crypt_parsepwdfile(FILE* datafile, char** login, char** pwd, char** valdate) { + + char buffer[256]; + char* parse; + int count, + i; + + fgets(buffer, 256, datafile); + parse = buffer; + + /* store a copy of user login to return + */ + count = strcspn(parse, "#"); + *login = (char*)malloc(count + 1); + strncpy(*login, parse, count); + (*login)[count] = '\0'; + parse += (count + 1); + + /* skip to the password field + */ + for (i = 0; i < 5; i++) + parse += (strcspn(parse, "#") + 1); + + /* store a copy of user password to return + */ + count = strcspn(parse, "#"); + *pwd = (char*)malloc(count + 1); + strncpy(*pwd, parse, count); + (*pwd)[count] = '\0'; + parse += (count + 1); + + /* store a copy of date login becomes invalid + */ + count = strcspn(parse, "#"); + *valdate = (char*)malloc(count + 1); + strncpy(*valdate, parse, count); + (*valdate)[count] = '\0'; + parse += (count + 1); +} + +/*-------------------------------------------------------------------------*/ + +static +void crypt_getloginfo(const char* user, char** passwd, char** valuntil) { + + FILE* datafile; + char* login; + char* pwd; + char* valdate; + + *passwd = NULL; + *valuntil = NULL; + + if (!(datafile = crypt_openpwdfile())) + return; + + while (!feof(datafile)) { + crypt_parsepwdfile(datafile, &login, &pwd, &valdate); + if (!strcmp(login, user)) { + free((void*)login); + *passwd = pwd; + *valuntil = valdate; + fclose(datafile); + return; + } + free((void*)login); + free((void*)pwd); + free((void*)valdate); + } + fclose(datafile); +} + +/*-------------------------------------------------------------------------*/ + +MsgType crypt_salt(const char* user) { + + char* passwd; + char* valuntil; + + crypt_getloginfo(user, &passwd, &valuntil); + + if (passwd == NULL || *passwd == '\0') { + if (passwd) free((void*)passwd); + if (valuntil) free((void*)valuntil); + return STARTUP_UNSALT_MSG; + } + + free((void*)passwd); + if (valuntil) free((void*)valuntil); + return STARTUP_SALT_MSG; +} + +/*-------------------------------------------------------------------------*/ + +int crypt_verify(Port* port, const char* user, const char* pgpass) { + + char* passwd; + char* valuntil; + char* crypt_pwd; + int retval = STATUS_ERROR; + AbsoluteTime vuntil, + current; + + crypt_getloginfo(user, &passwd, &valuntil); + + if (passwd == NULL || *passwd == '\0') { + if (passwd) free((void*)passwd); + if (valuntil) free((void*)valuntil); + return STATUS_ERROR; + } + + crypt_pwd = crypt(passwd, port->salt); + if (!strcmp(pgpass, crypt_pwd)) { + /* check here to be sure we are not past valuntil + */ + if (!valuntil) + vuntil = INVALID_ABSTIME; + else + vuntil = nabstimein(valuntil); + current = GetCurrentAbsoluteTime(); + if (vuntil != INVALID_ABSTIME && vuntil < current) + retval = STATUS_ERROR; + else + retval = STATUS_OK; + } + + free((void*)passwd); + if (valuntil) free((void*)valuntil); + + return retval; +} |