PostgreSQL Source Code  git master
auth.h File Reference
#include "libpq/libpq-be.h"
Include dependency graph for auth.h:
This graph shows which files directly or indirectly include this file:

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
 
bool pg_krb_caseins_users
 
char * pg_krb_realm
 
PGDLLIMPORT ClientAuthentication_hook_type ClientAuthentication_hook
 

Typedef Documentation

◆ ClientAuthentication_hook_type

typedef void(* ClientAuthentication_hook_type) (Port *, int)

Definition at line 26 of file auth.h.

Function Documentation

◆ ClientAuthentication()

void ClientAuthentication ( Port port)

Definition at line 394 of file auth.c.

References _, SockAddr::addr, am_db_walsender, am_walsender, Assert, auth_failed(), HbaLine::auth_method, auth_peer(), AUTH_REQ_GSS, AUTH_REQ_OK, AUTH_REQ_SSPI, CHECK_FOR_INTERRUPTS, CheckPasswordAuth(), CheckPWChallengeAuth(), CheckRADIUSAuth(), ClientAuthentication_hook, HbaLine::clientcert, clientCertFull, clientCertOff, Port::database_name, ereport, errcode(), errmsg(), FATAL, Port::gss, Port::hba, hba_getauthmethod(), HOSTNAME_LOOKUP_DETAIL, ident_inet(), MemoryContextAllocZero(), NI_MAXHOST, NI_NUMERICHOST, Port::peer_cert_valid, pg_getnameinfo_all(), port, Port::raddr, SockAddr::salen, secure_loaded_verify_locations(), sendAuthRequest(), Port::ssl_in_use, status(), STATUS_ERROR, STATUS_OK, TopMemoryContext, uaBSD, uaCert, uaGSS, uaIdent, uaImplicitReject, uaLDAP, uaMD5, uaPAM, uaPassword, uaRADIUS, uaReject, uaSCRAM, uaSSPI, uaTrust, and Port::user_name.

Referenced by PerformAuthentication().

395 {
396  int status = STATUS_ERROR;
397  char *logdetail = NULL;
398 
399  /*
400  * Get the authentication method to use for this frontend/database
401  * combination. Note: we do not parse the file at this point; this has
402  * already been done elsewhere. hba.c dropped an error message into the
403  * server logfile if parsing the hba config file failed.
404  */
405  hba_getauthmethod(port);
406 
408 
409  /*
410  * This is the first point where we have access to the hba record for the
411  * current connection, so perform any verifications based on the hba
412  * options field that should be done *before* the authentication here.
413  */
414  if (port->hba->clientcert != clientCertOff)
415  {
416  /* If we haven't loaded a root certificate store, fail */
418  ereport(FATAL,
419  (errcode(ERRCODE_CONFIG_FILE_ERROR),
420  errmsg("client certificates can only be checked if a root certificate store is available")));
421 
422  /*
423  * If we loaded a root certificate store, and if a certificate is
424  * present on the client, then it has been verified against our root
425  * certificate store, and the connection would have been aborted
426  * already if it didn't verify ok.
427  */
428  if (!port->peer_cert_valid)
429  ereport(FATAL,
430  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
431  errmsg("connection requires a valid client certificate")));
432  }
433 
434  /*
435  * Now proceed to do the actual authentication check
436  */
437  switch (port->hba->auth_method)
438  {
439  case uaReject:
440 
441  /*
442  * An explicit "reject" entry in pg_hba.conf. This report exposes
443  * the fact that there's an explicit reject entry, which is
444  * perhaps not so desirable from a security standpoint; but the
445  * message for an implicit reject could confuse the DBA a lot when
446  * the true situation is a match to an explicit reject. And we
447  * don't want to change the message for an implicit reject. As
448  * noted below, the additional information shown here doesn't
449  * expose anything not known to an attacker.
450  */
451  {
452  char hostinfo[NI_MAXHOST];
453  const char *encryption_state;
454 
455  pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
456  hostinfo, sizeof(hostinfo),
457  NULL, 0,
459 
460  encryption_state =
461 #ifdef ENABLE_GSS
462  (port->gss && port->gss->enc) ? _("GSS encryption") :
463 #endif
464 #ifdef USE_SSL
465  port->ssl_in_use ? _("SSL encryption") :
466 #endif
467  _("no encryption");
468 
470  ereport(FATAL,
471  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
472  /* translator: last %s describes encryption state */
473  errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
474  hostinfo, port->user_name,
475  encryption_state)));
476  else
477  ereport(FATAL,
478  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
479  /* translator: last %s describes encryption state */
480  errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
481  hostinfo, port->user_name,
482  port->database_name,
483  encryption_state)));
484  break;
485  }
486 
487  case uaImplicitReject:
488 
489  /*
490  * No matching entry, so tell the user we fell through.
491  *
492  * NOTE: the extra info reported here is not a security breach,
493  * because all that info is known at the frontend and must be
494  * assumed known to bad guys. We're merely helping out the less
495  * clueful good guys.
496  */
497  {
498  char hostinfo[NI_MAXHOST];
499  const char *encryption_state;
500 
501  pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
502  hostinfo, sizeof(hostinfo),
503  NULL, 0,
505 
506  encryption_state =
507 #ifdef ENABLE_GSS
508  (port->gss && port->gss->enc) ? _("GSS encryption") :
509 #endif
510 #ifdef USE_SSL
511  port->ssl_in_use ? _("SSL encryption") :
512 #endif
513  _("no encryption");
514 
515 #define HOSTNAME_LOOKUP_DETAIL(port) \
516  (port->remote_hostname ? \
517  (port->remote_hostname_resolv == +1 ? \
518  errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \
519  port->remote_hostname) : \
520  port->remote_hostname_resolv == 0 ? \
521  errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", \
522  port->remote_hostname) : \
523  port->remote_hostname_resolv == -1 ? \
524  errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", \
525  port->remote_hostname) : \
526  port->remote_hostname_resolv == -2 ? \
527  errdetail_log("Could not translate client host name \"%s\" to IP address: %s.", \
528  port->remote_hostname, \
529  gai_strerror(port->remote_hostname_errcode)) : \
530  0) \
531  : (port->remote_hostname_resolv == -2 ? \
532  errdetail_log("Could not resolve client IP address to a host name: %s.", \
533  gai_strerror(port->remote_hostname_errcode)) : \
534  0))
535 
537  ereport(FATAL,
538  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
539  /* translator: last %s describes encryption state */
540  errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
541  hostinfo, port->user_name,
542  encryption_state),
543  HOSTNAME_LOOKUP_DETAIL(port)));
544  else
545  ereport(FATAL,
546  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
547  /* translator: last %s describes encryption state */
548  errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
549  hostinfo, port->user_name,
550  port->database_name,
551  encryption_state),
552  HOSTNAME_LOOKUP_DETAIL(port)));
553  break;
554  }
555 
556  case uaGSS:
557 #ifdef ENABLE_GSS
558  /* We might or might not have the gss workspace already */
559  if (port->gss == NULL)
560  port->gss = (pg_gssinfo *)
562  sizeof(pg_gssinfo));
563  port->gss->auth = true;
564 
565  /*
566  * If GSS state was set up while enabling encryption, we can just
567  * check the client's principal. Otherwise, ask for it.
568  */
569  if (port->gss->enc)
570  status = pg_GSS_checkauth(port);
571  else
572  {
573  sendAuthRequest(port, AUTH_REQ_GSS, NULL, 0);
574  status = pg_GSS_recvauth(port);
575  }
576 #else
577  Assert(false);
578 #endif
579  break;
580 
581  case uaSSPI:
582 #ifdef ENABLE_SSPI
583  if (port->gss == NULL)
584  port->gss = (pg_gssinfo *)
586  sizeof(pg_gssinfo));
587  sendAuthRequest(port, AUTH_REQ_SSPI, NULL, 0);
588  status = pg_SSPI_recvauth(port);
589 #else
590  Assert(false);
591 #endif
592  break;
593 
594  case uaPeer:
595  status = auth_peer(port);
596  break;
597 
598  case uaIdent:
599  status = ident_inet(port);
600  break;
601 
602  case uaMD5:
603  case uaSCRAM:
604  status = CheckPWChallengeAuth(port, &logdetail);
605  break;
606 
607  case uaPassword:
608  status = CheckPasswordAuth(port, &logdetail);
609  break;
610 
611  case uaPAM:
612 #ifdef USE_PAM
613  status = CheckPAMAuth(port, port->user_name, "");
614 #else
615  Assert(false);
616 #endif /* USE_PAM */
617  break;
618 
619  case uaBSD:
620 #ifdef USE_BSD_AUTH
621  status = CheckBSDAuth(port, port->user_name);
622 #else
623  Assert(false);
624 #endif /* USE_BSD_AUTH */
625  break;
626 
627  case uaLDAP:
628 #ifdef USE_LDAP
629  status = CheckLDAPAuth(port);
630 #else
631  Assert(false);
632 #endif
633  break;
634  case uaRADIUS:
635  status = CheckRADIUSAuth(port);
636  break;
637  case uaCert:
638  /* uaCert will be treated as if clientcert=verify-full (uaTrust) */
639  case uaTrust:
640  status = STATUS_OK;
641  break;
642  }
643 
644  if ((status == STATUS_OK && port->hba->clientcert == clientCertFull)
645  || port->hba->auth_method == uaCert)
646  {
647  /*
648  * Make sure we only check the certificate if we use the cert method
649  * or verify-full option.
650  */
651 #ifdef USE_SSL
652  status = CheckCertAuth(port);
653 #else
654  Assert(false);
655 #endif
656  }
657 
659  (*ClientAuthentication_hook) (port, status);
660 
661  if (status == STATUS_OK)
662  sendAuthRequest(port, AUTH_REQ_OK, NULL, 0);
663  else
664  auth_failed(port, status, logdetail);
665 }
#define HOSTNAME_LOOKUP_DETAIL(port)
Definition: hba.h:30
#define AUTH_REQ_SSPI
Definition: pqcomm.h:160
static int auth_peer(hbaPort *port)
Definition: auth.c:2011
Definition: hba.h:38
#define NI_NUMERICHOST
Definition: getaddrinfo.h:78
Definition: hba.h:32
static void sendAuthRequest(Port *port, AuthRequest areq, const char *extradata, int extralen)
Definition: auth.c:672
#define AUTH_REQ_OK
Definition: pqcomm.h:151
#define AUTH_REQ_GSS
Definition: pqcomm.h:158
Definition: hba.h:35
bool peer_cert_valid
Definition: libpq-be.h:212
struct sockaddr_storage addr
Definition: pqcomm.h:64
int errcode(int sqlerrcode)
Definition: elog.c:698
#define STATUS_ERROR
Definition: c.h:1171
bool ssl_in_use
Definition: libpq-be.h:209
static int CheckRADIUSAuth(Port *port)
Definition: auth.c:3054
Definition: hba.h:34
Definition: hba.h:31
SockAddr raddr
Definition: libpq-be.h:131
bool am_walsender
Definition: walsender.c:115
#define NI_MAXHOST
Definition: getaddrinfo.h:88
Definition: hba.h:39
static int CheckPWChallengeAuth(Port *port, char **logdetail)
Definition: auth.c:818
#define FATAL
Definition: elog.h:49
Definition: hba.h:27
Definition: hba.h:29
void hba_getauthmethod(hbaPort *port)
Definition: hba.c:3134
ClientAuthentication_hook_type ClientAuthentication_hook
Definition: auth.c:245
char * user_name
Definition: libpq-be.h:146
ACCEPT_TYPE_ARG3 salen
Definition: pqcomm.h:65
#define STATUS_OK
Definition: c.h:1170
MemoryContext TopMemoryContext
Definition: mcxt.c:48
static int port
Definition: pg_regress.c:92
HbaLine * hba
Definition: libpq-be.h:160
static int ident_inet(hbaPort *port)
Definition: auth.c:1826
Definition: hba.h:33
bool am_db_walsender
Definition: walsender.c:118
static int CheckPasswordAuth(Port *port, char **logdetail)
Definition: auth.c:783
Definition: hba.h:37
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:906
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:122
ClientCertMode clientcert
Definition: hba.h:109
bool secure_loaded_verify_locations(void)
Definition: be-secure.c:102
void * gss
Definition: libpq-be.h:203
int errmsg(const char *fmt,...)
Definition: elog.c:909
static void auth_failed(Port *port, int status, char *logdetail)
Definition: auth.c:261
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:120
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:227
char * database_name
Definition: libpq-be.h:145
Definition: hba.h:36
#define _(x)
Definition: elog.c:89
Definition: hba.h:40
UserAuth auth_method
Definition: hba.h:93

Variable Documentation

◆ ClientAuthentication_hook

PGDLLIMPORT ClientAuthentication_hook_type ClientAuthentication_hook

Definition at line 245 of file auth.c.

Referenced by _PG_init(), ClientAuthentication(), and sepgsql_init_client_label().

◆ pg_krb_caseins_users

bool pg_krb_caseins_users

Definition at line 173 of file auth.c.

Referenced by CheckSCRAMAuth().

◆ pg_krb_realm

char* pg_krb_realm

◆ pg_krb_server_keyfile

char* pg_krb_server_keyfile

Definition at line 172 of file auth.c.

Referenced by CheckSCRAMAuth(), and secure_open_gssapi().