aboutsummaryrefslogtreecommitdiff
path: root/src/backend/libpq/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/libpq/auth.c')
-rw-r--r--src/backend/libpq/auth.c47
1 files changed, 36 insertions, 11 deletions
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index d5115aad729..fb86e9e9d41 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -363,7 +363,7 @@ ClientAuthentication(Port *port)
* current connection, so perform any verifications based on the hba
* options field that should be done *before* the authentication here.
*/
- if (port->hba->clientcert)
+ if (port->hba->clientcert != clientCertOff)
{
/* If we haven't loaded a root certificate store, fail */
if (!secure_loaded_verify_locations())
@@ -583,22 +583,30 @@ ClientAuthentication(Port *port)
Assert(false);
#endif
break;
-
- case uaCert:
-#ifdef USE_SSL
- status = CheckCertAuth(port);
-#else
- Assert(false);
-#endif
- break;
case uaRADIUS:
status = CheckRADIUSAuth(port);
break;
+ case uaCert:
+ /* uaCert will be treated as if clientcert=verify-full (uaTrust) */
case uaTrust:
status = STATUS_OK;
break;
}
+ if ((status == STATUS_OK && port->hba->clientcert == clientCertFull)
+ || port->hba->auth_method == uaCert)
+ {
+ /*
+ * Make sure we only check the certificate if we use the cert method
+ * or verify-full option.
+ */
+#ifdef USE_SSL
+ status = CheckCertAuth(port);
+#else
+ Assert(false);
+#endif
+ }
+
if (ClientAuthentication_hook)
(*ClientAuthentication_hook) (port, status);
@@ -2788,6 +2796,8 @@ errdetail_for_ldap(LDAP *ldap)
static int
CheckCertAuth(Port *port)
{
+ int status_check_usermap = STATUS_ERROR;
+
Assert(port->ssl);
/* Make sure we have received a username in the certificate */
@@ -2800,8 +2810,23 @@ CheckCertAuth(Port *port)
return STATUS_ERROR;
}
- /* Just pass the certificate CN to the usermap check */
- return check_usermap(port->hba->usermap, port->user_name, port->peer_cn, false);
+ /* Just pass the certificate cn to the usermap check */
+ status_check_usermap = check_usermap(port->hba->usermap, port->user_name, port->peer_cn, false);
+ if (status_check_usermap != STATUS_OK)
+ {
+ /*
+ * If clientcert=verify-full was specified and the authentication
+ * method is other than uaCert, log the reason for rejecting the
+ * authentication.
+ */
+ if (port->hba->clientcert == clientCertFull && port->hba->auth_method != uaCert)
+ {
+ ereport(LOG,
+ (errmsg("certificate validation (clientcert=verify-full) failed for user \"%s\": cn mismatch",
+ port->user_name)));
+ }
+ }
+ return status_check_usermap;
}
#endif