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

References _, SockAddr::addr, 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(), 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().

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

Variable Documentation

◆ ClientAuthentication_hook

PGDLLIMPORT ClientAuthentication_hook_type ClientAuthentication_hook

Definition at line 241 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 170 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 169 of file auth.c.

Referenced by CheckSCRAMAuth(), and secure_open_gssapi().