From cb007441789dc19d40b4ae8902e0108b75811f00 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 1 Aug 2019 09:38:14 +0900
Subject: [PATCH] Fix handling of previous password hooks in passwordcheck

When piling up loading of modules using check_password_hook_type,
loading passwordcheck would remove any trace of a previously-loaded
hook.  Unloading the module would also cause previous hooks to be
entirely gone.

Reported-by: Rafael Castro
Author: Michael Paquier
Reviewed-by: Daniel Gustafsson
Discussion: https://postgr.es/m/15932-78f48f9ef166778c@postgresql.org
Backpatch-through: 9.4
---
 contrib/passwordcheck/passwordcheck.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/contrib/passwordcheck/passwordcheck.c b/contrib/passwordcheck/passwordcheck.c
index b80fd458ad7..435d118d123 100644
--- a/contrib/passwordcheck/passwordcheck.c
+++ b/contrib/passwordcheck/passwordcheck.c
@@ -26,10 +26,14 @@
 
 PG_MODULE_MAGIC;
 
+/* Saved hook value in case of unload */
+static check_password_hook_type prev_check_password_hook = NULL;
+
 /* passwords shorter than this will be rejected */
 #define MIN_PWD_LENGTH 8
 
 extern void _PG_init(void);
+extern void _PG_fini(void);
 
 /*
  * check_password
@@ -55,6 +59,11 @@ check_password(const char *username,
 			   Datum validuntil_time,
 			   bool validuntil_null)
 {
+	if (prev_check_password_hook)
+		prev_check_password_hook(username, shadow_pass,
+								 password_type, validuntil_time,
+								 validuntil_null);
+
 	if (password_type != PASSWORD_TYPE_PLAINTEXT)
 	{
 		/*
@@ -133,5 +142,16 @@ void
 _PG_init(void)
 {
 	/* activate password checks when the module is loaded */
+	prev_check_password_hook = check_password_hook;
 	check_password_hook = check_password;
 }
+
+/*
+ * Module unload function
+ */
+void
+_PG_fini(void)
+{
+	/* uninstall hook */
+	check_password_hook = prev_check_password_hook;
+}
-- 
GitLab