diff options
author | Nathan Bossart | 2025-01-07 21:06:40 +0000 |
---|---|---|
committer | Nathan Bossart | 2025-01-07 21:06:40 +0000 |
commit | f7e1b3828a930639aefb5746a214cb5ddf734361 (patch) | |
tree | 336b31633f29da5e3eab7b25e0277b29f0d04299 | |
parent | 6d01541960e2a42c92ef67be9a1c4842cd4458d6 (diff) |
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, Japin Li
Discussion: https://postgr.es/m/CA%2BugDNyYtHOtWCqVD3YkSVYDWD_1fO8Jm_ahsDGA5dXhbDPwrQ%40mail.gmail.com
-rw-r--r-- | contrib/passwordcheck/expected/passwordcheck.out | 4 | ||||
-rw-r--r-- | contrib/passwordcheck/expected/passwordcheck_1.out | 4 | ||||
-rw-r--r-- | contrib/passwordcheck/passwordcheck.c | 24 | ||||
-rw-r--r-- | contrib/passwordcheck/sql/passwordcheck.sql | 4 | ||||
-rw-r--r-- | doc/src/sgml/passwordcheck.sgml | 37 |
5 files changed, 69 insertions, 4 deletions
diff --git a/contrib/passwordcheck/expected/passwordcheck.out b/contrib/passwordcheck/expected/passwordcheck.out index dfb2ccfe008..83472c76d27 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 9519d60a495..fb12ec45cc4 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 96ada5b98c6..3db42a5b99d 100644 --- a/contrib/passwordcheck/passwordcheck.c +++ b/contrib/passwordcheck/passwordcheck.c @@ -15,6 +15,7 @@ #include "postgres.h" #include <ctype.h> +#include <limits.h> #ifdef USE_CRACKLIB #include <crack.h> @@ -29,8 +30,8 @@ PG_MODULE_MAGIC; /* Saved hook value */ 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 5953ece5c26..21ad8d452b5 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 601f4892272..7ea32410463 100644 --- a/doc/src/sgml/passwordcheck.sgml +++ b/doc/src/sgml/passwordcheck.sgml @@ -59,4 +59,41 @@ </para> </caution> + <sect2 id="passwordcheck-configuration-parameters"> + <title>Configuration Parameters</title> + + <variablelist> + <varlistentry> + <term> + <varname>passwordcheck.min_password_length</varname> (<type>integer</type>) + <indexterm> + <primary><varname>passwordcheck.min_password_length</varname> configuration parameter</primary> + </indexterm> + </term> + <listitem> + <para> + The minimum acceptable password length in bytes. The default is 8. Only + superusers can change this setting. + </para> + <note> + <para> + This parameter has no effect if a user supplies a pre-encrypted + password. + </para> + </note> + </listitem> + </varlistentry> + </variablelist> + + <para> + In ordinary usage, this parameter is set in + <filename>postgresql.conf</filename>, but superusers can alter it on-the-fly + within their own sessions. Typical usage might be: + </para> + +<programlisting> +# postgresql.conf +passwordcheck.min_password_length = 12 +</programlisting> + </sect2> </sect1> |