PostgreSQL Source Code: src/backend/libpq/auth.c File Reference (original) (raw)
Go to the source code of this file.
Macros | |
---|---|
#define | IDENT_USERNAME_MAX 512 |
#define | IDENT_PORT 113 |
#define | HOSTNAME_LOOKUP_DETAIL(port) |
#define | RADIUS_VECTOR_LENGTH 16 |
#define | RADIUS_HEADER_LENGTH 20 |
#define | RADIUS_MAX_PASSWORD_LENGTH 128 |
#define | RADIUS_BUFFER_SIZE 1024 |
#define | RADIUS_ACCESS_REQUEST 1 |
#define | RADIUS_ACCESS_ACCEPT 2 |
#define | RADIUS_ACCESS_REJECT 3 |
#define | RADIUS_USER_NAME 1 |
#define | RADIUS_PASSWORD 2 |
#define | RADIUS_SERVICE_TYPE 6 |
#define | RADIUS_NAS_IDENTIFIER 32 |
#define | RADIUS_AUTHENTICATE_ONLY 8 |
#define | RADIUS_TIMEOUT 3 |
Functions | |
---|---|
static void | auth_failed (Port *port, int status, const char *logdetail) |
static char * | recv_password_packet (Port *port) |
static int | CheckPasswordAuth (Port *port, const char **logdetail) |
static int | CheckPWChallengeAuth (Port *port, const char **logdetail) |
static int | CheckMD5Auth (Port *port, char *shadow_pass, const char **logdetail) |
static int | ident_inet (hbaPort *port) |
static int | auth_peer (hbaPort *port) |
static int | CheckRADIUSAuth (Port *port) |
static int | PerformRadiusTransaction (const char *server, const char *secret, const char *portstr, const char *identifier, const char *user_name, const char *passwd) |
void | set_authn_id (Port *port, const char *id) |
void | ClientAuthentication (Port *port) |
void | sendAuthRequest (Port *port, AuthRequest areq, const void *extradata, int extralen) |
static bool | interpret_ident_response (const char *ident_response, char *ident_user) |
static void | radius_add_attribute (radius_packet *packet, uint8 type, const unsigned char *data, int len) |
Variables | |
---|---|
char * | pg_krb_server_keyfile |
bool | pg_krb_caseins_users |
bool | pg_gss_accept_delegation |
ClientAuthentication_hook_type | ClientAuthentication_hook = NULL |
◆ HOSTNAME_LOOKUP_DETAIL
| #define HOSTNAME_LOOKUP_DETAIL | ( | | port | ) | | -------------------------------- | - | | ------------------------------------------------------------------- | - |
Value:
(port->remote_hostname ? \
(port->remote_hostname_resolv == +1 ? \
errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \
port->remote_hostname) : \
port->remote_hostname_resolv == 0 ? \
errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", \
port->remote_hostname) : \
port->remote_hostname_resolv == -1 ? \
errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", \
port->remote_hostname) : \
port->remote_hostname_resolv == -2 ? \
errdetail_log("Could not translate client host name \"%s\" to IP address: %s.", \
port->remote_hostname, \
- \
: (port->remote_hostname_resolv == -2 ? \
errdetail_log("Could not resolve client IP address to a host name: %s.", \
0))
int errdetail_log(const char *fmt,...)
const char * gai_strerror(int ecode)
◆ IDENT_PORT
◆ IDENT_USERNAME_MAX
#define IDENT_USERNAME_MAX 512
Definition at line 68 of file auth.c.
◆ RADIUS_ACCESS_ACCEPT
#define RADIUS_ACCESS_ACCEPT 2
◆ RADIUS_ACCESS_REJECT
#define RADIUS_ACCESS_REJECT 3
◆ RADIUS_ACCESS_REQUEST
#define RADIUS_ACCESS_REQUEST 1
◆ RADIUS_AUTHENTICATE_ONLY
#define RADIUS_AUTHENTICATE_ONLY 8
◆ RADIUS_BUFFER_SIZE
#define RADIUS_BUFFER_SIZE 1024
◆ RADIUS_HEADER_LENGTH
#define RADIUS_HEADER_LENGTH 20
◆ RADIUS_MAX_PASSWORD_LENGTH
#define RADIUS_MAX_PASSWORD_LENGTH 128
◆ RADIUS_NAS_IDENTIFIER
#define RADIUS_NAS_IDENTIFIER 32
◆ RADIUS_PASSWORD
#define RADIUS_PASSWORD 2
◆ RADIUS_SERVICE_TYPE
#define RADIUS_SERVICE_TYPE 6
◆ RADIUS_TIMEOUT
◆ RADIUS_USER_NAME
#define RADIUS_USER_NAME 1
◆ RADIUS_VECTOR_LENGTH
#define RADIUS_VECTOR_LENGTH 16
◆ auth_failed()
static void auth_failed ( Port * port, int status, const char * logdetail ) | static |
---|
Definition at line 231 of file auth.c.
232{
233 const char *errstr;
234 char *cdetail;
235 int errcode_return = ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION;
236
237
238
239
240
241
242
243
244
245
246
249
250 switch (port->hba->auth_method)
251 {
254 errstr = gettext_noop("authentication failed for user \"%s\": host rejected");
255 break;
257 errstr = gettext_noop("\"trust\" authentication failed for user \"%s\"");
258 break;
260 errstr = gettext_noop("Ident authentication failed for user \"%s\"");
261 break;
263 errstr = gettext_noop("Peer authentication failed for user \"%s\"");
264 break;
268 errstr = gettext_noop("password authentication failed for user \"%s\"");
269
271 break;
273 errstr = gettext_noop("GSSAPI authentication failed for user \"%s\"");
274 break;
276 errstr = gettext_noop("SSPI authentication failed for user \"%s\"");
277 break;
279 errstr = gettext_noop("PAM authentication failed for user \"%s\"");
280 break;
282 errstr = gettext_noop("BSD authentication failed for user \"%s\"");
283 break;
285 errstr = gettext_noop("LDAP authentication failed for user \"%s\"");
286 break;
288 errstr = gettext_noop("certificate authentication failed for user \"%s\"");
289 break;
291 errstr = gettext_noop("RADIUS authentication failed for user \"%s\"");
292 break;
294 errstr = gettext_noop("OAuth bearer authentication failed for user \"%s\"");
295 break;
296 default:
297 errstr = gettext_noop("authentication failed for user \"%s\": invalid authentication method");
298 break;
299 }
300
301 cdetail = psprintf(_("Connection matched file \"%s\" line %d: \"%s\""),
302 port->hba->sourcefile, port->hba->linenumber,
303 port->hba->rawline);
304 if (logdetail)
305 logdetail = psprintf("%s\n%s", logdetail, cdetail);
306 else
307 logdetail = cdetail;
308
310 (errcode(errcode_return),
312 logdetail ? errdetail_log("%s", logdetail) : 0));
313
314
315}
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define ERRCODE_INVALID_PASSWORD
char * psprintf(const char *fmt,...)
References _, ereport, errcode(), ERRCODE_INVALID_PASSWORD, errdetail_log(), errmsg(), FATAL, gettext_noop, port, proc_exit(), psprintf(), STATUS_EOF, uaBSD, uaCert, uaGSS, uaIdent, uaImplicitReject, uaLDAP, uaMD5, uaOAuth, uaPAM, uaPassword, uaPeer, uaRADIUS, uaReject, uaSCRAM, uaSSPI, and uaTrust.
Referenced by ClientAuthentication().
◆ auth_peer()
static int auth_peer ( hbaPort * port) | static |
---|
Definition at line 1848 of file auth.c.
1849{
1852#ifndef WIN32
1853 struct passwd pwbuf;
1854 struct passwd *pw;
1855 char buf[1024];
1856 int rc;
1857 int ret;
1858#endif
1859
1861 {
1862
1863 if (errno == ENOSYS)
1865 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1866 errmsg("peer authentication is not supported on this platform")));
1867 else
1870 errmsg("could not get peer credentials: %m")));
1872 }
1873
1874#ifndef WIN32
1875 rc = getpwuid_r(uid, &pwbuf, buf, sizeof buf, &pw);
1876 if (rc != 0)
1877 {
1878 errno = rc;
1880 errmsg("could not look up local user ID %ld: %m", (long) uid));
1882 }
1883 else if (!pw)
1884 {
1886 errmsg("local user with ID %ld does not exist", (long) uid));
1888 }
1889
1890
1891
1892
1893
1894
1896
1899
1900 return ret;
1901#else
1902
1905#endif
1906}
void set_authn_id(Port *port, const char *id)
int errcode_for_socket_access(void)
Assert(PointerIsAligned(start, uint64))
int check_usermap(const char *usermap_name, const char *pg_user, const char *system_user, bool case_insensitive)
ClientConnectionInfo MyClientConnectionInfo
int getpeereid(int sock, uid_t *uid, gid_t *gid)
References Assert(), ClientConnectionInfo::authn_id, buf, check_usermap(), ereport, errcode(), errcode_for_socket_access(), errmsg(), getpeereid(), LOG, MyClientConnectionInfo, port, set_authn_id(), and STATUS_ERROR.
Referenced by ClientAuthentication().
◆ CheckMD5Auth()
static int CheckMD5Auth ( Port * port, char * shadow_pass, const char ** logdetail ) | static |
---|
Definition at line 875 of file auth.c.
876{
877 uint8 md5Salt[4];
878 char *passwd;
879 int result;
880
881
883 {
885 (errmsg("could not generate random MD5 salt")));
887 }
888
890
892 if (passwd == NULL)
893 return STATUS_EOF;
894
895 if (shadow_pass)
897 md5Salt, 4, logdetail);
898 else
900
902
903 return result;
904}
void sendAuthRequest(Port *port, AuthRequest areq, const void *extradata, int extralen)
static char * recv_password_packet(Port *port)
int md5_crypt_verify(const char *role, const char *shadow_pass, const char *client_pass, const uint8 *md5_salt, int md5_salt_len, const char **logdetail)
void pfree(void *pointer)
bool pg_strong_random(void *buf, size_t len)
References AUTH_REQ_MD5, ereport, errmsg(), LOG, md5_crypt_verify(), pfree(), pg_strong_random(), port, recv_password_packet(), sendAuthRequest(), STATUS_EOF, and STATUS_ERROR.
Referenced by CheckPWChallengeAuth().
◆ CheckPasswordAuth()
static int CheckPasswordAuth ( Port * port, const char ** logdetail ) | static |
---|
Definition at line 780 of file auth.c.
781{
782 char *passwd;
783 int result;
784 char *shadow_pass;
785
787
789 if (passwd == NULL)
790 return STATUS_EOF;
791
793 if (shadow_pass)
794 {
796 logdetail);
797 }
798 else
800
801 if (shadow_pass)
802 pfree(shadow_pass);
804
807
808 return result;
809}
int plain_crypt_verify(const char *role, const char *shadow_pass, const char *client_pass, const char **logdetail)
char * get_role_password(const char *role, const char **logdetail)
#define AUTH_REQ_PASSWORD
References AUTH_REQ_PASSWORD, get_role_password(), pfree(), plain_crypt_verify(), port, recv_password_packet(), sendAuthRequest(), set_authn_id(), STATUS_EOF, STATUS_ERROR, and STATUS_OK.
Referenced by ClientAuthentication().
◆ CheckPWChallengeAuth()
static int CheckPWChallengeAuth ( Port * port, const char ** logdetail ) | static |
---|
Definition at line 815 of file auth.c.
816{
817 int auth_result;
818 char *shadow_pass;
820
822 port->hba->auth_method == uaMD5);
823
824
826
827
828
829
830
831
832
833
834
835
836 if (!shadow_pass)
838 else
840
841
842
843
844
845
846
847
848
849
850
853 else
855 logdetail);
856
857 if (shadow_pass)
858 pfree(shadow_pass);
859 else
860 {
861
862
863
864
866 }
867
870
871 return auth_result;
872}
int CheckSASLAuth(const pg_be_sasl_mech *mech, Port *port, char *shadow_pass, const char **logdetail)
const pg_be_sasl_mech pg_be_scram_mech
static int CheckMD5Auth(Port *port, char *shadow_pass, const char **logdetail)
PasswordType get_password_type(const char *shadow_pass)
References Assert(), CheckMD5Auth(), CheckSASLAuth(), get_password_type(), get_role_password(), Password_encryption, PASSWORD_TYPE_MD5, pfree(), pg_be_scram_mech, port, set_authn_id(), STATUS_OK, uaMD5, and uaSCRAM.
Referenced by ClientAuthentication().
◆ CheckRADIUSAuth()
static int CheckRADIUSAuth ( Port * port) | static |
---|
Definition at line 2837 of file auth.c.
2838{
2839 char *passwd;
2841 *secrets,
2842 *radiusports,
2843 *identifiers;
2844
2845
2847
2848
2849 if (port->hba->radiusservers == NIL)
2850 {
2852 (errmsg("RADIUS server not specified")));
2854 }
2855
2856 if (port->hba->radiussecrets == NIL)
2857 {
2859 (errmsg("RADIUS secret not specified")));
2861 }
2862
2863
2865
2867 if (passwd == NULL)
2868 return STATUS_EOF;
2869
2871 {
2876 }
2877
2878
2879
2880
2882 radiusports = list_head(port->hba->radiusports);
2883 identifiers = list_head(port->hba->radiusidentifiers);
2884 foreach(server, port->hba->radiusservers)
2885 {
2888 radiusports ? lfirst(radiusports) : NULL,
2889 identifiers ? lfirst(identifiers) : NULL,
2890 port->user_name,
2891 passwd);
2892
2893
2894
2895
2896
2897
2898
2900 {
2902
2905 }
2907 {
2910 }
2911
2912
2913
2914
2915
2916
2917
2919 secrets = lnext(port->hba->radiussecrets, secrets);
2921 radiusports = lnext(port->hba->radiusports, radiusports);
2923 identifiers = lnext(port->hba->radiusidentifiers, identifiers);
2924 }
2925
2926
2929}
#define RADIUS_MAX_PASSWORD_LENGTH
static int PerformRadiusTransaction(const char *server, const char *secret, const char *portstr, const char *identifier, const char *user_name, const char *passwd)
static int list_length(const List *l)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
References Assert(), AUTH_REQ_PASSWORD, ereport, errmsg(), lfirst, list_head(), list_length(), lnext(), LOG, NIL, PerformRadiusTransaction(), pfree(), port, RADIUS_MAX_PASSWORD_LENGTH, recv_password_packet(), sendAuthRequest(), set_authn_id(), STATUS_EOF, STATUS_ERROR, and STATUS_OK.
Referenced by ClientAuthentication().
◆ ClientAuthentication()
void ClientAuthentication | ( | Port * | port | ) |
---|
Definition at line 371 of file auth.c.
372{
374 const char *logdetail = NULL;
375
376
377
378
379
380
381
383
385
386
387
388
389
390
392 {
393
396 (errcode(ERRCODE_CONFIG_FILE_ERROR),
397 errmsg("client certificates can only be checked if a root certificate store is available")));
398
399
400
401
402
403
404
405 if (->peer_cert_valid)
407 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
408 errmsg("connection requires a valid client certificate")));
409 }
410
411
412
413
414 switch (port->hba->auth_method)
415 {
417
418
419
420
421
422
423
424
425
426
427
428 {
429 char hostinfo[NI_MAXHOST];
430 const char *encryption_state;
431
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
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
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
465
466
467
468
469
470
471
472
473
474 {
475 char hostinfo[NI_MAXHOST];
476 const char *encryption_state;
477
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
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
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
534#ifdef ENABLE_GSS
535
536 if (port->gss == NULL)
537 port->gss = (pg_gssinfo *)
539 sizeof(pg_gssinfo));
540 port->gss->auth = true;
541
542
543
544
545
546 if (port->gss->enc)
547 status = pg_GSS_checkauth(port);
548 else
549 {
551 status = pg_GSS_recvauth(port);
552 }
553#else
555#endif
556 break;
557
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
568#endif
569 break;
570
573 break;
574
577 break;
578
582 break;
583
586 break;
587
589#ifdef USE_PAM
590 status = CheckPAMAuth(port, port->user_name, "");
591#else
593#endif
594 break;
595
597#ifdef USE_BSD_AUTH
598 status = CheckBSDAuth(port, port->user_name);
599#else
601#endif
602 break;
603
605#ifdef USE_LDAP
606 status = CheckLDAPAuth(port);
607#else
609#endif
610 break;
613 break;
615
618 break;
621 break;
622 }
623
626 {
627
628
629
630
631#ifdef USE_SSL
632 status = CheckCertAuth(port);
633#else
635#endif
636 }
637
641 {
642
643
644
645
646
647
649 errmsg("connection authenticated: user=\"%s\" method=%s "
650 "(%s:%d)",
652 port->hba->sourcefile, port->hba->linenumber));
653 }
654
656 (*ClientAuthentication_hook) (port, status);
657
660 else
662}
const pg_be_sasl_mech pg_be_oauth_mech
static int CheckPWChallengeAuth(Port *port, const char **logdetail)
static int ident_inet(hbaPort *port)
static int CheckRADIUSAuth(Port *port)
static void auth_failed(Port *port, int status, const char *logdetail)
ClientAuthentication_hook_type ClientAuthentication_hook
static int auth_peer(hbaPort *port)
#define HOSTNAME_LOOKUP_DETAIL(port)
static int CheckPasswordAuth(Port *port, const char **logdetail)
@ LOG_CONNECTION_AUTHENTICATION
bool secure_loaded_verify_locations(void)
void hba_getauthmethod(hbaPort *port)
const char * hba_authname(UserAuth auth_method)
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
void * MemoryContextAllocZero(MemoryContext context, Size size)
MemoryContext TopMemoryContext
#define CHECK_FOR_INTERRUPTS()
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().
◆ ident_inet()
static int ident_inet ( hbaPort * port) | static |
---|
Definition at line 1663 of file auth.c.
1664{
1669 int rc;
1670 bool ident_return;
1671 char remote_addr_s[NI_MAXHOST];
1672 char remote_port[NI_MAXSERV];
1673 char local_addr_s[NI_MAXHOST];
1674 char local_port[NI_MAXSERV];
1675 char ident_port[NI_MAXSERV];
1676 char ident_query[80];
1678 struct addrinfo *ident_serv = NULL,
1679 *la = NULL,
1680 hints;
1681
1682
1683
1684
1685
1687 remote_addr_s, sizeof(remote_addr_s),
1688 remote_port, sizeof(remote_port),
1689 NI_NUMERICHOST | NI_NUMERICSERV);
1691 local_addr_s, sizeof(local_addr_s),
1692 local_port, sizeof(local_port),
1693 NI_NUMERICHOST | NI_NUMERICSERV);
1694
1696 hints.ai_flags = AI_NUMERICHOST;
1697 hints.ai_family = remote_addr.addr.ss_family;
1698 hints.ai_socktype = SOCK_STREAM;
1699 hints.ai_protocol = 0;
1700 hints.ai_addrlen = 0;
1701 hints.ai_canonname = NULL;
1702 hints.ai_addr = NULL;
1703 hints.ai_next = NULL;
1704 rc = pg_getaddrinfo_all(remote_addr_s, ident_port, &hints, &ident_serv);
1705 if (rc || !ident_serv)
1706 {
1707
1708 ident_return = false;
1709 goto ident_inet_done;
1710 }
1711
1712 hints.ai_flags = AI_NUMERICHOST;
1713 hints.ai_family = local_addr.addr.ss_family;
1714 hints.ai_socktype = SOCK_STREAM;
1715 hints.ai_protocol = 0;
1716 hints.ai_addrlen = 0;
1717 hints.ai_canonname = NULL;
1718 hints.ai_addr = NULL;
1719 hints.ai_next = NULL;
1721 if (rc || !la)
1722 {
1723
1724 ident_return = false;
1725 goto ident_inet_done;
1726 }
1727
1728 sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
1729 ident_serv->ai_protocol);
1731 {
1734 errmsg("could not create socket for Ident connection: %m")));
1735 ident_return = false;
1736 goto ident_inet_done;
1737 }
1738
1739
1740
1741
1742
1743
1744 rc = bind(sock_fd, la->ai_addr, la->ai_addrlen);
1745 if (rc != 0)
1746 {
1749 errmsg("could not bind to local address \"%s\": %m",
1750 local_addr_s)));
1751 ident_return = false;
1752 goto ident_inet_done;
1753 }
1754
1755 rc = connect(sock_fd, ident_serv->ai_addr,
1756 ident_serv->ai_addrlen);
1757 if (rc != 0)
1758 {
1761 errmsg("could not connect to Ident server at address \"%s\", port %s: %m",
1762 remote_addr_s, ident_port)));
1763 ident_return = false;
1764 goto ident_inet_done;
1765 }
1766
1767
1768 snprintf(ident_query, sizeof(ident_query), "%s,%s\r\n",
1769 remote_port, local_port);
1770
1771
1772 do
1773 {
1775
1776 rc = send(sock_fd, ident_query, strlen(ident_query), 0);
1777 } while (rc < 0 && errno == EINTR);
1778
1779 if (rc < 0)
1780 {
1783 errmsg("could not send query to Ident server at address \"%s\", port %s: %m",
1784 remote_addr_s, ident_port)));
1785 ident_return = false;
1786 goto ident_inet_done;
1787 }
1788
1789 do
1790 {
1792
1793 rc = recv(sock_fd, ident_response, sizeof(ident_response) - 1, 0);
1794 } while (rc < 0 && errno == EINTR);
1795
1796 if (rc < 0)
1797 {
1800 errmsg("could not receive response from Ident server at address \"%s\", port %s: %m",
1801 remote_addr_s, ident_port)));
1802 ident_return = false;
1803 goto ident_inet_done;
1804 }
1805
1806 ident_response[rc] = '\0';
1808 if (!ident_return)
1810 (errmsg("invalidly formatted response from Ident server: \"%s\"",
1811 ident_response)));
1812
1813ident_inet_done:
1816 if (ident_serv)
1818 if (la)
1820
1821 if (ident_return)
1822 {
1823
1824
1825
1826
1827
1830 }
1832}
#define IDENT_USERNAME_MAX
static bool interpret_ident_response(const char *ident_response, char *ident_user)
void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
int pg_getaddrinfo_all(const char *hostname, const char *servname, const struct addrinfo *hintp, struct addrinfo **result)
struct sockaddr_storage addr
#define bind(s, addr, addrlen)
#define recv(s, buf, len, flags)
#define send(s, buf, len, flags)
#define socket(af, type, protocol)
#define connect(s, name, namelen)
References SockAddr::addr, bind, CHECK_FOR_INTERRUPTS, check_usermap(), closesocket, connect, EINTR, ereport, errcode_for_socket_access(), errmsg(), IDENT_PORT, IDENT_USERNAME_MAX, interpret_ident_response(), LOG, pg_freeaddrinfo_all(), pg_getaddrinfo_all(), pg_getnameinfo_all(), PGINVALID_SOCKET, port, recv, SockAddr::salen, send, set_authn_id(), snprintf, socket, and STATUS_ERROR.
Referenced by ClientAuthentication().
◆ interpret_ident_response()
static bool interpret_ident_response ( const char * ident_response, char * ident_user ) | static |
---|
Definition at line 1582 of file auth.c.
1584{
1585 const char *cursor = ident_response;
1586
1587
1588
1589
1590 if (strlen(ident_response) < 2)
1591 return false;
1592 else if (ident_response[strlen(ident_response) - 2] != '\r')
1593 return false;
1594 else
1595 {
1597 cursor++;
1598
1600 return false;
1601 else
1602 {
1603
1604 char response_type[80];
1605 int i;
1606
1607 cursor++;
1609 cursor++;
1610 i = 0;
1612 i < (int) (sizeof(response_type) - 1))
1613 response_type[i++] = *cursor++;
1614 response_type[i] = '\0';
1616 cursor++;
1617 if (strcmp(response_type, "USERID") != 0)
1618 return false;
1619 else
1620 {
1621
1622
1623
1624
1626 return false;
1627 else
1628 {
1629 cursor++;
1630
1634 return false;
1635 else
1636 {
1637 cursor++;
1639 cursor++;
1640
1641 i = 0;
1643 ident_user[i++] = *cursor++;
1644 ident_user[i] = '\0';
1645 return true;
1646 }
1647 }
1648 }
1649 }
1650 }
1651}
bool pg_isblank(const char c)
References i, IDENT_USERNAME_MAX, and pg_isblank().
Referenced by ident_inet().
◆ PerformRadiusTransaction()
static int PerformRadiusTransaction ( const char * server, const char * secret, const char * portstr, const char * identifier, const char * user_name, const char * passwd ) | static |
---|
Definition at line 2932 of file auth.c.
2933{
2937 radius_packet *receivepacket = &radius_recv_pack;
2938 void *radius_buffer = &radius_send_pack;
2939 void *receive_buffer = &radius_recv_pack;
2941 uint8 *cryptvector;
2942 int encryptedpasswordlen;
2944 uint8 *md5trailer;
2945 int packetlength;
2947
2948 struct sockaddr_in6 localaddr;
2949 struct sockaddr_in6 remoteaddr;
2950 struct addrinfo hint;
2951 struct addrinfo *serveraddrs;
2954 fd_set fdset;
2955 struct timeval endtime;
2956 int i,
2957 j,
2958 r;
2959
2960
2963 if (identifier == NULL)
2964 identifier = "postgresql";
2965
2966 MemSet(&hint, 0, sizeof(hint));
2967 hint.ai_socktype = SOCK_DGRAM;
2968 hint.ai_family = AF_UNSPEC;
2970
2972 if (r || !serveraddrs)
2973 {
2975 (errmsg("could not translate RADIUS server name \"%s\" to address: %s",
2977 if (serveraddrs)
2980 }
2981
2982
2983
2987 {
2989 (errmsg("could not generate random encryption vector")));
2992 }
2993 packet->id = packet->vector[0];
2997
2998
2999
3000
3001
3002
3003
3006 memcpy(cryptvector, secret, strlen(secret));
3007
3008
3009 md5trailer = packet->vector;
3011 {
3012 const char *errstr = NULL;
3013
3015
3016
3017
3018
3019
3020 md5trailer = encryptedpassword + i;
3021
3023 encryptedpassword + i, &errstr))
3024 {
3026 (errmsg("could not perform MD5 encryption of password: %s",
3027 errstr)));
3028 pfree(cryptvector);
3031 }
3032
3034 {
3035 if (j < strlen(passwd))
3036 encryptedpassword[j] = passwd[j] ^ encryptedpassword[j];
3037 else
3038 encryptedpassword[j] = '\0' ^ encryptedpassword[j];
3039 }
3040 }
3041 pfree(cryptvector);
3042
3044
3045
3046 packetlength = packet->length;
3048
3049 sock = socket(serveraddrs[0].ai_family, SOCK_DGRAM, 0);
3051 {
3053 (errmsg("could not create RADIUS socket: %m")));
3056 }
3057
3058 memset(&localaddr, 0, sizeof(localaddr));
3059 localaddr.sin6_family = serveraddrs[0].ai_family;
3060 localaddr.sin6_addr = in6addr_any;
3061 if (localaddr.sin6_family == AF_INET6)
3062 addrsize = sizeof(struct sockaddr_in6);
3063 else
3064 addrsize = sizeof(struct sockaddr_in);
3065
3066 if (bind(sock, (struct sockaddr *) &localaddr, addrsize))
3067 {
3069 (errmsg("could not bind local RADIUS socket: %m")));
3073 }
3074
3075 if (sendto(sock, radius_buffer, packetlength, 0,
3076 serveraddrs[0].ai_addr, serveraddrs[0].ai_addrlen) < 0)
3077 {
3079 (errmsg("could not send RADIUS packet: %m")));
3083 }
3084
3085
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3100
3101 while (true)
3102 {
3103 struct timeval timeout;
3104 struct timeval now;
3105 int64 timeoutval;
3106 const char *errstr = NULL;
3107
3109 timeoutval = (endtime.tv_sec * 1000000 + endtime.tv_usec) - (now.tv_sec * 1000000 + now.tv_usec);
3110 if (timeoutval <= 0)
3111 {
3113 (errmsg("timeout waiting for RADIUS response from %s",
3114 server)));
3117 }
3118 timeout.tv_sec = timeoutval / 1000000;
3119 timeout.tv_usec = timeoutval % 1000000;
3120
3121 FD_ZERO(&fdset);
3122 FD_SET(sock, &fdset);
3123
3124 r = select(sock + 1, &fdset, NULL, NULL, &timeout);
3125 if (r < 0)
3126 {
3127 if (errno == EINTR)
3128 continue;
3129
3130
3132 (errmsg("could not check status on RADIUS socket: %m")));
3135 }
3136 if (r == 0)
3137 {
3139 (errmsg("timeout waiting for RADIUS response from %s",
3140 server)));
3143 }
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156 addrsize = sizeof(remoteaddr);
3157 packetlength = recvfrom(sock, receive_buffer, RADIUS_BUFFER_SIZE, 0,
3158 (struct sockaddr *) &remoteaddr, &addrsize);
3159 if (packetlength < 0)
3160 {
3162 (errmsg("could not read RADIUS response: %m")));
3165 }
3166
3168 {
3170 (errmsg("RADIUS response from %s was sent from incorrect port: %d",
3171 server, pg_ntoh16(remoteaddr.sin6_port))));
3172 continue;
3173 }
3174
3176 {
3178 (errmsg("RADIUS response from %s too short: %d", server, packetlength)));
3179 continue;
3180 }
3181
3183 {
3185 (errmsg("RADIUS response from %s has corrupt length: %d (actual length %d)",
3186 server, pg_ntoh16(receivepacket->length), packetlength)));
3187 continue;
3188 }
3189
3190 if (packet->id != receivepacket->id)
3191 {
3193 (errmsg("RADIUS response from %s is to a different request: %d (should be %d)",
3194 server, receivepacket->id, packet->id)));
3195 continue;
3196 }
3197
3198
3199
3200
3201
3202 cryptvector = palloc(packetlength + strlen(secret));
3203
3204 memcpy(cryptvector, receivepacket, 4);
3206
3207
3209
3213 memcpy(cryptvector + packetlength, secret, strlen(secret));
3214
3216 packetlength + strlen(secret),
3217 encryptedpassword, &errstr))
3218 {
3220 (errmsg("could not perform MD5 encryption of received packet: %s",
3221 errstr)));
3222 pfree(cryptvector);
3223 continue;
3224 }
3225 pfree(cryptvector);
3226
3228 {
3230 (errmsg("RADIUS response from %s has incorrect MD5 signature",
3231 server)));
3232 continue;
3233 }
3234
3236 {
3239 }
3241 {
3244 }
3245 else
3246 {
3248 (errmsg("RADIUS response from %s has invalid code (%d) for user \"%s\"",
3249 server, receivepacket->code, user_name)));
3250 continue;
3251 }
3252 }
3253}
static void radius_add_attribute(radius_packet *packet, uint8 type, const unsigned char *data, int len)
#define RADIUS_HEADER_LENGTH
#define RADIUS_AUTHENTICATE_ONLY
#define RADIUS_ACCESS_REQUEST
#define RADIUS_NAS_IDENTIFIER
#define RADIUS_SERVICE_TYPE
#define RADIUS_ACCESS_REJECT
#define RADIUS_ACCESS_ACCEPT
#define RADIUS_VECTOR_LENGTH
#define RADIUS_BUFFER_SIZE
Datum now(PG_FUNCTION_ARGS)
#define MemSet(start, val, len)
bool pg_md5_binary(const void *buff, size_t len, uint8 *outbuf, const char **errstr)
uint8 vector[RADIUS_VECTOR_LENGTH]
#define select(n, r, w, e, timeout)
int gettimeofday(struct timeval *tp, void *tzp)
References bind, closesocket, radius_packet::code, EINTR, ereport, errmsg(), gai_strerror(), gettimeofday(), i, radius_packet::id, j, radius_packet::length, LOG, MemSet, now(), palloc(), pfree(), pg_freeaddrinfo_all(), pg_getaddrinfo_all(), pg_hton16, pg_hton32, pg_md5_binary(), pg_ntoh16, pg_strong_random(), PGINVALID_SOCKET, port, portstr, RADIUS_ACCESS_ACCEPT, RADIUS_ACCESS_REJECT, RADIUS_ACCESS_REQUEST, radius_add_attribute(), RADIUS_AUTHENTICATE_ONLY, RADIUS_BUFFER_SIZE, RADIUS_HEADER_LENGTH, RADIUS_MAX_PASSWORD_LENGTH, RADIUS_NAS_IDENTIFIER, RADIUS_PASSWORD, RADIUS_SERVICE_TYPE, RADIUS_TIMEOUT, RADIUS_USER_NAME, RADIUS_VECTOR_LENGTH, select, socket, STATUS_EOF, STATUS_ERROR, STATUS_OK, and radius_packet::vector.
Referenced by CheckRADIUSAuth().
◆ radius_add_attribute()
static void radius_add_attribute ( radius_packet * packet, uint8 type, const unsigned char * data, int len ) | static |
---|
Definition at line 2811 of file auth.c.
2812{
2814
2816 {
2817
2818
2819
2820
2821
2822
2824 "adding attribute code %d with length %d to radius packet would create oversize packet, ignoring",
2826 return;
2827 }
2828
2834}
uint8 data[FLEXIBLE_ARRAY_MEMBER]
References radius_attribute::attribute, radius_attribute::data, data, elog, len, radius_attribute::length, radius_packet::length, RADIUS_BUFFER_SIZE, type, and WARNING.
Referenced by PerformRadiusTransaction().
◆ recv_password_packet()
static char * recv_password_packet ( Port * port) | static |
---|
Definition at line 699 of file auth.c.
700{
702 int mtype;
703
705
706
709 {
710
711
712
713
714
715 if (mtype != EOF)
717 (errcode(ERRCODE_PROTOCOL_VIOLATION),
718 errmsg("expected password response, got message type %d",
719 mtype)));
720 return NULL;
721 }
722
725 {
726
728 return NULL;
729 }
730
731
732
733
734
735
736 if (strlen(buf.data) + 1 != buf.len)
738 (errcode(ERRCODE_PROTOCOL_VIOLATION),
739 errmsg("invalid password packet size")));
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754 if (buf.len == 1)
757 errmsg("empty password returned by client")));
758
759
760 elog(DEBUG5, "received password packet");
761
762
763
764
765
766
767 return buf.data;
768}
#define PG_MAX_AUTH_TOKEN_LENGTH
int pq_getmessage(StringInfo s, int maxlen)
void pq_startmsgread(void)
#define PqMsg_PasswordMessage
void initStringInfo(StringInfo str)
References buf, DEBUG5, elog, ereport, errcode(), ERRCODE_INVALID_PASSWORD, errmsg(), ERROR, initStringInfo(), pfree(), PG_MAX_AUTH_TOKEN_LENGTH, pq_getbyte(), pq_getmessage(), pq_startmsgread(), and PqMsg_PasswordMessage.
Referenced by CheckMD5Auth(), CheckPasswordAuth(), and CheckRADIUSAuth().
◆ sendAuthRequest()
void sendAuthRequest | ( | Port * | port, |
---|---|---|---|
AuthRequest | areq, | ||
const void * | extradata, | ||
int | extralen | ||
) |
Definition at line 669 of file auth.c.
670{
672
674
677 if (extralen > 0)
679
681
682
683
684
685
686
689
691}
void pq_sendbytes(StringInfo buf, const void *data, int datalen)
void pq_endmessage(StringInfo buf)
void pq_beginmessage(StringInfo buf, char msgtype)
static void pq_sendint32(StringInfo buf, uint32 i)
#define PqMsg_AuthenticationRequest
#define AUTH_REQ_SASL_FIN
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{
336
338 {
339
340
341
342
343
344
346 (errmsg("authentication identifier set more than once"),
347 errdetail_log("previous identifier: \"%s\"; new identifier: \"%s\"",
349 }
350
353
355 {
357 errmsg("connection authenticated: identity=\"%s\" method=%s "
358 "(%s:%d)",
361 port->hba->sourcefile, port->hba->linenumber));
362 }
363}
char * MemoryContextStrdup(MemoryContext context, const char *string)
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().
◆ ClientAuthentication_hook
◆ pg_gss_accept_delegation
bool pg_gss_accept_delegation
◆ pg_krb_caseins_users
bool pg_krb_caseins_users
Definition at line 166 of file auth.c.
◆ pg_krb_server_keyfile
char* pg_krb_server_keyfile