mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
234a02b2a8
Get rid of VARATT_SIZE and VARATT_DATA, which were simply redundant with VARSIZE and VARDATA, and as a consequence almost no code was using the longer names. Rename the length fields of struct varlena and various derived structures to catch anyplace that was accessing them directly; and clean up various places so caught. In itself this patch doesn't change any behavior at all, but it is necessary infrastructure if we hope to play any games with the representation of varlena headers. Greg Stark and Tom Lane
172 lines
3.6 KiB
C
172 lines
3.6 KiB
C
/*
|
|
* PostgreSQL type definitions for chkpass
|
|
* Written by D'Arcy J.M. Cain
|
|
* darcy@druid.net
|
|
* http://www.druid.net/darcy/
|
|
*
|
|
* $PostgreSQL: pgsql/contrib/chkpass/chkpass.c,v 1.19 2007/02/27 23:48:05 tgl Exp $
|
|
* best viewed with tabs set to 4
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
#ifdef HAVE_CRYPT_H
|
|
#include <crypt.h>
|
|
#endif
|
|
|
|
#include "fmgr.h"
|
|
|
|
PG_MODULE_MAGIC;
|
|
|
|
/*
|
|
* This type encrypts it's input unless the first character is a colon.
|
|
* The output is the encrypted form with a leading colon. The output
|
|
* format is designed to allow dump and reload operations to work as
|
|
* expected without doing special tricks.
|
|
*/
|
|
|
|
|
|
/*
|
|
* This is the internal storage format for CHKPASSs.
|
|
* 15 is all I need but add a little buffer
|
|
*/
|
|
|
|
typedef struct chkpass
|
|
{
|
|
char password[16];
|
|
} chkpass;
|
|
|
|
/*
|
|
* Various forward declarations:
|
|
*/
|
|
|
|
Datum chkpass_in(PG_FUNCTION_ARGS);
|
|
Datum chkpass_out(PG_FUNCTION_ARGS);
|
|
Datum chkpass_rout(PG_FUNCTION_ARGS);
|
|
|
|
/* Only equal or not equal make sense */
|
|
Datum chkpass_eq(PG_FUNCTION_ARGS);
|
|
Datum chkpass_ne(PG_FUNCTION_ARGS);
|
|
|
|
|
|
/* This function checks that the password is a good one
|
|
* It's just a placeholder for now */
|
|
static int
|
|
verify_pass(const char *str)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* CHKPASS reader.
|
|
*/
|
|
PG_FUNCTION_INFO_V1(chkpass_in);
|
|
Datum
|
|
chkpass_in(PG_FUNCTION_ARGS)
|
|
{
|
|
char *str = PG_GETARG_CSTRING(0);
|
|
chkpass *result;
|
|
char mysalt[4];
|
|
static char salt_chars[] =
|
|
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
|
|
/* special case to let us enter encrypted passwords */
|
|
if (*str == ':')
|
|
{
|
|
result = (chkpass *) palloc(sizeof(chkpass));
|
|
strlcpy(result->password, str + 1, 13 + 1);
|
|
PG_RETURN_POINTER(result);
|
|
}
|
|
|
|
if (verify_pass(str) != 0)
|
|
ereport(ERROR,
|
|
(errcode(ERRCODE_DATA_EXCEPTION),
|
|
errmsg("password \"%s\" is weak", str)));
|
|
|
|
result = (chkpass *) palloc(sizeof(chkpass));
|
|
|
|
mysalt[0] = salt_chars[random() & 0x3f];
|
|
mysalt[1] = salt_chars[random() & 0x3f];
|
|
mysalt[2] = 0; /* technically the terminator is not necessary
|
|
* but I like to play safe */
|
|
strcpy(result->password, crypt(str, mysalt));
|
|
PG_RETURN_POINTER(result);
|
|
}
|
|
|
|
/*
|
|
* CHKPASS output function.
|
|
* Just like any string but we know it is max 15 (13 plus colon and terminator.)
|
|
*/
|
|
|
|
PG_FUNCTION_INFO_V1(chkpass_out);
|
|
Datum
|
|
chkpass_out(PG_FUNCTION_ARGS)
|
|
{
|
|
chkpass *password = (chkpass *) PG_GETARG_POINTER(0);
|
|
char *result;
|
|
|
|
result = (char *) palloc(16);
|
|
result[0] = ':';
|
|
strcpy(result + 1, password->password);
|
|
|
|
PG_RETURN_CSTRING(result);
|
|
}
|
|
|
|
|
|
/*
|
|
* special output function that doesn't output the colon
|
|
*/
|
|
|
|
PG_FUNCTION_INFO_V1(chkpass_rout);
|
|
Datum
|
|
chkpass_rout(PG_FUNCTION_ARGS)
|
|
{
|
|
chkpass *password = (chkpass *) PG_GETARG_POINTER(0);
|
|
text *result;
|
|
int slen;
|
|
|
|
slen = strlen(password->password);
|
|
result = (text *) palloc(VARHDRSZ + slen);
|
|
SET_VARSIZE(result, VARHDRSZ + slen);
|
|
memcpy(VARDATA(result), password->password, slen);
|
|
|
|
PG_RETURN_TEXT_P(result);
|
|
}
|
|
|
|
|
|
/*
|
|
* Boolean tests
|
|
*/
|
|
|
|
PG_FUNCTION_INFO_V1(chkpass_eq);
|
|
Datum
|
|
chkpass_eq(PG_FUNCTION_ARGS)
|
|
{
|
|
chkpass *a1 = (chkpass *) PG_GETARG_POINTER(0);
|
|
text *a2 = (text *) PG_GETARG_TEXT_P(1);
|
|
char str[10];
|
|
int sz;
|
|
|
|
sz = Min(VARSIZE(a2) - VARHDRSZ, 8);
|
|
memcpy(str, VARDATA(a2), sz);
|
|
str[sz] = '\0';
|
|
PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) == 0);
|
|
}
|
|
|
|
PG_FUNCTION_INFO_V1(chkpass_ne);
|
|
Datum
|
|
chkpass_ne(PG_FUNCTION_ARGS)
|
|
{
|
|
chkpass *a1 = (chkpass *) PG_GETARG_POINTER(0);
|
|
text *a2 = (text *) PG_GETARG_TEXT_P(1);
|
|
char str[10];
|
|
int sz;
|
|
|
|
sz = Min(VARSIZE(a2) - VARHDRSZ, 8);
|
|
memcpy(str, VARDATA(a2), sz);
|
|
str[sz] = '\0';
|
|
PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) != 0);
|
|
}
|