mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 10:30:33 +03:00 
			
		
		
		
	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);
 | |
| }
 |