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, \

  1. \

: (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 (port->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

2831 attr->length = len + 2;

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