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 13:03:25.000000000 +0100 *************** *** 0 **** --- 1,89 ---- + #include + #include + #include "postgres.h" + #include "fmgr.h" + #include "libpq/md5.h" + #include "commands/user.h" + #ifdef USE_CRACKLIB + #include + #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, bool isencrypted) + { + 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