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

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  /*
386  * Now proceed to do the actual authentication check
387  */
388  switch (port->hba->auth_method)
389  {
390  case uaReject:
391 
392  /*
393  * An explicit "reject" entry in pg_hba.conf. This report exposes
394  * the fact that there's an explicit reject entry, which is
395  * perhaps not so desirable from a security standpoint; but the
396  * message for an implicit reject could confuse the DBA a lot when
397  * the true situation is a match to an explicit reject. And we
398  * don't want to change the message for an implicit reject. As
399  * noted below, the additional information shown here doesn't
400  * expose anything not known to an attacker.
401  */
402  {
403  char hostinfo[NI_MAXHOST];
404  const char *encryption_state;
405 
406  pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
407  hostinfo, sizeof(hostinfo),
408  NULL, 0,
410 
411  encryption_state =
412 #ifdef ENABLE_GSS
413  (port->gss && port->gss->enc) ? _("GSS encryption") :
414 #endif
415 #ifdef USE_SSL
416  port->ssl_in_use ? _("SSL encryption") :
417 #endif
418  _("no encryption");
419 
420  if (am_walsender)
421  ereport(FATAL,
422  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
423  /* translator: last %s describes encryption state */
424  errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
425  hostinfo, port->user_name,
426  encryption_state)));
427  else
428  ereport(FATAL,
429  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
430  /* translator: last %s describes encryption state */
431  errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
432  hostinfo, port->user_name,
433  port->database_name,
434  encryption_state)));
435  break;
436  }
437 
438  case uaImplicitReject:
439 
440  /*
441  * No matching entry, so tell the user we fell through.
442  *
443  * NOTE: the extra info reported here is not a security breach,
444  * because all that info is known at the frontend and must be
445  * assumed known to bad guys. We're merely helping out the less
446  * clueful good guys.
447  */
448  {
449  char hostinfo[NI_MAXHOST];
450  const char *encryption_state;
451 
452  pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
453  hostinfo, sizeof(hostinfo),
454  NULL, 0,
456 
457  encryption_state =
458 #ifdef ENABLE_GSS
459  (port->gss && port->gss->enc) ? _("GSS encryption") :
460 #endif
461 #ifdef USE_SSL
462  port->ssl_in_use ? _("SSL encryption") :
463 #endif
464  _("no encryption");
465 
466 #define HOSTNAME_LOOKUP_DETAIL(port) \
467  (port->remote_hostname ? \
468  (port->remote_hostname_resolv == +1 ? \
469  errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \
470  port->remote_hostname) : \
471  port->remote_hostname_resolv == 0 ? \
472  errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", \
473  port->remote_hostname) : \
474  port->remote_hostname_resolv == -1 ? \
475  errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", \
476  port->remote_hostname) : \
477  port->remote_hostname_resolv == -2 ? \
478  errdetail_log("Could not translate client host name \"%s\" to IP address: %s.", \
479  port->remote_hostname, \
480  gai_strerror(port->remote_hostname_errcode)) : \
481  0) \
482  : (port->remote_hostname_resolv == -2 ? \
483  errdetail_log("Could not resolve client IP address to a host name: %s.", \
484  gai_strerror(port->remote_hostname_errcode)) : \
485  0))
486 
487  if (am_walsender)
488  ereport(FATAL,
489  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
490  /* translator: last %s describes encryption state */
491  errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
492  hostinfo, port->user_name,
493  encryption_state),
494  HOSTNAME_LOOKUP_DETAIL(port)));
495  else
496  ereport(FATAL,
497  (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
498  /* translator: last %s describes encryption state */
499  errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
500  hostinfo, port->user_name,
501  port->database_name,
502  encryption_state),
503  HOSTNAME_LOOKUP_DETAIL(port)));
504  break;
505  }
506 
507  case uaGSS:
508 #ifdef ENABLE_GSS
509  /* We might or might not have the gss workspace already */
510  if (port->gss == NULL)
511  port->gss = (pg_gssinfo *)
513  sizeof(pg_gssinfo));
514  port->gss->auth = true;
515 
516  /*
517  * If GSS state was set up while enabling encryption, we can just
518  * check the client's principal. Otherwise, ask for it.
519  */
520  if (port->gss->enc)
521  status = pg_GSS_checkauth(port);
522  else
523  {
524  sendAuthRequest(port, AUTH_REQ_GSS, NULL, 0);
525  status = pg_GSS_recvauth(port);
526  }
527 #else
528  Assert(false);
529 #endif
530  break;
531 
532  case uaSSPI:
533 #ifdef ENABLE_SSPI
534  if (port->gss == NULL)
535  port->gss = (pg_gssinfo *)
537  sizeof(pg_gssinfo));
538  sendAuthRequest(port, AUTH_REQ_SSPI, NULL, 0);
539  status = pg_SSPI_recvauth(port);
540 #else
541  Assert(false);
542 #endif
543  break;
544 
545  case uaPeer:
546  status = auth_peer(port);
547  break;
548 
549  case uaIdent:
550  status = ident_inet(port);
551  break;
552 
553  case uaMD5:
554  case uaSCRAM:
555  status = CheckPWChallengeAuth(port, &logdetail);
556  break;
557 
558  case uaPassword:
559  status = CheckPasswordAuth(port, &logdetail);
560  break;
561 
562  case uaPAM:
563 #ifdef USE_PAM
564  status = CheckPAMAuth(port, port->user_name, "");
565 #else
566  Assert(false);
567 #endif /* USE_PAM */
568  break;
569 
570  case uaBSD:
571 #ifdef USE_BSD_AUTH
572  status = CheckBSDAuth(port, port->user_name);
573 #else
574  Assert(false);
575 #endif /* USE_BSD_AUTH */
576  break;
577 
578  case uaLDAP:
579 #ifdef USE_LDAP
580  status = CheckLDAPAuth(port);
581 #else
582  Assert(false);
583 #endif
584  break;
585  case uaRADIUS:
586  status = CheckRADIUSAuth(port);
587  break;
588  case uaCert:
589  /* uaCert will be treated as if clientcert=verify-full (uaTrust) */
590  case uaTrust:
591  status = STATUS_OK;
592  break;
593  }
594 
595  if ((status == STATUS_OK && port->hba->clientcert == clientCertFull)
596  || port->hba->auth_method == uaCert)
597  {
598  /*
599  * Make sure we only check the certificate if we use the cert method
600  * or verify-full option.
601  */
602 #ifdef USE_SSL
603  status = CheckCertAuth(port);
604 #else
605  Assert(false);
606 #endif
607  }
608 
610  (*ClientAuthentication_hook) (port, status);
611 
612  if (status == STATUS_OK)
613  sendAuthRequest(port, AUTH_REQ_OK, NULL, 0);
614  else
615  auth_failed(port, status, logdetail);
616 }
#define HOSTNAME_LOOKUP_DETAIL(port)
Definition: hba.h:30
#define AUTH_REQ_SSPI
Definition: pqcomm.h:183
static int auth_peer(hbaPort *port)
Definition: auth.c:1971
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:623
#define AUTH_REQ_OK
Definition: pqcomm.h:174
#define AUTH_REQ_GSS
Definition: pqcomm.h:181
Definition: hba.h:35
bool peer_cert_valid
Definition: libpq-be.h:193
struct sockaddr_storage addr
Definition: pqcomm.h:64
int errcode(int sqlerrcode)
Definition: elog.c:704
#define STATUS_ERROR
Definition: c.h:1159
bool ssl_in_use
Definition: libpq-be.h:191
static int CheckRADIUSAuth(Port *port)
Definition: auth.c:2962
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:776
#define FATAL
Definition: elog.h:54
Definition: hba.h:27
Definition: hba.h:29
void hba_getauthmethod(hbaPort *port)
Definition: hba.c:3109
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:1158
MemoryContext TopMemoryContext
Definition: mcxt.c:44
static int port
Definition: pg_regress.c:92
HbaLine * hba
Definition: libpq-be.h:155
static int ident_inet(hbaPort *port)
Definition: auth.c:1793
Definition: hba.h:33
static int CheckPasswordAuth(Port *port, char **logdetail)
Definition: auth.c:744
Definition: hba.h:37
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:840
#define ereport(elevel,...)
Definition: elog.h:155
#define Assert(condition)
Definition: c.h:792
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:103
bool secure_loaded_verify_locations(void)
Definition: be-secure.c:101
void * gss
Definition: libpq-be.h:185
int errmsg(const char *fmt,...)
Definition: elog.c:915
static void auth_failed(Port *port, int status, char *logdetail)
Definition: auth.c:257
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:100
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:89
Definition: hba.h:40
UserAuth auth_method
Definition: hba.h:87

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