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.

Macros

#define PG_MAX_AUTH_TOKEN_LENGTH   65535
 

Typedefs

typedef void(* ClientAuthentication_hook_type) (Port *, int)
 
typedef char *(* auth_password_hook_typ) (char *input)
 

Functions

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

Variables

PGDLLIMPORT char * pg_krb_server_keyfile
 
PGDLLIMPORT bool pg_krb_caseins_users
 
PGDLLIMPORT bool pg_gss_accept_delegation
 
PGDLLIMPORT ClientAuthentication_hook_type ClientAuthentication_hook
 
PGDLLIMPORT auth_password_hook_typ ldap_password_hook
 

Macro Definition Documentation

◆ PG_MAX_AUTH_TOKEN_LENGTH

#define PG_MAX_AUTH_TOKEN_LENGTH   65535

Definition at line 33 of file auth.h.

Typedef Documentation

◆ auth_password_hook_typ

typedef char *(* auth_password_hook_typ) (char *input)

Definition at line 49 of file auth.h.

◆ ClientAuthentication_hook_type

typedef void(* ClientAuthentication_hook_type) (Port *, int)

Definition at line 45 of file auth.h.

Function Documentation

◆ ClientAuthentication()

void ClientAuthentication ( Port port)

Definition at line 371 of file auth.c.

372{
373 int status = STATUS_ERROR;
374 const char *logdetail = NULL;
375
376 /*
377 * Get the authentication method to use for this frontend/database
378 * combination. Note: we do not parse the file at this point; this has
379 * already been done elsewhere. hba.c dropped an error message into the
380 * server logfile if parsing the hba config file failed.
381 */
383
385
386 /*
387 * This is the first point where we have access to the hba record for the
388 * current connection, so perform any verifications based on the hba
389 * options field that should be done *before* the authentication here.
390 */
391 if (port->hba->clientcert != clientCertOff)
392 {
393 /* If we haven't loaded a root certificate store, fail */
396 (errcode(ERRCODE_CONFIG_FILE_ERROR),
397 errmsg("client certificates can only be checked if a root certificate store is available")));
398
399 /*
400 * If we loaded a root certificate store, and if a certificate is
401 * present on the client, then it has been verified against our root
402 * certificate store, and the connection would have been aborted
403 * already if it didn't verify ok.
404 */
405 if (!port->peer_cert_valid)
407 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
408 errmsg("connection requires a valid client certificate")));
409 }
410
411 /*
412 * Now proceed to do the actual authentication check
413 */
414 switch (port->hba->auth_method)
415 {
416 case uaReject:
417
418 /*
419 * An explicit "reject" entry in pg_hba.conf. This report exposes
420 * the fact that there's an explicit reject entry, which is
421 * perhaps not so desirable from a security standpoint; but the
422 * message for an implicit reject could confuse the DBA a lot when
423 * the true situation is a match to an explicit reject. And we
424 * don't want to change the message for an implicit reject. As
425 * noted below, the additional information shown here doesn't
426 * expose anything not known to an attacker.
427 */
428 {
429 char hostinfo[NI_MAXHOST];
430 const char *encryption_state;
431
432 pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
433 hostinfo, sizeof(hostinfo),
434 NULL, 0,
435 NI_NUMERICHOST);
436
437 encryption_state =
438#ifdef ENABLE_GSS
439 (port->gss && port->gss->enc) ? _("GSS encryption") :
440#endif
441#ifdef USE_SSL
442 port->ssl_in_use ? _("SSL encryption") :
443#endif
444 _("no encryption");
445
448 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
449 /* translator: last %s describes encryption state */
450 errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
451 hostinfo, port->user_name,
452 encryption_state)));
453 else
455 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
456 /* translator: last %s describes encryption state */
457 errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
458 hostinfo, port->user_name,
459 port->database_name,
460 encryption_state)));
461 break;
462 }
463
464 case uaImplicitReject:
465
466 /*
467 * No matching entry, so tell the user we fell through.
468 *
469 * NOTE: the extra info reported here is not a security breach,
470 * because all that info is known at the frontend and must be
471 * assumed known to bad guys. We're merely helping out the less
472 * clueful good guys.
473 */
474 {
475 char hostinfo[NI_MAXHOST];
476 const char *encryption_state;
477
478 pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
479 hostinfo, sizeof(hostinfo),
480 NULL, 0,
481 NI_NUMERICHOST);
482
483 encryption_state =
484#ifdef ENABLE_GSS
485 (port->gss && port->gss->enc) ? _("GSS encryption") :
486#endif
487#ifdef USE_SSL
488 port->ssl_in_use ? _("SSL encryption") :
489#endif
490 _("no encryption");
491
492#define HOSTNAME_LOOKUP_DETAIL(port) \
493 (port->remote_hostname ? \
494 (port->remote_hostname_resolv == +1 ? \
495 errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \
496 port->remote_hostname) : \
497 port->remote_hostname_resolv == 0 ? \
498 errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", \
499 port->remote_hostname) : \
500 port->remote_hostname_resolv == -1 ? \
501 errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", \
502 port->remote_hostname) : \
503 port->remote_hostname_resolv == -2 ? \
504 errdetail_log("Could not translate client host name \"%s\" to IP address: %s.", \
505 port->remote_hostname, \
506 gai_strerror(port->remote_hostname_errcode)) : \
507 0) \
508 : (port->remote_hostname_resolv == -2 ? \
509 errdetail_log("Could not resolve client IP address to a host name: %s.", \
510 gai_strerror(port->remote_hostname_errcode)) : \
511 0))
512
515 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
516 /* translator: last %s describes encryption state */
517 errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
518 hostinfo, port->user_name,
519 encryption_state),
521 else
523 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
524 /* translator: last %s describes encryption state */
525 errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
526 hostinfo, port->user_name,
527 port->database_name,
528 encryption_state),
530 break;
531 }
532
533 case uaGSS:
534#ifdef ENABLE_GSS
535 /* We might or might not have the gss workspace already */
536 if (port->gss == NULL)
537 port->gss = (pg_gssinfo *)
539 sizeof(pg_gssinfo));
540 port->gss->auth = true;
541
542 /*
543 * If GSS state was set up while enabling encryption, we can just
544 * check the client's principal. Otherwise, ask for it.
545 */
546 if (port->gss->enc)
547 status = pg_GSS_checkauth(port);
548 else
549 {
551 status = pg_GSS_recvauth(port);
552 }
553#else
554 Assert(false);
555#endif
556 break;
557
558 case uaSSPI:
559#ifdef ENABLE_SSPI
560 if (port->gss == NULL)
561 port->gss = (pg_gssinfo *)
563 sizeof(pg_gssinfo));
565 status = pg_SSPI_recvauth(port);
566#else
567 Assert(false);
568#endif
569 break;
570
571 case uaPeer:
572 status = auth_peer(port);
573 break;
574
575 case uaIdent:
576 status = ident_inet(port);
577 break;
578
579 case uaMD5:
580 case uaSCRAM:
581 status = CheckPWChallengeAuth(port, &logdetail);
582 break;
583
584 case uaPassword:
585 status = CheckPasswordAuth(port, &logdetail);
586 break;
587
588 case uaPAM:
589#ifdef USE_PAM
590 status = CheckPAMAuth(port, port->user_name, "");
591#else
592 Assert(false);
593#endif /* USE_PAM */
594 break;
595
596 case uaBSD:
597#ifdef USE_BSD_AUTH
598 status = CheckBSDAuth(port, port->user_name);
599#else
600 Assert(false);
601#endif /* USE_BSD_AUTH */
602 break;
603
604 case uaLDAP:
605#ifdef USE_LDAP
606 status = CheckLDAPAuth(port);
607#else
608 Assert(false);
609#endif
610 break;
611 case uaRADIUS:
612 status = CheckRADIUSAuth(port);
613 break;
614 case uaCert:
615 /* uaCert will be treated as if clientcert=verify-full (uaTrust) */
616 case uaTrust:
617 status = STATUS_OK;
618 break;
619 case uaOAuth:
620 status = CheckSASLAuth(&pg_be_oauth_mech, port, NULL, NULL);
621 break;
622 }
623
624 if ((status == STATUS_OK && port->hba->clientcert == clientCertFull)
625 || port->hba->auth_method == uaCert)
626 {
627 /*
628 * Make sure we only check the certificate if we use the cert method
629 * or verify-full option.
630 */
631#ifdef USE_SSL
632 status = CheckCertAuth(port);
633#else
634 Assert(false);
635#endif
636 }
637
639 status == STATUS_OK &&
641 {
642 /*
643 * Normally, if log_connections is set, the call to set_authn_id()
644 * will log the connection. However, if that function is never
645 * called, perhaps because the trust method is in use, then we handle
646 * the logging here instead.
647 */
648 ereport(LOG,
649 errmsg("connection authenticated: user=\"%s\" method=%s "
650 "(%s:%d)",
651 port->user_name, hba_authname(port->hba->auth_method),
652 port->hba->sourcefile, port->hba->linenumber));
653 }
654
656 (*ClientAuthentication_hook) (port, status);
657
658 if (status == STATUS_OK)
660 else
661 auth_failed(port, status, logdetail);
662}
const pg_be_sasl_mech pg_be_oauth_mech
Definition: auth-oauth.c:48
int CheckSASLAuth(const pg_be_sasl_mech *mech, Port *port, char *shadow_pass, const char **logdetail)
Definition: auth-sasl.c:44
void sendAuthRequest(Port *port, AuthRequest areq, const char *extradata, int extralen)
Definition: auth.c:669
static int CheckPWChallengeAuth(Port *port, const char **logdetail)
Definition: auth.c:815
static int ident_inet(hbaPort *port)
Definition: auth.c:1663
static int CheckRADIUSAuth(Port *port)
Definition: auth.c:2837
static void auth_failed(Port *port, int status, const char *logdetail)
Definition: auth.c:231
ClientAuthentication_hook_type ClientAuthentication_hook
Definition: auth.c:215
static int auth_peer(hbaPort *port)
Definition: auth.c:1848
#define HOSTNAME_LOOKUP_DETAIL(port)
static int CheckPasswordAuth(Port *port, const char **logdetail)
Definition: auth.c:780
uint32 log_connections
@ LOG_CONNECTION_AUTHENTICATION
bool secure_loaded_verify_locations(void)
Definition: be-secure.c:99
#define STATUS_OK
Definition: c.h:1140
#define STATUS_ERROR
Definition: c.h:1141
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define _(x)
Definition: elog.c:91
#define LOG
Definition: elog.h:31
#define FATAL
Definition: elog.h:41
#define ereport(elevel,...)
Definition: elog.h:149
Assert(PointerIsAligned(start, uint64))
void hba_getauthmethod(hbaPort *port)
Definition: hba.c:3110
const char * hba_authname(UserAuth auth_method)
Definition: hba.c:3123
@ uaBSD
Definition: hba.h:37
@ uaLDAP
Definition: hba.h:38
@ uaPeer
Definition: hba.h:41
@ 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
@ uaOAuth
Definition: hba.h:42
@ uaTrust
Definition: hba.h:29
@ uaSSPI
Definition: hba.h:35
@ clientCertOff
Definition: hba.h:70
@ clientCertFull
Definition: hba.h:72
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:114
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1294
MemoryContext TopMemoryContext
Definition: mcxt.c:165
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:123
ClientConnectionInfo MyClientConnectionInfo
Definition: miscinit.c:1069
static int port
Definition: pg_regress.c:115
#define AUTH_REQ_SSPI
Definition: protocol.h:83
#define AUTH_REQ_GSS
Definition: protocol.h:81
#define AUTH_REQ_OK
Definition: protocol.h:74
const char * authn_id
Definition: libpq-be.h:99
bool am_walsender
Definition: walsender.c:120
bool am_db_walsender
Definition: walsender.c:123

References _, am_db_walsender, am_walsender, Assert(), auth_failed(), auth_peer(), AUTH_REQ_GSS, AUTH_REQ_OK, AUTH_REQ_SSPI, ClientConnectionInfo::authn_id, CHECK_FOR_INTERRUPTS, CheckPasswordAuth(), CheckPWChallengeAuth(), CheckRADIUSAuth(), CheckSASLAuth(), ClientAuthentication_hook, clientCertFull, clientCertOff, ereport, errcode(), errmsg(), FATAL, hba_authname(), hba_getauthmethod(), HOSTNAME_LOOKUP_DETAIL, ident_inet(), LOG, LOG_CONNECTION_AUTHENTICATION, log_connections, MemoryContextAllocZero(), MyClientConnectionInfo, pg_be_oauth_mech, pg_getnameinfo_all(), port, secure_loaded_verify_locations(), sendAuthRequest(), STATUS_ERROR, STATUS_OK, TopMemoryContext, uaBSD, uaCert, uaGSS, uaIdent, uaImplicitReject, uaLDAP, uaMD5, uaOAuth, uaPAM, uaPassword, uaPeer, uaRADIUS, uaReject, uaSCRAM, uaSSPI, and uaTrust.

Referenced by PerformAuthentication().

◆ sendAuthRequest()

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

Definition at line 669 of file auth.c.

670{
672
674
676 pq_sendint32(&buf, (int32) areq);
677 if (extralen > 0)
678 pq_sendbytes(&buf, extradata, extralen);
679
681
682 /*
683 * Flush message so client will see it, except for AUTH_REQ_OK and
684 * AUTH_REQ_SASL_FIN, which need not be sent until we are ready for
685 * queries.
686 */
687 if (areq != AUTH_REQ_OK && areq != AUTH_REQ_SASL_FIN)
688 pq_flush();
689
691}
int32_t int32
Definition: c.h:498
#define pq_flush()
Definition: libpq.h:46
static char * buf
Definition: pg_test_fsync.c:72
void pq_sendbytes(StringInfo buf, const void *data, int datalen)
Definition: pqformat.c:126
void pq_endmessage(StringInfo buf)
Definition: pqformat.c:296
void pq_beginmessage(StringInfo buf, char msgtype)
Definition: pqformat.c:88
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:144
#define PqMsg_AuthenticationRequest
Definition: protocol.h:50
#define AUTH_REQ_SASL_FIN
Definition: protocol.h:86

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

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

◆ set_authn_id()

void set_authn_id ( Port port,
const char *  id 
)

Definition at line 333 of file auth.c.

334{
335 Assert(id);
336
338 {
339 /*
340 * An existing authn_id should never be overwritten; that means two
341 * authentication providers are fighting (or one is fighting itself).
342 * Don't leak any authn details to the client, but don't let the
343 * connection continue, either.
344 */
346 (errmsg("authentication identifier set more than once"),
347 errdetail_log("previous identifier: \"%s\"; new identifier: \"%s\"",
349 }
350
352 MyClientConnectionInfo.auth_method = port->hba->auth_method;
353
355 {
356 ereport(LOG,
357 errmsg("connection authenticated: identity=\"%s\" method=%s "
358 "(%s:%d)",
361 port->hba->sourcefile, port->hba->linenumber));
362 }
363}
int errdetail_log(const char *fmt,...)
Definition: elog.c:1252
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:2312
UserAuth auth_method
Definition: libpq-be.h:105

References Assert(), ClientConnectionInfo::auth_method, ClientConnectionInfo::authn_id, ereport, errdetail_log(), errmsg(), FATAL, hba_authname(), LOG, LOG_CONNECTION_AUTHENTICATION, log_connections, MemoryContextStrdup(), MyClientConnectionInfo, port, and TopMemoryContext.

Referenced by auth_peer(), CheckPasswordAuth(), CheckPWChallengeAuth(), CheckRADIUSAuth(), ident_inet(), and validate().

Variable Documentation

◆ ClientAuthentication_hook

PGDLLIMPORT ClientAuthentication_hook_type ClientAuthentication_hook
extern

Definition at line 215 of file auth.c.

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

◆ ldap_password_hook

PGDLLIMPORT auth_password_hook_typ ldap_password_hook
extern

Referenced by _PG_init().

◆ pg_gss_accept_delegation

PGDLLIMPORT bool pg_gss_accept_delegation
extern

Definition at line 167 of file auth.c.

Referenced by secure_open_gssapi().

◆ pg_krb_caseins_users

PGDLLIMPORT bool pg_krb_caseins_users
extern

Definition at line 166 of file auth.c.

◆ pg_krb_server_keyfile

PGDLLIMPORT char* pg_krb_server_keyfile
extern

Definition at line 165 of file auth.c.

Referenced by secure_open_gssapi().