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)
 
void sendAuthRequest (Port *port, AuthRequest areq, const char *extradata, int extralen)
 

Variables

PGDLLIMPORT char * pg_krb_server_keyfile
 
PGDLLIMPORT bool pg_krb_caseins_users
 
PGDLLIMPORT 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 28 of file auth.h.

Function Documentation

◆ ClientAuthentication()

void ClientAuthentication ( Port port)

Definition at line 385 of file auth.c.

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

References _, am_db_walsender, am_walsender, Assert(), auth_failed(), auth_peer(), AUTH_REQ_GSS, AUTH_REQ_OK, AUTH_REQ_SSPI, CHECK_FOR_INTERRUPTS, CheckPasswordAuth(), CheckPWChallengeAuth(), CheckRADIUSAuth(), ClientAuthentication_hook, clientCertFull, clientCertOff, ereport, errcode(), errmsg(), FATAL, hba_getauthmethod(), HOSTNAME_LOOKUP_DETAIL, ident_inet(), MemoryContextAllocZero(), NI_MAXHOST, NI_NUMERICHOST, pg_getnameinfo_all(), port, secure_loaded_verify_locations(), sendAuthRequest(), status(), STATUS_ERROR, STATUS_OK, TopMemoryContext, uaBSD, uaCert, uaGSS, uaIdent, uaImplicitReject, uaLDAP, uaMD5, uaPAM, uaPassword, uaRADIUS, uaReject, uaSCRAM, uaSSPI, and uaTrust.

Referenced by PerformAuthentication().

◆ sendAuthRequest()

void sendAuthRequest ( Port port,
AuthRequest  areq,
const char *  extradata,
int  extralen 
)

Definition at line 663 of file auth.c.

664 {
666 
668 
669  pq_beginmessage(&buf, 'R');
670  pq_sendint32(&buf, (int32) areq);
671  if (extralen > 0)
672  pq_sendbytes(&buf, extradata, extralen);
673 
674  pq_endmessage(&buf);
675 
676  /*
677  * Flush message so client will see it, except for AUTH_REQ_OK and
678  * AUTH_REQ_SASL_FIN, which need not be sent until we are ready for
679  * queries.
680  */
681  if (areq != AUTH_REQ_OK && areq != AUTH_REQ_SASL_FIN)
682  pq_flush();
683 
685 }
signed int int32
Definition: c.h:440
#define pq_flush()
Definition: libpq.h:46
static char * buf
Definition: pg_test_fsync.c:67
#define AUTH_REQ_SASL_FIN
Definition: pqcomm.h:163
void pq_endmessage(StringInfo buf)
Definition: pqformat.c:298
void pq_beginmessage(StringInfo buf, char msgtype)
Definition: pqformat.c:87
void pq_sendbytes(StringInfo buf, const char *data, int datalen)
Definition: pqformat.c:125
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145

References AUTH_REQ_OK, AUTH_REQ_SASL_FIN, buf, CHECK_FOR_INTERRUPTS, pq_beginmessage(), pq_endmessage(), pq_flush, pq_sendbytes(), and pq_sendint32().

Referenced by CheckMD5Auth(), CheckPasswordAuth(), CheckRADIUSAuth(), CheckSASLAuth(), and ClientAuthentication().

Variable Documentation

◆ ClientAuthentication_hook

PGDLLIMPORT ClientAuthentication_hook_type ClientAuthentication_hook
extern

Definition at line 236 of file auth.c.

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

◆ pg_krb_caseins_users

PGDLLIMPORT bool pg_krb_caseins_users
extern

Definition at line 172 of file auth.c.

◆ pg_krb_realm

PGDLLIMPORT char* pg_krb_realm
extern

◆ pg_krb_server_keyfile

PGDLLIMPORT char* pg_krb_server_keyfile
extern

Definition at line 171 of file auth.c.

Referenced by secure_open_gssapi().