diff --new-file -c -r postgresql-8.5.orig/contrib/Makefile postgresql-8.5/contrib/Makefile
*** postgresql-8.5.orig/contrib/Makefile	2009-11-16 11:31:13.000000000 +0100
--- postgresql-8.5/contrib/Makefile	2009-11-16 11:34:11.000000000 +0100
***************
*** 25,30 ****
--- 25,31 ----
  		ltree		\
  		oid2name	\
  		pageinspect	\
+ 		passwordcheck	\
  		pg_buffercache	\
  		pg_freespacemap \
  		pg_standby	\
diff --new-file -c -r postgresql-8.5.orig/contrib/passwordcheck/Makefile postgresql-8.5/contrib/passwordcheck/Makefile
*** postgresql-8.5.orig/contrib/passwordcheck/Makefile	1970-01-01 01:00:00.000000000 +0100
--- postgresql-8.5/contrib/passwordcheck/Makefile	2009-11-16 11:34:11.000000000 +0100
***************
*** 0 ****
--- 1,16 ----
+ MODULE_big = passwordcheck
+ OBJS = passwordcheck.o
+ # uncomment the following two lines to enable cracklib support
+ # SHLIB_LINK += -lcrack
+ # CUSTOM_COPT += -DUSE_CRACKLIB
+ 
+ ifdef USE_PGXS
+ PG_CONFIG = pg_config
+ PGXS := $(shell $(PG_CONFIG) --pgxs)
+ include $(PGXS)
+ else
+ subdir = contrib/passwordcheck
+ top_builddir = ../..
+ include $(top_builddir)/src/Makefile.global
+ include $(top_srcdir)/contrib/contrib-global.mk
+ endif
diff --new-file -c -r postgresql-8.5.orig/contrib/passwordcheck/passwordcheck.c postgresql-8.5/contrib/passwordcheck/passwordcheck.c
*** postgresql-8.5.orig/contrib/passwordcheck/passwordcheck.c	1970-01-01 01:00:00.000000000 +0100
--- postgresql-8.5/contrib/passwordcheck/passwordcheck.c	2009-11-17 11:21:50.000000000 +0100
***************
*** 0 ****
--- 1,91 ----
+ #include <string.h>
+ #include <ctype.h>
+ #include "postgres.h"
+ #include "fmgr.h"
+ #include "libpq/md5.h"
+ #include "commands/user.h"
+ #ifdef USE_CRACKLIB
+ #include <crack.h>
+ #define CRACKLIB_DICTPATH "/usr/lib/cracklib_dict"
+ #endif
+ 
+ PG_MODULE_MAGIC;
+ 
+ extern void _PG_init(void);
+ 
+ /* passwords shorter than that will be rejected */
+ #define MIN_PWD_LENGTH 8
+ 
+ /*
+  * check_password
+  * performs checks on an encrypted or unencrypted password
+  * returns "false" if the password is rejected as too weak, else "true"
+  */
+ static bool check_password(const char * username, const char * password)
+ {
+ 	/* a password is considered encrypted if it starts with "md5" */
+ 	const bool isencrypted = isMD5(password);
+ 	const int namelen = strlen(username), pwdlen = strlen(password);
+ 	char encrypted[MD5_PASSWD_LEN + 1];
+ 	int i;
+ 	bool pwd_has_letter, pwd_has_nonletter;
+ 
+ 	if (isencrypted)
+ 	{
+ 		/*
+ 		 * unfortunately we cannot perform exhaustive checks on
+ 		 * encrypted passwords - we are restricted to guessing
+ 		 * we check for username = password
+ 		 */
+ 		if (! pg_md5_encrypt(username, username, namelen, encrypted))
+ 			elog(ERROR, "password encryption failed");
+ 
+ 		if (! strcmp(password, encrypted))
+ 			return false;
+ 	}
+ 	else
+ 	{
+ 		/*
+ 		 * for unencrypted passwords we can perform better checks
+ 		 */
+ 		/* check if the password is less than MIN_PWD_LENGTH characters long */
+ 		if (pwdlen < MIN_PWD_LENGTH)
+ 			return false;
+ 
+ 		/* check if the password contains the username */
+ 		if (strstr(password, username))
+ 			return false;
+ 
+ 		/* check if the password contains both letters and non-letters */
+ 		pwd_has_letter = false;
+ 		pwd_has_nonletter = false;
+ 		for (i=1; i<pwdlen; ++i)
+ 		{
+ 			/*
+ 			 * isalpha() does not work for multibyte encodings
+ 			 * but let's consider non-ASCII characters non-letters
+ 			 */
+ 			if (isalpha((unsigned char) password[i]))
+ 				pwd_has_letter = true;
+ 			else
+ 				pwd_has_nonletter = true;
+ 		}
+ 		if (! pwd_has_letter || ! pwd_has_nonletter)
+ 			return false;
+ 
+ #ifdef USE_CRACKLIB
+ 		/* call cracklib to check password */
+ 		if (FascistCheck(password, CRACKLIB_DICTPATH))
+ 			return false;
+ #endif
+ 	}
+ 
+ 	/* all checks passed, password is ok */
+ 	return true;
+ }
+ 
+ void _PG_init(void)
+ {
+ 	/* activate password checks when the module is loaded */
+ 	check_password_hook = &check_password;
+ }
