From 39c7d9ce42be3f0878ee3c70b9b17c3ca96f9321 Mon Sep 17 00:00:00 2001
From: Jacob Champion <jacob.champion@enterprisedb.com>
Date: Fri, 8 Nov 2024 14:19:26 -0800
Subject: [PATCH v8 3/3] squash! Report external auth calls as wait events

Add a wait event around all calls to ldap_unbind(). (For the record, I
do not want to implement this in this way.)
---
 src/backend/libpq/auth.c                       | 18 ++++++++++++++++++
 .../utils/activity/wait_event_names.txt        |  9 +++++++++
 2 files changed, 27 insertions(+)

diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index f79626f019f..e42e7daa29c 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -2367,7 +2367,9 @@ InitializeLDAPConnection(Port *port, LDAP **ldap)
 				(errmsg("could not set LDAP protocol version: %s",
 						ldap_err2string(r)),
 				 errdetail_for_ldap(*ldap)));
+		pgstat_report_wait_start(WAIT_EVENT_LDAP_UNBIND_AFTER_SET_OPTION);
 		ldap_unbind(*ldap);
+		pgstat_report_wait_end();
 		return STATUS_ERROR;
 	}
 
@@ -2387,7 +2389,9 @@ InitializeLDAPConnection(Port *port, LDAP **ldap)
 					(errmsg("could not start LDAP TLS session: %s",
 							ldap_err2string(r)),
 					 errdetail_for_ldap(*ldap)));
+			pgstat_report_wait_start(WAIT_EVENT_LDAP_UNBIND_AFTER_START_TLS);
 			ldap_unbind(*ldap);
+			pgstat_report_wait_end();
 			return STATUS_ERROR;
 		}
 	}
@@ -2531,7 +2535,9 @@ CheckLDAPAuth(Port *port)
 			{
 				ereport(LOG,
 						(errmsg("invalid character in user name for LDAP authentication")));
+				pgstat_report_wait_start(WAIT_EVENT_LDAP_UNBIND_AFTER_NAME_CHECK);
 				ldap_unbind(ldap);
+				pgstat_report_wait_end();
 				pfree(passwd);
 				return STATUS_ERROR;
 			}
@@ -2555,7 +2561,9 @@ CheckLDAPAuth(Port *port)
 							server_name,
 							ldap_err2string(r)),
 					 errdetail_for_ldap(ldap)));
+			pgstat_report_wait_start(WAIT_EVENT_LDAP_UNBIND_AFTER_BIND_FOR_SEARCH);
 			ldap_unbind(ldap);
+			pgstat_report_wait_end();
 			pfree(passwd);
 			return STATUS_ERROR;
 		}
@@ -2588,7 +2596,9 @@ CheckLDAPAuth(Port *port)
 					 errdetail_for_ldap(ldap)));
 			if (search_message != NULL)
 				ldap_msgfree(search_message);
+			pgstat_report_wait_start(WAIT_EVENT_LDAP_UNBIND_AFTER_SEARCH);
 			ldap_unbind(ldap);
+			pgstat_report_wait_end();
 			pfree(passwd);
 			pfree(filter);
 			return STATUS_ERROR;
@@ -2610,7 +2620,9 @@ CheckLDAPAuth(Port *port)
 										  count,
 										  filter, server_name, count)));
 
+			pgstat_report_wait_start(WAIT_EVENT_LDAP_UNBIND_AFTER_COUNT_ENTRIES);
 			ldap_unbind(ldap);
+			pgstat_report_wait_end();
 			pfree(passwd);
 			pfree(filter);
 			ldap_msgfree(search_message);
@@ -2629,7 +2641,9 @@ CheckLDAPAuth(Port *port)
 							filter, server_name,
 							ldap_err2string(error)),
 					 errdetail_for_ldap(ldap)));
+			pgstat_report_wait_start(WAIT_EVENT_LDAP_UNBIND_AFTER_GET_DN);
 			ldap_unbind(ldap);
+			pgstat_report_wait_end();
 			pfree(passwd);
 			pfree(filter);
 			ldap_msgfree(search_message);
@@ -2657,7 +2671,9 @@ CheckLDAPAuth(Port *port)
 				(errmsg("LDAP login failed for user \"%s\" on server \"%s\": %s",
 						fulluser, server_name, ldap_err2string(r)),
 				 errdetail_for_ldap(ldap)));
+		pgstat_report_wait_start(WAIT_EVENT_LDAP_UNBIND_AFTER_BIND);
 		ldap_unbind(ldap);
+		pgstat_report_wait_end();
 		pfree(passwd);
 		pfree(fulluser);
 		return STATUS_ERROR;
@@ -2666,7 +2682,9 @@ CheckLDAPAuth(Port *port)
 	/* Save the original bind DN as the authenticated identity. */
 	set_authn_id(port, fulluser);
 
+	pgstat_report_wait_start(WAIT_EVENT_LDAP_UNBIND_SUCCESS);
 	ldap_unbind(ldap);
+	pgstat_report_wait_end();
 	pfree(passwd);
 	pfree(fulluser);
 
diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt
index a2852225614..f082756c294 100644
--- a/src/backend/utils/activity/wait_event_names.txt
+++ b/src/backend/utils/activity/wait_event_names.txt
@@ -177,6 +177,15 @@ LDAP_BIND_FOR_SEARCH	"Waiting for an LDAP bind operation to search the directory
 LDAP_HOST_LOOKUP	"Waiting for DNS lookup of LDAP servers."
 LDAP_SEARCH	"Waiting for an LDAP search operation to complete."
 LDAP_START_TLS	"Waiting for an LDAP StartTLS exchange."
+LDAP_UNBIND_AFTER_BIND	"Waiting for an LDAP connection to be unbound after a simple bind failed."
+LDAP_UNBIND_AFTER_BIND_FOR_SEARCH	"Waiting for an LDAP connection to be unbound after a bind for search failed."
+LDAP_UNBIND_AFTER_COUNT_ENTRIES	"Waiting for an LDAP connection to be unbound after an entry count failed."
+LDAP_UNBIND_AFTER_GET_DN	"Waiting for an LDAP connection to be unbound after ldap_get_dn failed."
+LDAP_UNBIND_AFTER_NAME_CHECK	"Waiting for an LDAP connection to be unbound after a name check failed."
+LDAP_UNBIND_AFTER_SEARCH	"Waiting for an LDAP connection to be unbound after a bind+search failed."
+LDAP_UNBIND_AFTER_SET_OPTION	"Waiting for an LDAP connection to be unbound after ldap_set_option failed."
+LDAP_UNBIND_AFTER_START_TLS	"Waiting for an LDAP connection to be unbound after ldap_start_tls_s failed."
+LDAP_UNBIND_SUCCESS	"Waiting for a successful LDAP connection to be unbound."
 PAM_ACCT_MGMT	"Waiting for the PAM service to validate the user account."
 PAM_AUTHENTICATE	"Waiting for the PAM service to authenticate the user."
 RADIUS_RECVFROM	"Waiting for a <function>recvfrom</function> call during a RADIUS transaction."
-- 
2.34.1

