#include "libpq/libpq-be.h"
Go to the source code of this file.
Typedefs | |
typedef void(* | ClientAuthentication_hook_type )(Port *, int) |
Functions | |
void | ClientAuthentication (Port *port) |
Variables | |
char * | pg_krb_server_keyfile |
char * | pg_krb_srvnam |
bool | pg_krb_caseins_users |
char * | pg_krb_server_hostname |
char * | pg_krb_realm |
PGDLLIMPORT ClientAuthentication_hook_type | ClientAuthentication_hook |
typedef void(* ClientAuthentication_hook_type)(Port *, int) |
void ClientAuthentication | ( | Port * | port | ) |
Definition at line 319 of file auth.c.
References _, SockAddr::addr, am_walsender, Assert, auth_failed(), HbaLine::auth_method, AUTH_REQ_GSS, AUTH_REQ_KRB5, AUTH_REQ_MD5, AUTH_REQ_OK, AUTH_REQ_PASSWORD, AUTH_REQ_SSPI, CHECK_FOR_INTERRUPTS, CheckRADIUSAuth(), ClientAuthentication_hook, HbaLine::clientcert, Port::database_name, Db_user_namespace, ereport, errcode(), errmsg(), FATAL, Port::hba, hba_getauthmethod(), HOSTNAME_LOOKUP_DETAIL, ident_inet(), ImmediateInterruptOK, NI_NUMERICHOST, NULL, pg_getnameinfo_all(), Port::raddr, recv_and_check_password_packet(), SockAddr::salen, sendAuthRequest(), status(), STATUS_OK, uaCert, uaGSS, uaIdent, uaImplicitReject, uaKrb5, uaLDAP, uaMD5, uaPAM, uaPassword, uaPeer, uaRADIUS, uaReject, uaSSPI, uaTrust, and Port::user_name.
Referenced by PerformAuthentication().
{ int status = STATUS_ERROR; /* * Get the authentication method to use for this frontend/database * combination. Note: we do not parse the file at this point; this has * already been done elsewhere. hba.c dropped an error message into the * server logfile if parsing the hba config file failed. */ hba_getauthmethod(port); /* * Enable immediate response to SIGTERM/SIGINT/timeout interrupts. (We * don't want this during hba_getauthmethod() because it might have to do * database access, eg for role membership checks.) */ ImmediateInterruptOK = true; /* And don't forget to detect one that already arrived */ CHECK_FOR_INTERRUPTS(); /* * This is the first point where we have access to the hba record for the * current connection, so perform any verifications based on the hba * options field that should be done *before* the authentication here. */ if (port->hba->clientcert) { /* * When we parse pg_hba.conf, we have already made sure that we have * been able to load a certificate store. Thus, if a certificate is * present on the client, it has been verified against our root * certificate store, and the connection would have been aborted * already if it didn't verify ok. */ #ifdef USE_SSL if (!port->peer) { ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("connection requires a valid client certificate"))); } #else /* * hba.c makes sure hba->clientcert can't be set unless OpenSSL is * present. */ Assert(false); #endif } /* * Now proceed to do the actual authentication check */ switch (port->hba->auth_method) { case uaReject: /* * An explicit "reject" entry in pg_hba.conf. This report exposes * the fact that there's an explicit reject entry, which is * perhaps not so desirable from a security standpoint; but the * message for an implicit reject could confuse the DBA a lot when * the true situation is a match to an explicit reject. And we * don't want to change the message for an implicit reject. As * noted below, the additional information shown here doesn't * expose anything not known to an attacker. */ { char hostinfo[NI_MAXHOST]; pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen, hostinfo, sizeof(hostinfo), NULL, 0, NI_NUMERICHOST); if (am_walsender) { #ifdef USE_SSL ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s", hostinfo, port->user_name, port->ssl ? _("SSL on") : _("SSL off")))); #else ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"", hostinfo, port->user_name))); #endif } else { #ifdef USE_SSL ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s", hostinfo, port->user_name, port->database_name, port->ssl ? _("SSL on") : _("SSL off")))); #else ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"", hostinfo, port->user_name, port->database_name))); #endif } break; } case uaImplicitReject: /* * No matching entry, so tell the user we fell through. * * NOTE: the extra info reported here is not a security breach, * because all that info is known at the frontend and must be * assumed known to bad guys. We're merely helping out the less * clueful good guys. */ { char hostinfo[NI_MAXHOST]; pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen, hostinfo, sizeof(hostinfo), NULL, 0, NI_NUMERICHOST); #define HOSTNAME_LOOKUP_DETAIL(port) \ (port->remote_hostname \ ? (port->remote_hostname_resolv == +1 \ ? errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", port->remote_hostname) \ : (port->remote_hostname_resolv == 0 \ ? errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", port->remote_hostname) \ : (port->remote_hostname_resolv == -1 \ ? errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", port->remote_hostname) \ : 0))) \ : 0) if (am_walsender) { #ifdef USE_SSL ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s", hostinfo, port->user_name, port->ssl ? _("SSL on") : _("SSL off")), HOSTNAME_LOOKUP_DETAIL(port))); #else ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"", hostinfo, port->user_name), HOSTNAME_LOOKUP_DETAIL(port))); #endif } else { #ifdef USE_SSL ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s", hostinfo, port->user_name, port->database_name, port->ssl ? _("SSL on") : _("SSL off")), HOSTNAME_LOOKUP_DETAIL(port))); #else ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"", hostinfo, port->user_name, port->database_name), HOSTNAME_LOOKUP_DETAIL(port))); #endif } break; } case uaKrb5: #ifdef KRB5 sendAuthRequest(port, AUTH_REQ_KRB5); status = pg_krb5_recvauth(port); #else Assert(false); #endif break; case uaGSS: #ifdef ENABLE_GSS sendAuthRequest(port, AUTH_REQ_GSS); status = pg_GSS_recvauth(port); #else Assert(false); #endif break; case uaSSPI: #ifdef ENABLE_SSPI sendAuthRequest(port, AUTH_REQ_SSPI); status = pg_SSPI_recvauth(port); #else Assert(false); #endif break; case uaPeer: #ifdef HAVE_UNIX_SOCKETS status = auth_peer(port); #else Assert(false); #endif break; case uaIdent: status = ident_inet(port); break; case uaMD5: if (Db_user_namespace) ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("MD5 authentication is not supported when \"db_user_namespace\" is enabled"))); sendAuthRequest(port, AUTH_REQ_MD5); status = recv_and_check_password_packet(port); break; case uaPassword: sendAuthRequest(port, AUTH_REQ_PASSWORD); status = recv_and_check_password_packet(port); break; case uaPAM: #ifdef USE_PAM status = CheckPAMAuth(port, port->user_name, ""); #else Assert(false); #endif /* USE_PAM */ break; case uaLDAP: #ifdef USE_LDAP status = CheckLDAPAuth(port); #else Assert(false); #endif break; case uaCert: #ifdef USE_SSL status = CheckCertAuth(port); #else Assert(false); #endif break; case uaRADIUS: status = CheckRADIUSAuth(port); break; case uaTrust: status = STATUS_OK; break; } if (ClientAuthentication_hook) (*ClientAuthentication_hook) (port, status); if (status == STATUS_OK) sendAuthRequest(port, AUTH_REQ_OK); else auth_failed(port, status); /* Done with authentication, so we should turn off immediate interrupts */ ImmediateInterruptOK = false; }
Definition at line 220 of file auth.c.
Referenced by _PG_init(), ClientAuthentication(), and sepgsql_init_client_label().
char* pg_krb_realm |
char* pg_krb_server_hostname |
char* pg_krb_server_keyfile |
char* pg_krb_srvnam |