On Thu, Dec 19, 2024 at 09:36:17AM -0600, Nathan Bossart wrote:
> On Thu, Dec 19, 2024 at 07:25:30AM +0000, Bertrand Drouvot wrote:
>> - errmsg("password is too short")));
>> + errmsg("password is too short: %d (<
>> %d)", pwdlen, min_password_length)));
>
> I think we should explicitly point to the parameter and note its current
> value.
Like so.
--
nathan
>From ce67f3ff5fca47b443195f5bd1932429294bdbfb Mon Sep 17 00:00:00 2001
From: Nathan Bossart <[email protected]>
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 <ctype.h>
+#include <limits.h>
#ifdef USE_CRACKLIB
#include <crack.h>
@@ -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 @@
</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>
--
2.39.5 (Apple Git-154)