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 343 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().

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

Variable Documentation

◆ ClientAuthentication_hook

PGDLLIMPORT ClientAuthentication_hook_type ClientAuthentication_hook

Definition at line 239 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 167 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 166 of file auth.c.

Referenced by CheckSCRAMAuth(), and secure_open_gssapi().