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

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

685{
687
689
692 if (extralen > 0)
694
696
697 /*
698 * Flush message so client will see it, except for AUTH_REQ_OK and
699 * AUTH_REQ_SASL_FIN, which need not be sent until we are ready for
700 * queries.
701 */
703 pq_flush();
704
706}
int32_t int32
Definition c.h:679
#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 338 of file auth.c.

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

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

Referenced by secure_open_gssapi().

◆ pg_krb_caseins_users

PGDLLIMPORT bool pg_krb_caseins_users
extern

Definition at line 177 of file auth.c.

◆ pg_krb_server_keyfile

PGDLLIMPORT char* pg_krb_server_keyfile
extern

Definition at line 176 of file auth.c.

Referenced by secure_open_gssapi().