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 void *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 379 of file auth.c.

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

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 void *  extradata,
int  extralen 
)

Definition at line 677 of file auth.c.

678{
680
682
684 pq_sendint32(&buf, (int32) areq);
685 if (extralen > 0)
686 pq_sendbytes(&buf, extradata, extralen);
687
689
690 /*
691 * Flush message so client will see it, except for AUTH_REQ_OK and
692 * AUTH_REQ_SASL_FIN, which need not be sent until we are ready for
693 * queries.
694 */
695 if (areq != AUTH_REQ_OK && areq != AUTH_REQ_SASL_FIN)
696 pq_flush();
697
699}
int32_t int32
Definition: c.h:537
#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:108

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

342{
343 Assert(id);
344
346 {
347 /*
348 * An existing authn_id should never be overwritten; that means two
349 * authentication providers are fighting (or one is fighting itself).
350 * Don't leak any authn details to the client, but don't let the
351 * connection continue, either.
352 */
354 (errmsg("authentication identifier set more than once"),
355 errdetail_log("previous identifier: \"%s\"; new identifier: \"%s\"",
357 }
358
360 MyClientConnectionInfo.auth_method = port->hba->auth_method;
361
363 {
364 ereport(LOG,
365 errmsg("connection authenticated: identity=\"%s\" method=%s "
366 "(%s:%d)",
369 port->hba->sourcefile, port->hba->linenumber));
370 }
371}
int errdetail_log(const char *fmt,...)
Definition: elog.c:1264
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1746
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 223 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 175 of file auth.c.

Referenced by secure_open_gssapi().

◆ pg_krb_caseins_users

PGDLLIMPORT bool pg_krb_caseins_users
extern

Definition at line 174 of file auth.c.

◆ pg_krb_server_keyfile

PGDLLIMPORT char* pg_krb_server_keyfile
extern

Definition at line 173 of file auth.c.

Referenced by secure_open_gssapi().