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 348 of file auth.c.

References _, SockAddr::addr, am_walsender, Assert, auth_failed(), HbaLine::auth_method, 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(), 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, uaBSD, uaCert, uaGSS, uaIdent, uaImplicitReject, uaLDAP, uaMD5, uaPAM, uaPassword, uaRADIUS, uaReject, uaSCRAM, uaSSPI, uaTrust, and Port::user_name.

Referenced by PerformAuthentication().

349 {
350  int status = STATUS_ERROR;
351  char *logdetail = NULL;
352 
353  /*
354  * Get the authentication method to use for this frontend/database
355  * combination. Note: we do not parse the file at this point; this has
356  * already been done elsewhere. hba.c dropped an error message into the
357  * server logfile if parsing the hba config file failed.
358  */
359  hba_getauthmethod(port);
360 
362 
363  /*
364  * This is the first point where we have access to the hba record for the
365  * current connection, so perform any verifications based on the hba
366  * options field that should be done *before* the authentication here.
367  */
368  if (port->hba->clientcert != clientCertOff)
369  {
370  /* If we haven't loaded a root certificate store, fail */
372  ereport(FATAL,
373  (errcode(ERRCODE_CONFIG_FILE_ERROR),
374  errmsg("client certificates can only be checked if a root certificate store is available")));
375 
376  /*
377  * If we loaded a root certificate store, and if a certificate is
378  * present on the client, then it has been verified against our root
379  * certificate store, and the connection would have been aborted
380  * already if it didn't verify ok.
381  */
382  if (!port->peer_cert_valid)
383  ereport(FATAL,
384  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
385  errmsg("connection requires a valid client certificate")));
386  }
387 
388 #ifdef ENABLE_GSS
389  if (port->gss->enc && port->hba->auth_method != uaReject &&
390  port->hba->auth_method != uaImplicitReject &&
391  port->hba->auth_method != uaTrust &&
392  port->hba->auth_method != uaGSS)
393  {
394  ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
395  errmsg("GSSAPI encryption can only be used with gss, trust, or reject authentication methods")));
396  }
397 #endif
398 
399  /*
400  * Now proceed to do the actual authentication check
401  */
402  switch (port->hba->auth_method)
403  {
404  case uaReject:
405 
406  /*
407  * An explicit "reject" entry in pg_hba.conf. This report exposes
408  * the fact that there's an explicit reject entry, which is
409  * perhaps not so desirable from a security standpoint; but the
410  * message for an implicit reject could confuse the DBA a lot when
411  * the true situation is a match to an explicit reject. And we
412  * don't want to change the message for an implicit reject. As
413  * noted below, the additional information shown here doesn't
414  * expose anything not known to an attacker.
415  */
416  {
417  char hostinfo[NI_MAXHOST];
418 
419  pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
420  hostinfo, sizeof(hostinfo),
421  NULL, 0,
423 
424  if (am_walsender)
425  {
426 #ifdef USE_SSL
427  ereport(FATAL,
428  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
429  errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
430  hostinfo, port->user_name,
431  port->ssl_in_use ? _("SSL on") : _("SSL off"))));
432 #else
433  ereport(FATAL,
434  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
435  errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"",
436  hostinfo, port->user_name)));
437 #endif
438  }
439  else
440  {
441 #ifdef USE_SSL
442  ereport(FATAL,
443  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
444  errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
445  hostinfo, port->user_name,
446  port->database_name,
447  port->ssl_in_use ? _("SSL on") : _("SSL off"))));
448 #else
449  ereport(FATAL,
450  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
451  errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"",
452  hostinfo, port->user_name,
453  port->database_name)));
454 #endif
455  }
456  break;
457  }
458 
459  case uaImplicitReject:
460 
461  /*
462  * No matching entry, so tell the user we fell through.
463  *
464  * NOTE: the extra info reported here is not a security breach,
465  * because all that info is known at the frontend and must be
466  * assumed known to bad guys. We're merely helping out the less
467  * clueful good guys.
468  */
469  {
470  char hostinfo[NI_MAXHOST];
471 
472  pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
473  hostinfo, sizeof(hostinfo),
474  NULL, 0,
476 
477 #define HOSTNAME_LOOKUP_DETAIL(port) \
478  (port->remote_hostname ? \
479  (port->remote_hostname_resolv == +1 ? \
480  errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \
481  port->remote_hostname) : \
482  port->remote_hostname_resolv == 0 ? \
483  errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", \
484  port->remote_hostname) : \
485  port->remote_hostname_resolv == -1 ? \
486  errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", \
487  port->remote_hostname) : \
488  port->remote_hostname_resolv == -2 ? \
489  errdetail_log("Could not translate client host name \"%s\" to IP address: %s.", \
490  port->remote_hostname, \
491  gai_strerror(port->remote_hostname_errcode)) : \
492  0) \
493  : (port->remote_hostname_resolv == -2 ? \
494  errdetail_log("Could not resolve client IP address to a host name: %s.", \
495  gai_strerror(port->remote_hostname_errcode)) : \
496  0))
497 
498  if (am_walsender)
499  {
500 #ifdef USE_SSL
501  ereport(FATAL,
502  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
503  errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
504  hostinfo, port->user_name,
505  port->ssl_in_use ? _("SSL on") : _("SSL off")),
506  HOSTNAME_LOOKUP_DETAIL(port)));
507 #else
508  ereport(FATAL,
509  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
510  errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"",
511  hostinfo, port->user_name),
512  HOSTNAME_LOOKUP_DETAIL(port)));
513 #endif
514  }
515  else
516  {
517 #ifdef USE_SSL
518  ereport(FATAL,
519  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
520  errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
521  hostinfo, port->user_name,
522  port->database_name,
523  port->ssl_in_use ? _("SSL on") : _("SSL off")),
524  HOSTNAME_LOOKUP_DETAIL(port)));
525 #else
526  ereport(FATAL,
527  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
528  errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"",
529  hostinfo, port->user_name,
530  port->database_name),
531  HOSTNAME_LOOKUP_DETAIL(port)));
532 #endif
533  }
534  break;
535  }
536 
537  case uaGSS:
538 #ifdef ENABLE_GSS
539  port->gss->auth = true;
540  if (port->gss->enc)
541  status = pg_GSS_checkauth(port);
542  else
543  {
544  sendAuthRequest(port, AUTH_REQ_GSS, NULL, 0);
545  status = pg_GSS_recvauth(port);
546  }
547 #else
548  Assert(false);
549 #endif
550  break;
551 
552  case uaSSPI:
553 #ifdef ENABLE_SSPI
554  sendAuthRequest(port, AUTH_REQ_SSPI, NULL, 0);
555  status = pg_SSPI_recvauth(port);
556 #else
557  Assert(false);
558 #endif
559  break;
560 
561  case uaPeer:
562 #ifdef HAVE_UNIX_SOCKETS
563  status = auth_peer(port);
564 #else
565  Assert(false);
566 #endif
567  break;
568 
569  case uaIdent:
570  status = ident_inet(port);
571  break;
572 
573  case uaMD5:
574  case uaSCRAM:
575  status = CheckPWChallengeAuth(port, &logdetail);
576  break;
577 
578  case uaPassword:
579  status = CheckPasswordAuth(port, &logdetail);
580  break;
581 
582  case uaPAM:
583 #ifdef USE_PAM
584  status = CheckPAMAuth(port, port->user_name, "");
585 #else
586  Assert(false);
587 #endif /* USE_PAM */
588  break;
589 
590  case uaBSD:
591 #ifdef USE_BSD_AUTH
592  status = CheckBSDAuth(port, port->user_name);
593 #else
594  Assert(false);
595 #endif /* USE_BSD_AUTH */
596  break;
597 
598  case uaLDAP:
599 #ifdef USE_LDAP
600  status = CheckLDAPAuth(port);
601 #else
602  Assert(false);
603 #endif
604  break;
605  case uaRADIUS:
606  status = CheckRADIUSAuth(port);
607  break;
608  case uaCert:
609  /* uaCert will be treated as if clientcert=verify-full (uaTrust) */
610  case uaTrust:
611  status = STATUS_OK;
612  break;
613  }
614 
615  if ((status == STATUS_OK && port->hba->clientcert == clientCertFull)
616  || port->hba->auth_method == uaCert)
617  {
618  /*
619  * Make sure we only check the certificate if we use the cert method
620  * or verify-full option.
621  */
622 #ifdef USE_SSL
623  status = CheckCertAuth(port);
624 #else
625  Assert(false);
626 #endif
627  }
628 
630  (*ClientAuthentication_hook) (port, status);
631 
632  if (status == STATUS_OK)
633  sendAuthRequest(port, AUTH_REQ_OK, NULL, 0);
634  else
635  auth_failed(port, status, logdetail);
636 }
#define HOSTNAME_LOOKUP_DETAIL(port)
Definition: hba.h:30
#define AUTH_REQ_SSPI
Definition: pqcomm.h:174
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:643
#define AUTH_REQ_OK
Definition: pqcomm.h:165
#define AUTH_REQ_GSS
Definition: pqcomm.h:172
Definition: hba.h:35
bool peer_cert_valid
Definition: libpq-be.h:192
struct sockaddr_storage addr
Definition: pqcomm.h:64
int errcode(int sqlerrcode)
Definition: elog.c:608
#define STATUS_ERROR
Definition: c.h:1121
bool ssl_in_use
Definition: libpq-be.h:190
static int CheckRADIUSAuth(Port *port)
Definition: auth.c:2971
Definition: hba.h:34
Definition: hba.h:31
SockAddr raddr
Definition: libpq-be.h:126
bool am_walsender
Definition: walsender.c:114
#define NI_MAXHOST
Definition: getaddrinfo.h:88
Definition: hba.h:39
static int CheckPWChallengeAuth(Port *port, char **logdetail)
Definition: auth.c:796
#define FATAL
Definition: elog.h:52
Definition: hba.h:27
Definition: hba.h:29
void hba_getauthmethod(hbaPort *port)
Definition: hba.c:3089
ClientAuthentication_hook_type ClientAuthentication_hook
Definition: auth.c:244
char * user_name
Definition: libpq-be.h:141
ACCEPT_TYPE_ARG3 salen
Definition: pqcomm.h:65
#define ereport(elevel, rest)
Definition: elog.h:141
#define STATUS_OK
Definition: c.h:1120
static int port
Definition: pg_regress.c:91
HbaLine * hba
Definition: libpq-be.h:155
static int ident_inet(hbaPort *port)
Definition: auth.c:1810
Definition: hba.h:33
static int CheckPasswordAuth(Port *port, char **logdetail)
Definition: auth.c:764
Definition: hba.h:37
#define Assert(condition)
Definition: c.h:739
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:98
bool secure_loaded_verify_locations(void)
Definition: be-secure.c:101
void * gss
Definition: libpq-be.h:184
int errmsg(const char *fmt,...)
Definition: elog.c:822
static void auth_failed(Port *port, int status, char *logdetail)
Definition: auth.c:260
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:226
char * database_name
Definition: libpq-be.h:140
Definition: hba.h:36
#define _(x)
Definition: elog.c:87
Definition: hba.h:40
UserAuth auth_method
Definition: hba.h:81

Variable Documentation

◆ ClientAuthentication_hook

PGDLLIMPORT ClientAuthentication_hook_type ClientAuthentication_hook

Definition at line 244 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 172 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 171 of file auth.c.

Referenced by CheckSCRAMAuth(), and secure_open_gssapi().