PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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 charpg_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)
extern

Definition at line 374 of file auth.c.

375{
376 int status = STATUS_ERROR;
377 const char *logdetail = NULL;
378
379 /*
380 * "Abandoned" is a SASL-specific state similar to STATUS_EOF, in that we
381 * don't want to generate any server logs. But it's caused by an in-band
382 * client action that requires a server response, not an out-of-band
383 * connection closure, so we can't just proc_exit() like we do with
384 * STATUS_EOF.
385 */
386 bool abandoned = false;
387
388 /*
389 * Get the authentication method to use for this frontend/database
390 * combination. Note: we do not parse the file at this point; this has
391 * already been done elsewhere. hba.c dropped an error message into the
392 * server logfile if parsing the hba config file failed.
393 */
395
397
398 /*
399 * This is the first point where we have access to the hba record for the
400 * current connection, so perform any verifications based on the hba
401 * options field that should be done *before* the authentication here.
402 */
403 if (port->hba->clientcert != clientCertOff)
404 {
405 /* If we haven't loaded a root certificate store, fail */
409 errmsg("client certificates can only be checked if a root certificate store is available")));
410
411 /*
412 * If we loaded a root certificate store, and if a certificate is
413 * present on the client, then it has been verified against our root
414 * certificate store, and the connection would have been aborted
415 * already if it didn't verify ok.
416 */
417 if (!port->peer_cert_valid)
420 errmsg("connection requires a valid client certificate")));
421 }
422
423 /*
424 * Now proceed to do the actual authentication check
425 */
426 switch (port->hba->auth_method)
427 {
428 case uaReject:
429
430 /*
431 * An explicit "reject" entry in pg_hba.conf. This report exposes
432 * the fact that there's an explicit reject entry, which is
433 * perhaps not so desirable from a security standpoint; but the
434 * message for an implicit reject could confuse the DBA a lot when
435 * the true situation is a match to an explicit reject. And we
436 * don't want to change the message for an implicit reject. As
437 * noted below, the additional information shown here doesn't
438 * expose anything not known to an attacker.
439 */
440 {
441 char hostinfo[NI_MAXHOST];
442 const char *encryption_state;
443
444 pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
445 hostinfo, sizeof(hostinfo),
446 NULL, 0,
448
450#ifdef ENABLE_GSS
451 (port->gss && port->gss->enc) ? _("GSS encryption") :
452#endif
453#ifdef USE_SSL
454 port->ssl_in_use ? _("SSL encryption") :
455#endif
456 _("no encryption");
457
461 /* translator: last %s describes encryption state */
462 errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
463 hostinfo, port->user_name,
465 else
468 /* translator: last %s describes encryption state */
469 errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
470 hostinfo, port->user_name,
471 port->database_name,
473 break;
474 }
475
476 case uaImplicitReject:
477
478 /*
479 * No matching entry, so tell the user we fell through.
480 *
481 * NOTE: the extra info reported here is not a security breach,
482 * because all that info is known at the frontend and must be
483 * assumed known to bad guys. We're merely helping out the less
484 * clueful good guys.
485 */
486 {
487 char hostinfo[NI_MAXHOST];
488 const char *encryption_state;
489
490 pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
491 hostinfo, sizeof(hostinfo),
492 NULL, 0,
494
496#ifdef ENABLE_GSS
497 (port->gss && port->gss->enc) ? _("GSS encryption") :
498#endif
499#ifdef USE_SSL
500 port->ssl_in_use ? _("SSL encryption") :
501#endif
502 _("no encryption");
503
504#define HOSTNAME_LOOKUP_DETAIL(port) \
505 (port->remote_hostname ? \
506 (port->remote_hostname_resolv == +1 ? \
507 errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \
508 port->remote_hostname) : \
509 port->remote_hostname_resolv == 0 ? \
510 errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", \
511 port->remote_hostname) : \
512 port->remote_hostname_resolv == -1 ? \
513 errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", \
514 port->remote_hostname) : \
515 port->remote_hostname_resolv == -2 ? \
516 errdetail_log("Could not translate client host name \"%s\" to IP address: %s.", \
517 port->remote_hostname, \
518 gai_strerror(port->remote_hostname_errcode)) : \
519 0) \
520 : (port->remote_hostname_resolv == -2 ? \
521 errdetail_log("Could not resolve client IP address to a host name: %s.", \
522 gai_strerror(port->remote_hostname_errcode)) : \
523 0))
524
528 /* translator: last %s describes encryption state */
529 errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
530 hostinfo, port->user_name,
533 else
536 /* translator: last %s describes encryption state */
537 errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
538 hostinfo, port->user_name,
539 port->database_name,
542 break;
543 }
544
545 case uaGSS:
546#ifdef ENABLE_GSS
547 /* We might or might not have the gss workspace already */
548 if (port->gss == NULL)
549 port->gss = (pg_gssinfo *)
551 sizeof(pg_gssinfo));
552 port->gss->auth = true;
553
554 /*
555 * If GSS state was set up while enabling encryption, we can just
556 * check the client's principal. Otherwise, ask for it.
557 */
558 if (port->gss->enc)
559 status = pg_GSS_checkauth(port);
560 else
561 {
563 status = pg_GSS_recvauth(port);
564 }
565#else
566 Assert(false);
567#endif
568 break;
569
570 case uaSSPI:
571#ifdef ENABLE_SSPI
572 if (port->gss == NULL)
573 port->gss = (pg_gssinfo *)
575 sizeof(pg_gssinfo));
577 status = pg_SSPI_recvauth(port);
578#else
579 Assert(false);
580#endif
581 break;
582
583 case uaPeer:
584 status = auth_peer(port);
585 break;
586
587 case uaIdent:
588 status = ident_inet(port);
589 break;
590
591 case uaMD5:
592 case uaSCRAM:
593 status = CheckPWChallengeAuth(port, &logdetail);
594 break;
595
596 case uaPassword:
597 status = CheckPasswordAuth(port, &logdetail);
598 break;
599
600 case uaPAM:
601#ifdef USE_PAM
602 status = CheckPAMAuth(port, port->user_name, "");
603#else
604 Assert(false);
605#endif /* USE_PAM */
606 break;
607
608 case uaBSD:
609#ifdef USE_BSD_AUTH
610 status = CheckBSDAuth(port, port->user_name);
611#else
612 Assert(false);
613#endif /* USE_BSD_AUTH */
614 break;
615
616 case uaLDAP:
617#ifdef USE_LDAP
618 status = CheckLDAPAuth(port);
619#else
620 Assert(false);
621#endif
622 break;
623 case uaCert:
624 /* uaCert will be treated as if clientcert=verify-full (uaTrust) */
625 case uaTrust:
626 status = STATUS_OK;
627 break;
628 case uaOAuth:
629 status = CheckSASLAuth(&pg_be_oauth_mech, port, NULL, &logdetail,
630 &abandoned);
631 break;
632 }
633
634 if ((status == STATUS_OK && port->hba->clientcert == clientCertFull)
635 || port->hba->auth_method == uaCert)
636 {
637 /*
638 * Make sure we only check the certificate if we use the cert method
639 * or verify-full option.
640 */
641#ifdef USE_SSL
642 status = CheckCertAuth(port);
643#else
644 Assert(false);
645#endif
646 }
647
649 status == STATUS_OK &&
651 {
652 /*
653 * Normally, if log_connections is set, the call to set_authn_id()
654 * will log the connection. However, if that function is never
655 * called, perhaps because the trust method is in use, then we handle
656 * the logging here instead.
657 */
658 ereport(LOG,
659 errmsg("connection authenticated: user=\"%s\" method=%s "
660 "(%s:%d)",
661 port->user_name, hba_authname(port->hba->auth_method),
662 port->hba->sourcefile, port->hba->linenumber));
663 }
664
666 (*ClientAuthentication_hook) (port, status);
667
668 if (status == STATUS_OK)
670 else
673 status,
674 logdetail);
675}
const pg_be_sasl_mech pg_be_oauth_mech
Definition auth-oauth.c:54
int CheckSASLAuth(const pg_be_sasl_mech *mech, Port *port, char *shadow_pass, const char **logdetail, bool *abandoned)
Definition auth-sasl.c:50
void sendAuthRequest(Port *port, AuthRequest areq, const void *extradata, int extralen)
Definition auth.c:682
static int CheckPWChallengeAuth(Port *port, const char **logdetail)
Definition auth.c:828
static int auth_peer(Port *port)
Definition auth.c:1870
static void auth_failed(Port *port, int elevel, int status, const char *logdetail)
Definition auth.c:234
ClientAuthentication_hook_type ClientAuthentication_hook
Definition auth.c:217
static int ident_inet(Port *port)
Definition auth.c:1685
#define HOSTNAME_LOOKUP_DETAIL(port)
static int CheckPasswordAuth(Port *port, const char **logdetail)
Definition auth.c:793
uint32 log_connections
@ LOG_CONNECTION_AUTHENTICATION
bool secure_loaded_verify_locations(void)
Definition be-secure.c:103
#define STATUS_OK
Definition c.h:1258
#define Assert(condition)
Definition c.h:943
#define STATUS_ERROR
Definition c.h:1259
int errcode(int sqlerrcode)
Definition elog.c:874
#define _(x)
Definition elog.c:95
#define LOG
Definition elog.h:32
#define FATAL
Definition elog.h:42
#define FATAL_CLIENT_ONLY
Definition elog.h:43
#define ereport(elevel,...)
Definition elog.h:152
void hba_getauthmethod(Port *port)
Definition hba.c:2935
const char * hba_authname(UserAuth auth_method)
Definition hba.c:2948
@ uaBSD
Definition hba.h:37
@ uaLDAP
Definition hba.h:38
@ uaPeer
Definition hba.h:40
@ 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
@ uaIdent
Definition hba.h:30
@ uaOAuth
Definition hba.h:41
@ uaTrust
Definition hba.h:29
@ uaSSPI
Definition hba.h:35
@ clientCertOff
Definition hba.h:69
@ clientCertFull
Definition hba.h:71
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:1266
MemoryContext TopMemoryContext
Definition mcxt.c:166
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:125
ClientConnectionInfo MyClientConnectionInfo
Definition miscinit.c:1020
static char * errmsg
static int port
Definition pg_regress.c:117
static int fb(int x)
#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:135
bool am_db_walsender
Definition walsender.c:138

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(), CheckSASLAuth(), ClientAuthentication_hook, clientCertFull, clientCertOff, ereport, errcode(), errmsg, FATAL, FATAL_CLIENT_ONLY, fb(), 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, uaReject, uaSCRAM, uaSSPI, and uaTrust.

Referenced by PerformAuthentication().

◆ sendAuthRequest()

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

Definition at line 682 of file auth.c.

683{
685
687
690 if (extralen > 0)
692
694
695 /*
696 * Flush message so client will see it, except for AUTH_REQ_OK and
697 * AUTH_REQ_SASL_FIN, which need not be sent until we are ready for
698 * queries.
699 */
701 pq_flush();
702
704}
int32_t int32
Definition c.h:620
#define pq_flush()
Definition libpq.h:49
static char buf[DEFAULT_XLOG_SEG_SIZE]
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, fb(), pq_beginmessage(), pq_endmessage(), pq_flush, pq_sendbytes(), pq_sendint32(), and PqMsg_AuthenticationRequest.

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

◆ set_authn_id()

void set_authn_id ( Port port,
const char id 
)
extern

Definition at line 336 of file auth.c.

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

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

Variable Documentation

◆ ClientAuthentication_hook

PGDLLIMPORT ClientAuthentication_hook_type ClientAuthentication_hook
extern

Definition at line 217 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 176 of file auth.c.

Referenced by secure_open_gssapi().

◆ pg_krb_caseins_users

PGDLLIMPORT bool pg_krb_caseins_users
extern

Definition at line 175 of file auth.c.

◆ pg_krb_server_keyfile

PGDLLIMPORT char* pg_krb_server_keyfile
extern

Definition at line 174 of file auth.c.

Referenced by secure_open_gssapi().