From ce67f3ff5fca47b443195f5bd1932429294bdbfb Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Wed, 18 Dec 2024 14:49:20 -0600 Subject: [PATCH v11 1/1] Add passwordcheck.min_password_length. This new parameter can be used to change the minimum allowed password length (in bytes). Note that it has no effect if a user supplies a pre-encrypted password. Author: Emanuele Musella, Maurizio Boriani Reviewed-by: Tomas Vondra, Bertrand Drouvot Discussion: https://postgr.es/m/CA%2BugDNyYtHOtWCqVD3YkSVYDWD_1fO8Jm_ahsDGA5dXhbDPwrQ%40mail.gmail.com --- .../passwordcheck/expected/passwordcheck.out | 4 ++ .../expected/passwordcheck_1.out | 4 ++ contrib/passwordcheck/passwordcheck.c | 26 ++++++++++--- contrib/passwordcheck/sql/passwordcheck.sql | 4 ++ doc/src/sgml/passwordcheck.sgml | 37 +++++++++++++++++++ 5 files changed, 70 insertions(+), 5 deletions(-) diff --git a/contrib/passwordcheck/expected/passwordcheck.out b/contrib/passwordcheck/expected/passwordcheck.out index dfb2ccfe00..83472c76d2 100644 --- a/contrib/passwordcheck/expected/passwordcheck.out +++ b/contrib/passwordcheck/expected/passwordcheck.out @@ -6,6 +6,10 @@ ALTER USER regress_passwordcheck_user1 PASSWORD 'a_nice_long_password'; -- error: too short ALTER USER regress_passwordcheck_user1 PASSWORD 'tooshrt'; ERROR: password is too short +DETAIL: password must be at least "passwordcheck.min_password_length" (8) bytes long +-- ok +SET passwordcheck.min_password_length = 6; +ALTER USER regress_passwordcheck_user1 PASSWORD 'v_shrt'; -- error: contains user name ALTER USER regress_passwordcheck_user1 PASSWORD 'xyzregress_passwordcheck_user1'; ERROR: password must not contain user name diff --git a/contrib/passwordcheck/expected/passwordcheck_1.out b/contrib/passwordcheck/expected/passwordcheck_1.out index 9519d60a49..fb12ec45cc 100644 --- a/contrib/passwordcheck/expected/passwordcheck_1.out +++ b/contrib/passwordcheck/expected/passwordcheck_1.out @@ -6,6 +6,10 @@ ALTER USER regress_passwordcheck_user1 PASSWORD 'a_nice_long_password'; -- error: too short ALTER USER regress_passwordcheck_user1 PASSWORD 'tooshrt'; ERROR: password is too short +DETAIL: password must be at least "passwordcheck.min_password_length" (8) bytes long +-- ok +SET passwordcheck.min_password_length = 6; +ALTER USER regress_passwordcheck_user1 PASSWORD 'v_shrt'; -- error: contains user name ALTER USER regress_passwordcheck_user1 PASSWORD 'xyzregress_passwordcheck_user1'; ERROR: password must not contain user name diff --git a/contrib/passwordcheck/passwordcheck.c b/contrib/passwordcheck/passwordcheck.c index 0785618f2a..d79ecb00b6 100644 --- a/contrib/passwordcheck/passwordcheck.c +++ b/contrib/passwordcheck/passwordcheck.c @@ -15,6 +15,7 @@ #include "postgres.h" #include +#include #ifdef USE_CRACKLIB #include @@ -26,11 +27,11 @@ PG_MODULE_MAGIC; -/* Saved hook value in case of unload */ +/* Original hook */ static check_password_hook_type prev_check_password_hook = NULL; -/* passwords shorter than this will be rejected */ -#define MIN_PWD_LENGTH 8 +/* GUC variables */ +static int min_password_length = 8; /* * check_password @@ -93,10 +94,12 @@ check_password(const char *username, #endif /* enforce minimum length */ - if (pwdlen < MIN_PWD_LENGTH) + if (pwdlen < min_password_length) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("password is too short"))); + errmsg("password is too short"), + errdetail("password must be at least \"passwordcheck.min_password_length\" (%d) bytes long", + min_password_length))); /* check if the password contains the username */ if (strstr(password, username)) @@ -142,6 +145,19 @@ check_password(const char *username, void _PG_init(void) { + /* Define custom GUC variables. */ + DefineCustomIntVariable("passwordcheck.min_password_length", + "Minimum allowed password length.", + NULL, + &min_password_length, + 8, + 0, INT_MAX, + PGC_SUSET, + GUC_UNIT_BYTE, + NULL, NULL, NULL); + + MarkGUCPrefixReserved("passwordcheck"); + /* activate password checks when the module is loaded */ prev_check_password_hook = check_password_hook; check_password_hook = check_password; diff --git a/contrib/passwordcheck/sql/passwordcheck.sql b/contrib/passwordcheck/sql/passwordcheck.sql index 5953ece5c2..21ad8d452b 100644 --- a/contrib/passwordcheck/sql/passwordcheck.sql +++ b/contrib/passwordcheck/sql/passwordcheck.sql @@ -9,6 +9,10 @@ ALTER USER regress_passwordcheck_user1 PASSWORD 'a_nice_long_password'; -- error: too short ALTER USER regress_passwordcheck_user1 PASSWORD 'tooshrt'; +-- ok +SET passwordcheck.min_password_length = 6; +ALTER USER regress_passwordcheck_user1 PASSWORD 'v_shrt'; + -- error: contains user name ALTER USER regress_passwordcheck_user1 PASSWORD 'xyzregress_passwordcheck_user1'; diff --git a/doc/src/sgml/passwordcheck.sgml b/doc/src/sgml/passwordcheck.sgml index 601f489227..7ea3241046 100644 --- a/doc/src/sgml/passwordcheck.sgml +++ b/doc/src/sgml/passwordcheck.sgml @@ -59,4 +59,41 @@ + + Configuration Parameters + + + + + passwordcheck.min_password_length (integer) + + passwordcheck.min_password_length configuration parameter + + + + + The minimum acceptable password length in bytes. The default is 8. Only + superusers can change this setting. + + + + This parameter has no effect if a user supplies a pre-encrypted + password. + + + + + + + + In ordinary usage, this parameter is set in + postgresql.conf, but superusers can alter it on-the-fly + within their own sessions. Typical usage might be: + + + +# postgresql.conf +passwordcheck.min_password_length = 12 + + -- 2.39.5 (Apple Git-154)