PageRenderTime 64ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/backend/libpq/auth.c

http://github.com/postgres/postgres
C | 3410 lines | 2225 code | 438 blank | 747 comment | 446 complexity | b6304eb2745dce163c35f3e3c8f345d7 MD5 | raw file
Possible License(s): AGPL-3.0
  1. /*-------------------------------------------------------------------------
  2. *
  3. * auth.c
  4. * Routines to handle network authentication
  5. *
  6. * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
  7. * Portions Copyright (c) 1994, Regents of the University of California
  8. *
  9. *
  10. * IDENTIFICATION
  11. * src/backend/libpq/auth.c
  12. *
  13. *-------------------------------------------------------------------------
  14. */
  15. #include "postgres.h"
  16. #include <sys/param.h>
  17. #include <sys/socket.h>
  18. #include <netinet/in.h>
  19. #include <unistd.h>
  20. #ifdef HAVE_SYS_SELECT_H
  21. #include <sys/select.h>
  22. #endif
  23. #include "commands/user.h"
  24. #include "common/ip.h"
  25. #include "common/md5.h"
  26. #include "common/scram-common.h"
  27. #include "libpq/auth.h"
  28. #include "libpq/crypt.h"
  29. #include "libpq/libpq.h"
  30. #include "libpq/pqformat.h"
  31. #include "libpq/scram.h"
  32. #include "miscadmin.h"
  33. #include "port/pg_bswap.h"
  34. #include "replication/walsender.h"
  35. #include "storage/ipc.h"
  36. #include "utils/memutils.h"
  37. #include "utils/timestamp.h"
  38. /*----------------------------------------------------------------
  39. * Global authentication functions
  40. *----------------------------------------------------------------
  41. */
  42. static void sendAuthRequest(Port *port, AuthRequest areq, const char *extradata,
  43. int extralen);
  44. static void auth_failed(Port *port, int status, char *logdetail);
  45. static char *recv_password_packet(Port *port);
  46. /*----------------------------------------------------------------
  47. * Password-based authentication methods (password, md5, and scram-sha-256)
  48. *----------------------------------------------------------------
  49. */
  50. static int CheckPasswordAuth(Port *port, char **logdetail);
  51. static int CheckPWChallengeAuth(Port *port, char **logdetail);
  52. static int CheckMD5Auth(Port *port, char *shadow_pass, char **logdetail);
  53. static int CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail);
  54. /*----------------------------------------------------------------
  55. * Ident authentication
  56. *----------------------------------------------------------------
  57. */
  58. /* Max size of username ident server can return (per RFC 1413) */
  59. #define IDENT_USERNAME_MAX 512
  60. /* Standard TCP port number for Ident service. Assigned by IANA */
  61. #define IDENT_PORT 113
  62. static int ident_inet(hbaPort *port);
  63. /*----------------------------------------------------------------
  64. * Peer authentication
  65. *----------------------------------------------------------------
  66. */
  67. static int auth_peer(hbaPort *port);
  68. /*----------------------------------------------------------------
  69. * PAM authentication
  70. *----------------------------------------------------------------
  71. */
  72. #ifdef USE_PAM
  73. #ifdef HAVE_PAM_PAM_APPL_H
  74. #include <pam/pam_appl.h>
  75. #endif
  76. #ifdef HAVE_SECURITY_PAM_APPL_H
  77. #include <security/pam_appl.h>
  78. #endif
  79. #define PGSQL_PAM_SERVICE "postgresql" /* Service name passed to PAM */
  80. static int CheckPAMAuth(Port *port, const char *user, const char *password);
  81. static int pam_passwd_conv_proc(int num_msg, const struct pam_message **msg,
  82. struct pam_response **resp, void *appdata_ptr);
  83. static struct pam_conv pam_passw_conv = {
  84. &pam_passwd_conv_proc,
  85. NULL
  86. };
  87. static const char *pam_passwd = NULL; /* Workaround for Solaris 2.6
  88. * brokenness */
  89. static Port *pam_port_cludge; /* Workaround for passing "Port *port" into
  90. * pam_passwd_conv_proc */
  91. static bool pam_no_password; /* For detecting no-password-given */
  92. #endif /* USE_PAM */
  93. /*----------------------------------------------------------------
  94. * BSD authentication
  95. *----------------------------------------------------------------
  96. */
  97. #ifdef USE_BSD_AUTH
  98. #include <bsd_auth.h>
  99. static int CheckBSDAuth(Port *port, char *user);
  100. #endif /* USE_BSD_AUTH */
  101. /*----------------------------------------------------------------
  102. * LDAP authentication
  103. *----------------------------------------------------------------
  104. */
  105. #ifdef USE_LDAP
  106. #ifndef WIN32
  107. /* We use a deprecated function to keep the codepath the same as win32. */
  108. #define LDAP_DEPRECATED 1
  109. #include <ldap.h>
  110. #else
  111. #include <winldap.h>
  112. /* Correct header from the Platform SDK */
  113. typedef
  114. ULONG (*__ldap_start_tls_sA) (IN PLDAP ExternalHandle,
  115. OUT PULONG ServerReturnValue,
  116. OUT LDAPMessage **result,
  117. IN PLDAPControlA * ServerControls,
  118. IN PLDAPControlA * ClientControls
  119. );
  120. #endif
  121. static int CheckLDAPAuth(Port *port);
  122. /* LDAP_OPT_DIAGNOSTIC_MESSAGE is the newer spelling */
  123. #ifndef LDAP_OPT_DIAGNOSTIC_MESSAGE
  124. #define LDAP_OPT_DIAGNOSTIC_MESSAGE LDAP_OPT_ERROR_STRING
  125. #endif
  126. #endif /* USE_LDAP */
  127. /*----------------------------------------------------------------
  128. * Cert authentication
  129. *----------------------------------------------------------------
  130. */
  131. #ifdef USE_SSL
  132. static int CheckCertAuth(Port *port);
  133. #endif
  134. /*----------------------------------------------------------------
  135. * Kerberos and GSSAPI GUCs
  136. *----------------------------------------------------------------
  137. */
  138. char *pg_krb_server_keyfile;
  139. bool pg_krb_caseins_users;
  140. /*----------------------------------------------------------------
  141. * GSSAPI Authentication
  142. *----------------------------------------------------------------
  143. */
  144. #ifdef ENABLE_GSS
  145. #include "libpq/be-gssapi-common.h"
  146. static int pg_GSS_checkauth(Port *port);
  147. static int pg_GSS_recvauth(Port *port);
  148. #endif /* ENABLE_GSS */
  149. /*----------------------------------------------------------------
  150. * SSPI Authentication
  151. *----------------------------------------------------------------
  152. */
  153. #ifdef ENABLE_SSPI
  154. typedef SECURITY_STATUS
  155. (WINAPI * QUERY_SECURITY_CONTEXT_TOKEN_FN) (PCtxtHandle, void **);
  156. static int pg_SSPI_recvauth(Port *port);
  157. static int pg_SSPI_make_upn(char *accountname,
  158. size_t accountnamesize,
  159. char *domainname,
  160. size_t domainnamesize,
  161. bool update_accountname);
  162. #endif
  163. /*----------------------------------------------------------------
  164. * RADIUS Authentication
  165. *----------------------------------------------------------------
  166. */
  167. static int CheckRADIUSAuth(Port *port);
  168. static int PerformRadiusTransaction(const char *server, const char *secret, const char *portstr, const char *identifier, const char *user_name, const char *passwd);
  169. /*
  170. * Maximum accepted size of GSS and SSPI authentication tokens.
  171. *
  172. * Kerberos tickets are usually quite small, but the TGTs issued by Windows
  173. * domain controllers include an authorization field known as the Privilege
  174. * Attribute Certificate (PAC), which contains the user's Windows permissions
  175. * (group memberships etc.). The PAC is copied into all tickets obtained on
  176. * the basis of this TGT (even those issued by Unix realms which the Windows
  177. * realm trusts), and can be several kB in size. The maximum token size
  178. * accepted by Windows systems is determined by the MaxAuthToken Windows
  179. * registry setting. Microsoft recommends that it is not set higher than
  180. * 65535 bytes, so that seems like a reasonable limit for us as well.
  181. */
  182. #define PG_MAX_AUTH_TOKEN_LENGTH 65535
  183. /*
  184. * Maximum accepted size of SASL messages.
  185. *
  186. * The messages that the server or libpq generate are much smaller than this,
  187. * but have some headroom.
  188. */
  189. #define PG_MAX_SASL_MESSAGE_LENGTH 1024
  190. /*----------------------------------------------------------------
  191. * Global authentication functions
  192. *----------------------------------------------------------------
  193. */
  194. /*
  195. * This hook allows plugins to get control following client authentication,
  196. * but before the user has been informed about the results. It could be used
  197. * to record login events, insert a delay after failed authentication, etc.
  198. */
  199. ClientAuthentication_hook_type ClientAuthentication_hook = NULL;
  200. /*
  201. * Tell the user the authentication failed, but not (much about) why.
  202. *
  203. * There is a tradeoff here between security concerns and making life
  204. * unnecessarily difficult for legitimate users. We would not, for example,
  205. * want to report the password we were expecting to receive...
  206. * But it seems useful to report the username and authorization method
  207. * in use, and these are items that must be presumed known to an attacker
  208. * anyway.
  209. * Note that many sorts of failure report additional information in the
  210. * postmaster log, which we hope is only readable by good guys. In
  211. * particular, if logdetail isn't NULL, we send that string to the log.
  212. */
  213. static void
  214. auth_failed(Port *port, int status, char *logdetail)
  215. {
  216. const char *errstr;
  217. char *cdetail;
  218. int errcode_return = ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION;
  219. /*
  220. * If we failed due to EOF from client, just quit; there's no point in
  221. * trying to send a message to the client, and not much point in logging
  222. * the failure in the postmaster log. (Logging the failure might be
  223. * desirable, were it not for the fact that libpq closes the connection
  224. * unceremoniously if challenged for a password when it hasn't got one to
  225. * send. We'll get a useless log entry for every psql connection under
  226. * password auth, even if it's perfectly successful, if we log STATUS_EOF
  227. * events.)
  228. */
  229. if (status == STATUS_EOF)
  230. proc_exit(0);
  231. switch (port->hba->auth_method)
  232. {
  233. case uaReject:
  234. case uaImplicitReject:
  235. errstr = gettext_noop("authentication failed for user \"%s\": host rejected");
  236. break;
  237. case uaTrust:
  238. errstr = gettext_noop("\"trust\" authentication failed for user \"%s\"");
  239. break;
  240. case uaIdent:
  241. errstr = gettext_noop("Ident authentication failed for user \"%s\"");
  242. break;
  243. case uaPeer:
  244. errstr = gettext_noop("Peer authentication failed for user \"%s\"");
  245. break;
  246. case uaPassword:
  247. case uaMD5:
  248. case uaSCRAM:
  249. errstr = gettext_noop("password authentication failed for user \"%s\"");
  250. /* We use it to indicate if a .pgpass password failed. */
  251. errcode_return = ERRCODE_INVALID_PASSWORD;
  252. break;
  253. case uaGSS:
  254. errstr = gettext_noop("GSSAPI authentication failed for user \"%s\"");
  255. break;
  256. case uaSSPI:
  257. errstr = gettext_noop("SSPI authentication failed for user \"%s\"");
  258. break;
  259. case uaPAM:
  260. errstr = gettext_noop("PAM authentication failed for user \"%s\"");
  261. break;
  262. case uaBSD:
  263. errstr = gettext_noop("BSD authentication failed for user \"%s\"");
  264. break;
  265. case uaLDAP:
  266. errstr = gettext_noop("LDAP authentication failed for user \"%s\"");
  267. break;
  268. case uaCert:
  269. errstr = gettext_noop("certificate authentication failed for user \"%s\"");
  270. break;
  271. case uaRADIUS:
  272. errstr = gettext_noop("RADIUS authentication failed for user \"%s\"");
  273. break;
  274. default:
  275. errstr = gettext_noop("authentication failed for user \"%s\": invalid authentication method");
  276. break;
  277. }
  278. cdetail = psprintf(_("Connection matched pg_hba.conf line %d: \"%s\""),
  279. port->hba->linenumber, port->hba->rawline);
  280. if (logdetail)
  281. logdetail = psprintf("%s\n%s", logdetail, cdetail);
  282. else
  283. logdetail = cdetail;
  284. ereport(FATAL,
  285. (errcode(errcode_return),
  286. errmsg(errstr, port->user_name),
  287. logdetail ? errdetail_log("%s", logdetail) : 0));
  288. /* doesn't return */
  289. }
  290. /*
  291. * Client authentication starts here. If there is an error, this
  292. * function does not return and the backend process is terminated.
  293. */
  294. void
  295. ClientAuthentication(Port *port)
  296. {
  297. int status = STATUS_ERROR;
  298. char *logdetail = NULL;
  299. /*
  300. * Get the authentication method to use for this frontend/database
  301. * combination. Note: we do not parse the file at this point; this has
  302. * already been done elsewhere. hba.c dropped an error message into the
  303. * server logfile if parsing the hba config file failed.
  304. */
  305. hba_getauthmethod(port);
  306. CHECK_FOR_INTERRUPTS();
  307. /*
  308. * This is the first point where we have access to the hba record for the
  309. * current connection, so perform any verifications based on the hba
  310. * options field that should be done *before* the authentication here.
  311. */
  312. if (port->hba->clientcert != clientCertOff)
  313. {
  314. /* If we haven't loaded a root certificate store, fail */
  315. if (!secure_loaded_verify_locations())
  316. ereport(FATAL,
  317. (errcode(ERRCODE_CONFIG_FILE_ERROR),
  318. errmsg("client certificates can only be checked if a root certificate store is available")));
  319. /*
  320. * If we loaded a root certificate store, and if a certificate is
  321. * present on the client, then it has been verified against our root
  322. * certificate store, and the connection would have been aborted
  323. * already if it didn't verify ok.
  324. */
  325. if (!port->peer_cert_valid)
  326. ereport(FATAL,
  327. (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
  328. errmsg("connection requires a valid client certificate")));
  329. }
  330. #ifdef ENABLE_GSS
  331. if (port->gss->enc && port->hba->auth_method != uaReject &&
  332. port->hba->auth_method != uaImplicitReject &&
  333. port->hba->auth_method != uaTrust &&
  334. port->hba->auth_method != uaGSS)
  335. {
  336. ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
  337. errmsg("GSSAPI encryption can only be used with gss, trust, or reject authentication methods")));
  338. }
  339. #endif
  340. /*
  341. * Now proceed to do the actual authentication check
  342. */
  343. switch (port->hba->auth_method)
  344. {
  345. case uaReject:
  346. /*
  347. * An explicit "reject" entry in pg_hba.conf. This report exposes
  348. * the fact that there's an explicit reject entry, which is
  349. * perhaps not so desirable from a security standpoint; but the
  350. * message for an implicit reject could confuse the DBA a lot when
  351. * the true situation is a match to an explicit reject. And we
  352. * don't want to change the message for an implicit reject. As
  353. * noted below, the additional information shown here doesn't
  354. * expose anything not known to an attacker.
  355. */
  356. {
  357. char hostinfo[NI_MAXHOST];
  358. pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
  359. hostinfo, sizeof(hostinfo),
  360. NULL, 0,
  361. NI_NUMERICHOST);
  362. if (am_walsender)
  363. {
  364. #ifdef USE_SSL
  365. ereport(FATAL,
  366. (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
  367. errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
  368. hostinfo, port->user_name,
  369. port->ssl_in_use ? _("SSL on") : _("SSL off"))));
  370. #else
  371. ereport(FATAL,
  372. (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
  373. errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"",
  374. hostinfo, port->user_name)));
  375. #endif
  376. }
  377. else
  378. {
  379. #ifdef USE_SSL
  380. ereport(FATAL,
  381. (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
  382. errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
  383. hostinfo, port->user_name,
  384. port->database_name,
  385. port->ssl_in_use ? _("SSL on") : _("SSL off"))));
  386. #else
  387. ereport(FATAL,
  388. (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
  389. errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"",
  390. hostinfo, port->user_name,
  391. port->database_name)));
  392. #endif
  393. }
  394. break;
  395. }
  396. case uaImplicitReject:
  397. /*
  398. * No matching entry, so tell the user we fell through.
  399. *
  400. * NOTE: the extra info reported here is not a security breach,
  401. * because all that info is known at the frontend and must be
  402. * assumed known to bad guys. We're merely helping out the less
  403. * clueful good guys.
  404. */
  405. {
  406. char hostinfo[NI_MAXHOST];
  407. pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
  408. hostinfo, sizeof(hostinfo),
  409. NULL, 0,
  410. NI_NUMERICHOST);
  411. #define HOSTNAME_LOOKUP_DETAIL(port) \
  412. (port->remote_hostname ? \
  413. (port->remote_hostname_resolv == +1 ? \
  414. errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \
  415. port->remote_hostname) : \
  416. port->remote_hostname_resolv == 0 ? \
  417. errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", \
  418. port->remote_hostname) : \
  419. port->remote_hostname_resolv == -1 ? \
  420. errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", \
  421. port->remote_hostname) : \
  422. port->remote_hostname_resolv == -2 ? \
  423. errdetail_log("Could not translate client host name \"%s\" to IP address: %s.", \
  424. port->remote_hostname, \
  425. gai_strerror(port->remote_hostname_errcode)) : \
  426. 0) \
  427. : (port->remote_hostname_resolv == -2 ? \
  428. errdetail_log("Could not resolve client IP address to a host name: %s.", \
  429. gai_strerror(port->remote_hostname_errcode)) : \
  430. 0))
  431. if (am_walsender)
  432. {
  433. #ifdef USE_SSL
  434. ereport(FATAL,
  435. (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
  436. errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
  437. hostinfo, port->user_name,
  438. port->ssl_in_use ? _("SSL on") : _("SSL off")),
  439. HOSTNAME_LOOKUP_DETAIL(port)));
  440. #else
  441. ereport(FATAL,
  442. (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
  443. errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"",
  444. hostinfo, port->user_name),
  445. HOSTNAME_LOOKUP_DETAIL(port)));
  446. #endif
  447. }
  448. else
  449. {
  450. #ifdef USE_SSL
  451. ereport(FATAL,
  452. (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
  453. errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
  454. hostinfo, port->user_name,
  455. port->database_name,
  456. port->ssl_in_use ? _("SSL on") : _("SSL off")),
  457. HOSTNAME_LOOKUP_DETAIL(port)));
  458. #else
  459. ereport(FATAL,
  460. (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
  461. errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"",
  462. hostinfo, port->user_name,
  463. port->database_name),
  464. HOSTNAME_LOOKUP_DETAIL(port)));
  465. #endif
  466. }
  467. break;
  468. }
  469. case uaGSS:
  470. #ifdef ENABLE_GSS
  471. port->gss->auth = true;
  472. if (port->gss->enc)
  473. status = pg_GSS_checkauth(port);
  474. else
  475. {
  476. sendAuthRequest(port, AUTH_REQ_GSS, NULL, 0);
  477. status = pg_GSS_recvauth(port);
  478. }
  479. #else
  480. Assert(false);
  481. #endif
  482. break;
  483. case uaSSPI:
  484. #ifdef ENABLE_SSPI
  485. sendAuthRequest(port, AUTH_REQ_SSPI, NULL, 0);
  486. status = pg_SSPI_recvauth(port);
  487. #else
  488. Assert(false);
  489. #endif
  490. break;
  491. case uaPeer:
  492. status = auth_peer(port);
  493. break;
  494. case uaIdent:
  495. status = ident_inet(port);
  496. break;
  497. case uaMD5:
  498. case uaSCRAM:
  499. status = CheckPWChallengeAuth(port, &logdetail);
  500. break;
  501. case uaPassword:
  502. status = CheckPasswordAuth(port, &logdetail);
  503. break;
  504. case uaPAM:
  505. #ifdef USE_PAM
  506. status = CheckPAMAuth(port, port->user_name, "");
  507. #else
  508. Assert(false);
  509. #endif /* USE_PAM */
  510. break;
  511. case uaBSD:
  512. #ifdef USE_BSD_AUTH
  513. status = CheckBSDAuth(port, port->user_name);
  514. #else
  515. Assert(false);
  516. #endif /* USE_BSD_AUTH */
  517. break;
  518. case uaLDAP:
  519. #ifdef USE_LDAP
  520. status = CheckLDAPAuth(port);
  521. #else
  522. Assert(false);
  523. #endif
  524. break;
  525. case uaRADIUS:
  526. status = CheckRADIUSAuth(port);
  527. break;
  528. case uaCert:
  529. /* uaCert will be treated as if clientcert=verify-full (uaTrust) */
  530. case uaTrust:
  531. status = STATUS_OK;
  532. break;
  533. }
  534. if ((status == STATUS_OK && port->hba->clientcert == clientCertFull)
  535. || port->hba->auth_method == uaCert)
  536. {
  537. /*
  538. * Make sure we only check the certificate if we use the cert method
  539. * or verify-full option.
  540. */
  541. #ifdef USE_SSL
  542. status = CheckCertAuth(port);
  543. #else
  544. Assert(false);
  545. #endif
  546. }
  547. if (ClientAuthentication_hook)
  548. (*ClientAuthentication_hook) (port, status);
  549. if (status == STATUS_OK)
  550. sendAuthRequest(port, AUTH_REQ_OK, NULL, 0);
  551. else
  552. auth_failed(port, status, logdetail);
  553. }
  554. /*
  555. * Send an authentication request packet to the frontend.
  556. */
  557. static void
  558. sendAuthRequest(Port *port, AuthRequest areq, const char *extradata, int extralen)
  559. {
  560. StringInfoData buf;
  561. CHECK_FOR_INTERRUPTS();
  562. pq_beginmessage(&buf, 'R');
  563. pq_sendint32(&buf, (int32) areq);
  564. if (extralen > 0)
  565. pq_sendbytes(&buf, extradata, extralen);
  566. pq_endmessage(&buf);
  567. /*
  568. * Flush message so client will see it, except for AUTH_REQ_OK and
  569. * AUTH_REQ_SASL_FIN, which need not be sent until we are ready for
  570. * queries.
  571. */
  572. if (areq != AUTH_REQ_OK && areq != AUTH_REQ_SASL_FIN)
  573. pq_flush();
  574. CHECK_FOR_INTERRUPTS();
  575. }
  576. /*
  577. * Collect password response packet from frontend.
  578. *
  579. * Returns NULL if couldn't get password, else palloc'd string.
  580. */
  581. static char *
  582. recv_password_packet(Port *port)
  583. {
  584. StringInfoData buf;
  585. pq_startmsgread();
  586. if (PG_PROTOCOL_MAJOR(port->proto) >= 3)
  587. {
  588. /* Expect 'p' message type */
  589. int mtype;
  590. mtype = pq_getbyte();
  591. if (mtype != 'p')
  592. {
  593. /*
  594. * If the client just disconnects without offering a password,
  595. * don't make a log entry. This is legal per protocol spec and in
  596. * fact commonly done by psql, so complaining just clutters the
  597. * log.
  598. */
  599. if (mtype != EOF)
  600. ereport(ERROR,
  601. (errcode(ERRCODE_PROTOCOL_VIOLATION),
  602. errmsg("expected password response, got message type %d",
  603. mtype)));
  604. return NULL; /* EOF or bad message type */
  605. }
  606. }
  607. else
  608. {
  609. /* For pre-3.0 clients, avoid log entry if they just disconnect */
  610. if (pq_peekbyte() == EOF)
  611. return NULL; /* EOF */
  612. }
  613. initStringInfo(&buf);
  614. if (pq_getmessage(&buf, 1000)) /* receive password */
  615. {
  616. /* EOF - pq_getmessage already logged a suitable message */
  617. pfree(buf.data);
  618. return NULL;
  619. }
  620. /*
  621. * Apply sanity check: password packet length should agree with length of
  622. * contained string. Note it is safe to use strlen here because
  623. * StringInfo is guaranteed to have an appended '\0'.
  624. */
  625. if (strlen(buf.data) + 1 != buf.len)
  626. ereport(ERROR,
  627. (errcode(ERRCODE_PROTOCOL_VIOLATION),
  628. errmsg("invalid password packet size")));
  629. /*
  630. * Don't allow an empty password. Libpq treats an empty password the same
  631. * as no password at all, and won't even try to authenticate. But other
  632. * clients might, so allowing it would be confusing.
  633. *
  634. * Note that this only catches an empty password sent by the client in
  635. * plaintext. There's also a check in CREATE/ALTER USER that prevents an
  636. * empty string from being stored as a user's password in the first place.
  637. * We rely on that for MD5 and SCRAM authentication, but we still need
  638. * this check here, to prevent an empty password from being used with
  639. * authentication methods that check the password against an external
  640. * system, like PAM, LDAP and RADIUS.
  641. */
  642. if (buf.len == 1)
  643. ereport(ERROR,
  644. (errcode(ERRCODE_INVALID_PASSWORD),
  645. errmsg("empty password returned by client")));
  646. /* Do not echo password to logs, for security. */
  647. elog(DEBUG5, "received password packet");
  648. /*
  649. * Return the received string. Note we do not attempt to do any
  650. * character-set conversion on it; since we don't yet know the client's
  651. * encoding, there wouldn't be much point.
  652. */
  653. return buf.data;
  654. }
  655. /*----------------------------------------------------------------
  656. * Password-based authentication mechanisms
  657. *----------------------------------------------------------------
  658. */
  659. /*
  660. * Plaintext password authentication.
  661. */
  662. static int
  663. CheckPasswordAuth(Port *port, char **logdetail)
  664. {
  665. char *passwd;
  666. int result;
  667. char *shadow_pass;
  668. sendAuthRequest(port, AUTH_REQ_PASSWORD, NULL, 0);
  669. passwd = recv_password_packet(port);
  670. if (passwd == NULL)
  671. return STATUS_EOF; /* client wouldn't send password */
  672. shadow_pass = get_role_password(port->user_name, logdetail);
  673. if (shadow_pass)
  674. {
  675. result = plain_crypt_verify(port->user_name, shadow_pass, passwd,
  676. logdetail);
  677. }
  678. else
  679. result = STATUS_ERROR;
  680. if (shadow_pass)
  681. pfree(shadow_pass);
  682. pfree(passwd);
  683. return result;
  684. }
  685. /*
  686. * MD5 and SCRAM authentication.
  687. */
  688. static int
  689. CheckPWChallengeAuth(Port *port, char **logdetail)
  690. {
  691. int auth_result;
  692. char *shadow_pass;
  693. PasswordType pwtype;
  694. Assert(port->hba->auth_method == uaSCRAM ||
  695. port->hba->auth_method == uaMD5);
  696. /* First look up the user's password. */
  697. shadow_pass = get_role_password(port->user_name, logdetail);
  698. /*
  699. * If the user does not exist, or has no password or it's expired, we
  700. * still go through the motions of authentication, to avoid revealing to
  701. * the client that the user didn't exist. If 'md5' is allowed, we choose
  702. * whether to use 'md5' or 'scram-sha-256' authentication based on current
  703. * password_encryption setting. The idea is that most genuine users
  704. * probably have a password of that type, and if we pretend that this user
  705. * had a password of that type, too, it "blends in" best.
  706. */
  707. if (!shadow_pass)
  708. pwtype = Password_encryption;
  709. else
  710. pwtype = get_password_type(shadow_pass);
  711. /*
  712. * If 'md5' authentication is allowed, decide whether to perform 'md5' or
  713. * 'scram-sha-256' authentication based on the type of password the user
  714. * has. If it's an MD5 hash, we must do MD5 authentication, and if it's a
  715. * SCRAM secret, we must do SCRAM authentication.
  716. *
  717. * If MD5 authentication is not allowed, always use SCRAM. If the user
  718. * had an MD5 password, CheckSCRAMAuth() will fail.
  719. */
  720. if (port->hba->auth_method == uaMD5 && pwtype == PASSWORD_TYPE_MD5)
  721. auth_result = CheckMD5Auth(port, shadow_pass, logdetail);
  722. else
  723. auth_result = CheckSCRAMAuth(port, shadow_pass, logdetail);
  724. if (shadow_pass)
  725. pfree(shadow_pass);
  726. /*
  727. * If get_role_password() returned error, return error, even if the
  728. * authentication succeeded.
  729. */
  730. if (!shadow_pass)
  731. {
  732. Assert(auth_result != STATUS_OK);
  733. return STATUS_ERROR;
  734. }
  735. return auth_result;
  736. }
  737. static int
  738. CheckMD5Auth(Port *port, char *shadow_pass, char **logdetail)
  739. {
  740. char md5Salt[4]; /* Password salt */
  741. char *passwd;
  742. int result;
  743. if (Db_user_namespace)
  744. ereport(FATAL,
  745. (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
  746. errmsg("MD5 authentication is not supported when \"db_user_namespace\" is enabled")));
  747. /* include the salt to use for computing the response */
  748. if (!pg_strong_random(md5Salt, 4))
  749. {
  750. ereport(LOG,
  751. (errmsg("could not generate random MD5 salt")));
  752. return STATUS_ERROR;
  753. }
  754. sendAuthRequest(port, AUTH_REQ_MD5, md5Salt, 4);
  755. passwd = recv_password_packet(port);
  756. if (passwd == NULL)
  757. return STATUS_EOF; /* client wouldn't send password */
  758. if (shadow_pass)
  759. result = md5_crypt_verify(port->user_name, shadow_pass, passwd,
  760. md5Salt, 4, logdetail);
  761. else
  762. result = STATUS_ERROR;
  763. pfree(passwd);
  764. return result;
  765. }
  766. static int
  767. CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail)
  768. {
  769. StringInfoData sasl_mechs;
  770. int mtype;
  771. StringInfoData buf;
  772. void *scram_opaq = NULL;
  773. char *output = NULL;
  774. int outputlen = 0;
  775. const char *input;
  776. int inputlen;
  777. int result;
  778. bool initial;
  779. /*
  780. * SASL auth is not supported for protocol versions before 3, because it
  781. * relies on the overall message length word to determine the SASL payload
  782. * size in AuthenticationSASLContinue and PasswordMessage messages. (We
  783. * used to have a hard rule that protocol messages must be parsable
  784. * without relying on the length word, but we hardly care about older
  785. * protocol version anymore.)
  786. */
  787. if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
  788. ereport(FATAL,
  789. (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  790. errmsg("SASL authentication is not supported in protocol version 2")));
  791. /*
  792. * Send the SASL authentication request to user. It includes the list of
  793. * authentication mechanisms that are supported.
  794. */
  795. initStringInfo(&sasl_mechs);
  796. pg_be_scram_get_mechanisms(port, &sasl_mechs);
  797. /* Put another '\0' to mark that list is finished. */
  798. appendStringInfoChar(&sasl_mechs, '\0');
  799. sendAuthRequest(port, AUTH_REQ_SASL, sasl_mechs.data, sasl_mechs.len);
  800. pfree(sasl_mechs.data);
  801. /*
  802. * Loop through SASL message exchange. This exchange can consist of
  803. * multiple messages sent in both directions. First message is always
  804. * from the client. All messages from client to server are password
  805. * packets (type 'p').
  806. */
  807. initial = true;
  808. do
  809. {
  810. pq_startmsgread();
  811. mtype = pq_getbyte();
  812. if (mtype != 'p')
  813. {
  814. /* Only log error if client didn't disconnect. */
  815. if (mtype != EOF)
  816. {
  817. ereport(ERROR,
  818. (errcode(ERRCODE_PROTOCOL_VIOLATION),
  819. errmsg("expected SASL response, got message type %d",
  820. mtype)));
  821. }
  822. else
  823. return STATUS_EOF;
  824. }
  825. /* Get the actual SASL message */
  826. initStringInfo(&buf);
  827. if (pq_getmessage(&buf, PG_MAX_SASL_MESSAGE_LENGTH))
  828. {
  829. /* EOF - pq_getmessage already logged error */
  830. pfree(buf.data);
  831. return STATUS_ERROR;
  832. }
  833. elog(DEBUG4, "processing received SASL response of length %d", buf.len);
  834. /*
  835. * The first SASLInitialResponse message is different from the others.
  836. * It indicates which SASL mechanism the client selected, and contains
  837. * an optional Initial Client Response payload. The subsequent
  838. * SASLResponse messages contain just the SASL payload.
  839. */
  840. if (initial)
  841. {
  842. const char *selected_mech;
  843. selected_mech = pq_getmsgrawstring(&buf);
  844. /*
  845. * Initialize the status tracker for message exchanges.
  846. *
  847. * If the user doesn't exist, or doesn't have a valid password, or
  848. * it's expired, we still go through the motions of SASL
  849. * authentication, but tell the authentication method that the
  850. * authentication is "doomed". That is, it's going to fail, no
  851. * matter what.
  852. *
  853. * This is because we don't want to reveal to an attacker what
  854. * usernames are valid, nor which users have a valid password.
  855. */
  856. scram_opaq = pg_be_scram_init(port, selected_mech, shadow_pass);
  857. inputlen = pq_getmsgint(&buf, 4);
  858. if (inputlen == -1)
  859. input = NULL;
  860. else
  861. input = pq_getmsgbytes(&buf, inputlen);
  862. initial = false;
  863. }
  864. else
  865. {
  866. inputlen = buf.len;
  867. input = pq_getmsgbytes(&buf, buf.len);
  868. }
  869. pq_getmsgend(&buf);
  870. /*
  871. * The StringInfo guarantees that there's a \0 byte after the
  872. * response.
  873. */
  874. Assert(input == NULL || input[inputlen] == '\0');
  875. /*
  876. * we pass 'logdetail' as NULL when doing a mock authentication,
  877. * because we should already have a better error message in that case
  878. */
  879. result = pg_be_scram_exchange(scram_opaq, input, inputlen,
  880. &output, &outputlen,
  881. logdetail);
  882. /* input buffer no longer used */
  883. pfree(buf.data);
  884. if (output)
  885. {
  886. /*
  887. * Negotiation generated data to be sent to the client.
  888. */
  889. elog(DEBUG4, "sending SASL challenge of length %u", outputlen);
  890. if (result == SASL_EXCHANGE_SUCCESS)
  891. sendAuthRequest(port, AUTH_REQ_SASL_FIN, output, outputlen);
  892. else
  893. sendAuthRequest(port, AUTH_REQ_SASL_CONT, output, outputlen);
  894. pfree(output);
  895. }
  896. } while (result == SASL_EXCHANGE_CONTINUE);
  897. /* Oops, Something bad happened */
  898. if (result != SASL_EXCHANGE_SUCCESS)
  899. {
  900. return STATUS_ERROR;
  901. }
  902. return STATUS_OK;
  903. }
  904. /*----------------------------------------------------------------
  905. * GSSAPI authentication system
  906. *----------------------------------------------------------------
  907. */
  908. #ifdef ENABLE_GSS
  909. static int
  910. pg_GSS_recvauth(Port *port)
  911. {
  912. OM_uint32 maj_stat,
  913. min_stat,
  914. lmin_s,
  915. gflags;
  916. int mtype;
  917. StringInfoData buf;
  918. gss_buffer_desc gbuf;
  919. /*
  920. * GSS auth is not supported for protocol versions before 3, because it
  921. * relies on the overall message length word to determine the GSS payload
  922. * size in AuthenticationGSSContinue and PasswordMessage messages. (This
  923. * is, in fact, a design error in our GSS support, because protocol
  924. * messages are supposed to be parsable without relying on the length
  925. * word; but it's not worth changing it now.)
  926. */
  927. if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
  928. ereport(FATAL,
  929. (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  930. errmsg("GSSAPI is not supported in protocol version 2")));
  931. if (pg_krb_server_keyfile && strlen(pg_krb_server_keyfile) > 0)
  932. {
  933. /*
  934. * Set default Kerberos keytab file for the Krb5 mechanism.
  935. *
  936. * setenv("KRB5_KTNAME", pg_krb_server_keyfile, 0); except setenv()
  937. * not always available.
  938. */
  939. if (getenv("KRB5_KTNAME") == NULL)
  940. {
  941. size_t kt_len = strlen(pg_krb_server_keyfile) + 14;
  942. char *kt_path = malloc(kt_len);
  943. if (!kt_path ||
  944. snprintf(kt_path, kt_len, "KRB5_KTNAME=%s",
  945. pg_krb_server_keyfile) != kt_len - 2 ||
  946. putenv(kt_path) != 0)
  947. {
  948. ereport(LOG,
  949. (errcode(ERRCODE_OUT_OF_MEMORY),
  950. errmsg("out of memory")));
  951. return STATUS_ERROR;
  952. }
  953. }
  954. }
  955. /*
  956. * We accept any service principal that's present in our keytab. This
  957. * increases interoperability between kerberos implementations that see
  958. * for example case sensitivity differently, while not really opening up
  959. * any vector of attack.
  960. */
  961. port->gss->cred = GSS_C_NO_CREDENTIAL;
  962. /*
  963. * Initialize sequence with an empty context
  964. */
  965. port->gss->ctx = GSS_C_NO_CONTEXT;
  966. /*
  967. * Loop through GSSAPI message exchange. This exchange can consist of
  968. * multiple messages sent in both directions. First message is always from
  969. * the client. All messages from client to server are password packets
  970. * (type 'p').
  971. */
  972. do
  973. {
  974. pq_startmsgread();
  975. CHECK_FOR_INTERRUPTS();
  976. mtype = pq_getbyte();
  977. if (mtype != 'p')
  978. {
  979. /* Only log error if client didn't disconnect. */
  980. if (mtype != EOF)
  981. ereport(ERROR,
  982. (errcode(ERRCODE_PROTOCOL_VIOLATION),
  983. errmsg("expected GSS response, got message type %d",
  984. mtype)));
  985. return STATUS_ERROR;
  986. }
  987. /* Get the actual GSS token */
  988. initStringInfo(&buf);
  989. if (pq_getmessage(&buf, PG_MAX_AUTH_TOKEN_LENGTH))
  990. {
  991. /* EOF - pq_getmessage already logged error */
  992. pfree(buf.data);
  993. return STATUS_ERROR;
  994. }
  995. /* Map to GSSAPI style buffer */
  996. gbuf.length = buf.len;
  997. gbuf.value = buf.data;
  998. elog(DEBUG4, "processing received GSS token of length %u",
  999. (unsigned int) gbuf.length);
  1000. maj_stat = gss_accept_sec_context(&min_stat,
  1001. &port->gss->ctx,
  1002. port->gss->cred,
  1003. &gbuf,
  1004. GSS_C_NO_CHANNEL_BINDINGS,
  1005. &port->gss->name,
  1006. NULL,
  1007. &port->gss->outbuf,
  1008. &gflags,
  1009. NULL,
  1010. NULL);
  1011. /* gbuf no longer used */
  1012. pfree(buf.data);
  1013. elog(DEBUG5, "gss_accept_sec_context major: %d, "
  1014. "minor: %d, outlen: %u, outflags: %x",
  1015. maj_stat, min_stat,
  1016. (unsigned int) port->gss->outbuf.length, gflags);
  1017. CHECK_FOR_INTERRUPTS();
  1018. if (port->gss->outbuf.length != 0)
  1019. {
  1020. /*
  1021. * Negotiation generated data to be sent to the client.
  1022. */
  1023. elog(DEBUG4, "sending GSS response token of length %u",
  1024. (unsigned int) port->gss->outbuf.length);
  1025. sendAuthRequest(port, AUTH_REQ_GSS_CONT,
  1026. port->gss->outbuf.value, port->gss->outbuf.length);
  1027. gss_release_buffer(&lmin_s, &port->gss->outbuf);
  1028. }
  1029. if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
  1030. {
  1031. gss_delete_sec_context(&lmin_s, &port->gss->ctx, GSS_C_NO_BUFFER);
  1032. pg_GSS_error(ERROR,
  1033. _("accepting GSS security context failed"),
  1034. maj_stat, min_stat);
  1035. }
  1036. if (maj_stat == GSS_S_CONTINUE_NEEDED)
  1037. elog(DEBUG4, "GSS continue needed");
  1038. } while (maj_stat == GSS_S_CONTINUE_NEEDED);
  1039. if (port->gss->cred != GSS_C_NO_CREDENTIAL)
  1040. {
  1041. /*
  1042. * Release service principal credentials
  1043. */
  1044. gss_release_cred(&min_stat, &port->gss->cred);
  1045. }
  1046. return pg_GSS_checkauth(port);
  1047. }
  1048. /*
  1049. * Check whether the GSSAPI-authenticated user is allowed to connect as the
  1050. * claimed username.
  1051. */
  1052. static int
  1053. pg_GSS_checkauth(Port *port)
  1054. {
  1055. int ret;
  1056. OM_uint32 maj_stat,
  1057. min_stat,
  1058. lmin_s;
  1059. gss_buffer_desc gbuf;
  1060. /*
  1061. * Get the name of the user that authenticated, and compare it to the pg
  1062. * username that was specified for the connection.
  1063. */
  1064. maj_stat = gss_display_name(&min_stat, port->gss->name, &gbuf, NULL);
  1065. if (maj_stat != GSS_S_COMPLETE)
  1066. pg_GSS_error(ERROR,
  1067. _("retrieving GSS user name failed"),
  1068. maj_stat, min_stat);
  1069. /*
  1070. * Copy the original name of the authenticated principal into our backend
  1071. * memory for display later.
  1072. */
  1073. port->gss->princ = MemoryContextStrdup(TopMemoryContext, gbuf.value);
  1074. /*
  1075. * Split the username at the realm separator
  1076. */
  1077. if (strchr(gbuf.value, '@'))
  1078. {
  1079. char *cp = strchr(gbuf.value, '@');
  1080. /*
  1081. * If we are not going to include the realm in the username that is
  1082. * passed to the ident map, destructively modify it here to remove the
  1083. * realm. Then advance past the separator to check the realm.
  1084. */
  1085. if (!port->hba->include_realm)
  1086. *cp = '\0';
  1087. cp++;
  1088. if (port->hba->krb_realm != NULL && strlen(port->hba->krb_realm))
  1089. {
  1090. /*
  1091. * Match the realm part of the name first
  1092. */
  1093. if (pg_krb_caseins_users)
  1094. ret = pg_strcasecmp(port->hba->krb_realm, cp);
  1095. else
  1096. ret = strcmp(port->hba->krb_realm, cp);
  1097. if (ret)
  1098. {
  1099. /* GSS realm does not match */
  1100. elog(DEBUG2,
  1101. "GSSAPI realm (%s) and configured realm (%s) don't match",
  1102. cp, port->hba->krb_realm);
  1103. gss_release_buffer(&lmin_s, &gbuf);
  1104. return STATUS_ERROR;
  1105. }
  1106. }
  1107. }
  1108. else if (port->hba->krb_realm && strlen(port->hba->krb_realm))
  1109. {
  1110. elog(DEBUG2,
  1111. "GSSAPI did not return realm but realm matching was requested");
  1112. gss_release_buffer(&lmin_s, &gbuf);
  1113. return STATUS_ERROR;
  1114. }
  1115. ret = check_usermap(port->hba->usermap, port->user_name, gbuf.value,
  1116. pg_krb_caseins_users);
  1117. gss_release_buffer(&lmin_s, &gbuf);
  1118. return ret;
  1119. }
  1120. #endif /* ENABLE_GSS */
  1121. /*----------------------------------------------------------------
  1122. * SSPI authentication system
  1123. *----------------------------------------------------------------
  1124. */
  1125. #ifdef ENABLE_SSPI
  1126. /*
  1127. * Generate an error for SSPI authentication. The caller should apply
  1128. * _() to errmsg to make it translatable.
  1129. */
  1130. static void
  1131. pg_SSPI_error(int severity, const char *errmsg, SECURITY_STATUS r)
  1132. {
  1133. char sysmsg[256];
  1134. if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS |
  1135. FORMAT_MESSAGE_FROM_SYSTEM,
  1136. NULL, r, 0,
  1137. sysmsg, sizeof(sysmsg), NULL) == 0)
  1138. ereport(severity,
  1139. (errmsg_internal("%s", errmsg),
  1140. errdetail_internal("SSPI error %x", (unsigned int) r)));
  1141. else
  1142. ereport(severity,
  1143. (errmsg_internal("%s", errmsg),
  1144. errdetail_internal("%s (%x)", sysmsg, (unsigned int) r)));
  1145. }
  1146. static int
  1147. pg_SSPI_recvauth(Port *port)
  1148. {
  1149. int mtype;
  1150. StringInfoData buf;
  1151. SECURITY_STATUS r;
  1152. CredHandle sspicred;
  1153. CtxtHandle *sspictx = NULL,
  1154. newctx;
  1155. TimeStamp expiry;
  1156. ULONG contextattr;
  1157. SecBufferDesc inbuf;
  1158. SecBufferDesc outbuf;
  1159. SecBuffer OutBuffers[1];
  1160. SecBuffer InBuffers[1];
  1161. HANDLE token;
  1162. TOKEN_USER *tokenuser;
  1163. DWORD retlen;
  1164. char accountname[MAXPGPATH];
  1165. char domainname[MAXPGPATH];
  1166. DWORD accountnamesize = sizeof(accountname);
  1167. DWORD domainnamesize = sizeof(domainname);
  1168. SID_NAME_USE accountnameuse;
  1169. HMODULE secur32;
  1170. QUERY_SECURITY_CONTEXT_TOKEN_FN _QuerySecurityContextToken;
  1171. /*
  1172. * SSPI auth is not supported for protocol versions before 3, because it
  1173. * relies on the overall message length word to determine the SSPI payload
  1174. * size in AuthenticationGSSContinue and PasswordMessage messages. (This
  1175. * is, in fact, a design error in our SSPI support, because protocol
  1176. * messages are supposed to be parsable without relying on the length
  1177. * word; but it's not worth changing it now.)
  1178. */
  1179. if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
  1180. ereport(FATAL,
  1181. (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  1182. errmsg("SSPI is not supported in protocol version 2")));
  1183. /*
  1184. * Acquire a handle to the server credentials.
  1185. */
  1186. r = AcquireCredentialsHandle(NULL,
  1187. "negotiate",
  1188. SECPKG_CRED_INBOUND,
  1189. NULL,
  1190. NULL,
  1191. NULL,
  1192. NULL,
  1193. &sspicred,
  1194. &expiry);
  1195. if (r != SEC_E_OK)
  1196. pg_SSPI_error(ERROR, _("could not acquire SSPI credentials"), r);
  1197. /*
  1198. * Loop through SSPI message exchange. This exchange can consist of
  1199. * multiple messages sent in both directions. First message is always from
  1200. * the client. All messages from client to server are password packets
  1201. * (type 'p').
  1202. */
  1203. do
  1204. {
  1205. pq_startmsgread();
  1206. mtype = pq_getbyte();
  1207. if (mtype != 'p')
  1208. {
  1209. if (sspictx != NULL)
  1210. {
  1211. DeleteSecurityContext(sspictx);
  1212. free(sspictx);
  1213. }
  1214. FreeCredentialsHandle(&sspicred);
  1215. /* Only log error if client didn't disconnect. */
  1216. if (mtype != EOF)
  1217. ereport(ERROR,
  1218. (errcode(ERRCODE_PROTOCOL_VIOLATION),
  1219. errmsg("expected SSPI response, got message type %d",
  1220. mtype)));
  1221. return STATUS_ERROR;
  1222. }
  1223. /* Get the actual SSPI token */
  1224. initStringInfo(&buf);
  1225. if (pq_getmessage(&buf, PG_MAX_AUTH_TOKEN_LENGTH))
  1226. {
  1227. /* EOF - pq_getmessage already logged error */
  1228. pfree(buf.data);
  1229. if (sspictx != NULL)
  1230. {
  1231. DeleteSecurityContext(sspictx);
  1232. free(sspictx);
  1233. }
  1234. FreeCredentialsHandle(&sspicred);
  1235. return STATUS_ERROR;
  1236. }
  1237. /* Map to SSPI style buffer */
  1238. inbuf.ulVersion = SECBUFFER_VERSION;
  1239. inbuf.cBuffers = 1;
  1240. inbuf.pBuffers = InBuffers;
  1241. InBuffers[0].pvBuffer = buf.data;
  1242. InBuffers[0].cbBuffer = buf.len;
  1243. InBuffers[0].BufferType = SECBUFFER_TOKEN;
  1244. /* Prepare output buffer */
  1245. OutBuffers[0].pvBuffer = NULL;
  1246. OutBuffers[0].BufferType = SECBUFFER_TOKEN;
  1247. OutBuffers[0].cbBuffer = 0;
  1248. outbuf.cBuffers = 1;
  1249. outbuf.pBuffers = OutBuffers;
  1250. outbuf.ulVersion = SECBUFFER_VERSION;
  1251. elog(DEBUG4, "processing received SSPI token of length %u",
  1252. (unsigned int) buf.len);
  1253. r = AcceptSecurityContext(&sspicred,
  1254. sspictx,
  1255. &inbuf,
  1256. ASC_REQ_ALLOCATE_MEMORY,
  1257. SECURITY_NETWORK_DREP,
  1258. &newctx,
  1259. &outbuf,
  1260. &contextattr,
  1261. NULL);
  1262. /* input buffer no longer used */
  1263. pfree(buf.data);
  1264. if (outbuf.cBuffers > 0 && outbuf.pBuffers[0].cbBuffer > 0)
  1265. {
  1266. /*
  1267. * Negotiation generated data to be sent to the client.
  1268. */
  1269. elog(DEBUG4, "sending SSPI response token of length %u",
  1270. (unsigned int) outbuf.pBuffers[0].cbBuffer);
  1271. port->gss->outbuf.length = outbuf.pBuffers[0].cbBuffer;
  1272. port->gss->outbuf.value = outbuf.pBuffers[0].pvBuffer;
  1273. sendAuthRequest(port, AUTH_REQ_GSS_CONT,
  1274. port->gss->outbuf.value, port->gss->outbuf.length);
  1275. FreeContextBuffer(outbuf.pBuffers[0].pvBuffer);
  1276. }
  1277. if (r != SEC_E_OK && r != SEC_I_CONTINUE_NEEDED)
  1278. {
  1279. if (sspictx != NULL)
  1280. {
  1281. DeleteSecurityContext(sspictx);
  1282. free(sspictx);
  1283. }
  1284. FreeCredentialsHandle(&sspicred);
  1285. pg_SSPI_error(ERROR,
  1286. _("could not accept SSPI security context"), r);
  1287. }
  1288. /*
  1289. * Overwrite the current context with the one we just received. If
  1290. * sspictx is NULL it was the first loop and we need to allocate a
  1291. * buffer for it. On subsequent runs, we can just overwrite the buffer
  1292. * contents since the size does not change.
  1293. */
  1294. if (sspictx == NULL)
  1295. {
  1296. sspictx = malloc(sizeof(CtxtHandle));
  1297. if (sspictx == NULL)
  1298. ereport(ERROR,
  1299. (errmsg("out of memory")));
  1300. }
  1301. memcpy(sspictx, &newctx, sizeof(CtxtHandle));
  1302. if (r == SEC_I_CONTINUE_NEEDED)
  1303. elog(DEBUG4, "SSPI continue needed");
  1304. } while (r == SEC_I_CONTINUE_NEEDED);
  1305. /*
  1306. * Release service principal credentials
  1307. */
  1308. FreeCredentialsHandle(&sspicred);
  1309. /*
  1310. * SEC_E_OK indicates that authentication is now complete.
  1311. *
  1312. * Get the name of the user that authenticated, and compare it to the pg
  1313. * username that was specified for the connection.
  1314. *
  1315. * MingW is missing the export for QuerySecurityContextToken in the
  1316. * secur32 library, so we have to load it dynamically.
  1317. */
  1318. secur32 = LoadLibrary("SECUR32.DLL");
  1319. if (secur32 == NULL)
  1320. ereport(ERROR,
  1321. (errmsg("could not load library \"%s\": error code %lu",
  1322. "SECUR32.DLL", GetLastError())));
  1323. _QuerySecurityContextToken = (QUERY_SECURITY_CONTEXT_TOKEN_FN)
  1324. GetProcAddress(secur32, "QuerySecurityContextToken");
  1325. if (_QuerySecurityContextToken == NULL)
  1326. {
  1327. FreeLibrary(secur32);
  1328. ereport(ERROR,
  1329. (errmsg_internal("could not locate QuerySecurityContextToken in secur32.dll: error code %lu",
  1330. GetLastError())));
  1331. }
  1332. r = (_QuerySecurityContextToken) (sspictx, &token);
  1333. if (r != SEC_E_OK)
  1334. {
  1335. FreeLibrary(secur32);
  1336. pg_SSPI_error(ERROR,
  1337. _("could not get token from SSPI security context"), r);
  1338. }
  1339. FreeLibrary(secur32);
  1340. /*
  1341. * No longer need the security context, everything from here on uses the
  1342. * token instead.
  1343. */
  1344. DeleteSecurityContext(sspictx);
  1345. free(sspictx);
  1346. if (!GetTokenInformation(token, TokenUser, NULL, 0, &retlen) && GetLastError() != 122)
  1347. ereport(ERROR,
  1348. (errmsg_internal("could not get token information buffer size: error code %lu",
  1349. GetLastError())));
  1350. tokenuser = malloc(retlen);
  1351. if (tokenuser == NULL)
  1352. ereport(ERROR,
  1353. (errmsg("out of memory")));
  1354. if (!GetTokenInformation(token, TokenUser, tokenuser, retlen, &retlen))
  1355. ereport(ERROR,
  1356. (errmsg_internal("could not get token information: error code %lu",
  1357. GetLastError())));
  1358. CloseHandle(token);
  1359. if (!LookupAccountSid(NULL, tokenuser->User.Sid, accountname, &accountnamesize,
  1360. domainname, &domainnamesize, &accountnameuse))
  1361. ereport(ERROR,
  1362. (errmsg_internal("could not look up account SID: error code %lu",
  1363. GetLastError())));
  1364. free(tokenuser);
  1365. if (!port->hba->compat_realm)
  1366. {
  1367. int status = pg_SSPI_make_upn(accountname, sizeof(accountname),
  1368. domainname, sizeof(domainname),
  1369. port->hba->upn_username);
  1370. if (status != STATUS_OK)
  1371. /* Error already reported from pg_SSPI_make_upn */
  1372. return status;
  1373. }
  1374. /*
  1375. * Compare realm/domain if requested. In SSPI, always compare case
  1376. * insensitive.
  1377. */
  1378. if (port->hba->krb_realm && strlen(port->hba->krb_realm))
  1379. {
  1380. if (pg_strcasecmp(port->hba->krb_realm, domainname) != 0)
  1381. {
  1382. elog(DEBUG2,
  1383. "SSPI domain (%s) and configured domain (%s) don't match",
  1384. domainname, port->hba->krb_realm);
  1385. return STATUS_ERROR;
  1386. }
  1387. }
  1388. /*
  1389. * We have the username (without domain/realm) in accountname, compare to
  1390. * the supplied value. In SSPI, always compare case insensitive.
  1391. *
  1392. * If set to include realm, append it in <username>@<realm> format.
  1393. */
  1394. if (port->hba->include_realm)
  1395. {
  1396. char *namebuf;
  1397. int retval;
  1398. namebuf = psprintf("%s@%s", accountname, domainname);
  1399. retval = check_usermap(port->hba->usermap, port->user_name, namebuf, true);
  1400. pfree(namebuf);
  1401. return retval;
  1402. }
  1403. else
  1404. return check_usermap(port->hba->usermap, port->user_name, accountname, true);
  1405. }
  1406. /*
  1407. * Replaces the domainname with the Kerberos realm name,
  1408. * and optionally the accountname with the Kerberos user name.
  1409. */
  1410. static int
  1411. pg_SSPI_make_upn(char *accountname,
  1412. size_t accountnamesize,
  1413. char *domainname,
  1414. size_t domainnamesize,
  1415. bool update_accountname)
  1416. {
  1417. char *samname;
  1418. char *upname = NULL;
  1419. char *p = NULL;
  1420. ULONG upnamesize = 0;
  1421. size_t upnamerealmsize;
  1422. BOOLEAN res;
  1423. /*
  1424. * Build SAM name (DOMAIN\user), then translate to UPN
  1425. * (user@kerberos.realm). The realm name is returned in lower case, but
  1426. * that is fine because in SSPI auth, string comparisons are always
  1427. * case-insensitive.
  1428. */
  1429. samname = psprintf("%s\\%s", domainname, accountname);
  1430. res = TranslateName(samname, NameSamCompatible, NameUserPrincipal,
  1431. NULL, &upnamesize);
  1432. if ((!res && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  1433. || upnamesize == 0)
  1434. {
  1435. pfree(samname);
  1436. ereport(LOG,
  1437. (errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
  1438. errmsg("could not translate name")));
  1439. return STATUS_ERROR;
  1440. }
  1441. /* upnamesize includes the terminating NUL. */
  1442. upname = palloc(upnamesize);
  1443. res = TranslateName(samname, NameSamCompatible, NameUserPrincipal,
  1444. upname, &upnamesize);
  1445. pfree(samname);
  1446. if (res)
  1447. p = strchr(upname, '@');
  1448. if (!res || p == NULL)
  1449. {
  1450. pfree(upname);
  1451. ereport(LOG,
  1452. (errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
  1453. errmsg("could not translate name")));
  1454. return STATUS_ERROR;
  1455. }
  1456. /* Length of realm name after the '@', including the NUL. */
  1457. upnamerealmsize = upnamesize - (p - upname + 1);
  1458. /* Replace domainname with realm name. */
  1459. if (upnamerealmsize > domainnamesize)
  1460. {
  1461. pfree(upname);
  1462. ereport(LOG,
  1463. (errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
  1464. errmsg("realm name too long")));
  1465. return STATUS_ERROR;
  1466. }
  1467. /* Length is now safe. */
  1468. strcpy(domainname, p + 1);
  1469. /* Replace account name as well (in case UPN != SAM)? */
  1470. if (update_accountname)
  1471. {
  1472. if ((p - upname + 1) > accountnamesize)
  1473. {
  1474. pfree(upname);
  1475. ereport(LOG,
  1476. (errcode(ERRCODE_INVALID_ROLE_SPECIFICATION),
  1477. errmsg("translated account name too long")));
  1478. return STATUS_ERROR;
  1479. }
  1480. *p = 0;
  1481. strcpy(accountname, upname);
  1482. }
  1483. pfree(upname);
  1484. return STATUS_OK;
  1485. }
  1486. #endif /* ENABLE_SSPI */
  1487. /*----------------------------------------------------------------
  1488. * Ident authentication system
  1489. *----------------------------------------------------------------
  1490. */
  1491. /*
  1492. * Parse the string "*ident_response" as a response from a query to an Ident
  1493. * server. If it's a normal response indicating a user name, return true
  1494. * and store the user name at *ident_user. If it's anything else,
  1495. * return false.
  1496. */
  1497. static bool
  1498. interpret_ident_response(const char *ident_response,
  1499. char *ident_user)
  1500. {
  1501. const char *cursor = ident_response; /* Cursor into *ident_response */
  1502. /*
  1503. * Ident's response, in the telnet tradition, should end in crlf (\r\n).
  1504. */
  1505. if (strlen(ident_response) < 2)
  1506. return false;
  1507. else if (ident_response[strlen(ident_response) - 2] != '\r')
  1508. return false;
  1509. else
  1510. {
  1511. while (*cursor != ':' && *cursor != '\r')
  1512. cursor++; /* skip port field */
  1513. if (*cursor != ':')
  1514. return false;
  1515. else
  1516. {
  1517. /* We're positioned to colon before response type field */
  1518. char response_type[80];
  1519. int i; /* Index into *response_type */
  1520. cursor++; /* Go over colon */
  1521. while (pg_isblank(*cursor))
  1522. cursor++; /* skip blanks */
  1523. i = 0;
  1524. while (*cursor != ':' && *cursor != '\r' && !pg_isblank(*cursor) &&
  1525. i < (int) (sizeof(response_type) - 1))
  1526. response_type[i++] = *cursor++;
  1527. response_type[i] = '\0';
  1528. while (pg_isblank(*cursor))
  1529. cursor++; /* skip blanks */
  1530. if (strcmp(response_type, "USERID") != 0)
  1531. return false;
  1532. else
  1533. {
  1534. /*
  1535. * It's a USERID response. Good. "cursor" should be pointing
  1536. * to the colon that precedes the operating system type.
  1537. */
  1538. if (*cursor != ':')
  1539. return false;
  1540. else
  1541. {
  1542. cursor++; /* Go over colon */
  1543. /* Skip over operating system field. */
  1544. while (*cursor != ':' && *cursor != '\r')
  1545. cursor++;
  1546. if (*cursor != ':')
  1547. return false;
  1548. else
  1549. {
  1550. int i; /* Index into *ident_user */
  1551. cursor++; /* Go over colon */
  1552. while (pg_isblank(*cursor))
  1553. cursor++; /* skip blanks */
  1554. /* Rest of line is user name. Copy it over. */
  1555. i = 0;
  1556. while (*cursor != '\r' && i < IDENT_USERNAME_MAX)
  1557. ident_user[i++] = *cursor++;
  1558. ident_user[i] = '\0';
  1559. return true;
  1560. }
  1561. }
  1562. }
  1563. }
  1564. }
  1565. }
  1566. /*
  1567. * Talk to the ident server on "remote_addr" and find out who
  1568. * owns the tcp connection to "local_addr"
  1569. * If the username is successfully retrieved, check the usermap.
  1570. *
  1571. * XXX: Using WaitLatchOrSocket() and doing a CHECK_FOR_INTERRUPTS() if the
  1572. * latch was set would improve the responsiveness to timeouts/cancellations.
  1573. */
  1574. static int
  1575. ident_inet(hbaPort *port)
  1576. {
  1577. const SockAddr remote_addr = port->raddr;
  1578. const SockAddr local_addr = port->laddr;
  1579. char ident_user[IDENT_USERNAME_MAX + 1];
  1580. pgsocket sock_fd = PGINVALID_SOCKET; /* for talking to Ident server */
  1581. int rc; /* Return code from a locally called function */
  1582. bool ident_return;
  1583. char remote_addr_s[NI_MAXHOST];
  1584. char remote_port[NI_MAXSERV];
  1585. char local_addr_s[NI_MAXHOST];
  1586. char local_port[NI_MAXSERV];
  1587. char ident_port[NI_MAXSERV];
  1588. char ident_query[80];
  1589. char ident_response[80 + IDENT_USERNAME_MAX];
  1590. struct addrinfo *ident_serv = NULL,
  1591. *la = NULL,
  1592. hints;
  1593. /*
  1594. * Might look a little weird to first convert it to text and then back to
  1595. * sockaddr, but it's protocol independent.
  1596. */
  1597. pg_getnameinfo_all(&remote_addr.addr, remote_addr.salen,
  1598. remote_addr_s, sizeof(remote_addr_s),
  1599. remote_port, sizeof(remote_port),
  1600. NI_NUMERICHOST | NI_NUMERICSERV);
  1601. pg_getnameinfo_all(&local_addr.addr, local_addr.salen,
  1602. local_addr_s, sizeof(local_addr_s),
  1603. local_port, sizeof(local_port),
  1604. NI_NUMERICHOST | NI_NUMERICSERV);
  1605. snprintf(ident_port, sizeof(ident_port), "%d", IDENT_PORT);
  1606. hints.ai_flags = AI_NUMERICHOST;
  1607. hints.ai_family = remote_addr.addr.ss_family;
  1608. hints.ai_socktype = SOCK_STREAM;
  1609. hints.ai_protocol = 0;
  1610. hints.ai_addrlen = 0;
  1611. hints.ai_canonname = NULL;
  1612. hints.ai_addr = NULL;
  1613. hints.ai_next = NULL;
  1614. rc = pg_getaddrinfo_all(remote_addr_s, ident_port, &hints, &ident_serv);
  1615. if (rc || !ident_serv)
  1616. {
  1617. /* we don't expect this to happen */
  1618. ident_return = false;
  1619. goto ident_inet_done;
  1620. }
  1621. hints.ai_flags = AI_NUMERICHOST;
  1622. hints.ai_family = local_addr.addr.ss_family;
  1623. hints.ai_socktype = SOCK_STREAM;
  1624. hints.ai_protocol = 0;
  1625. hints.ai_addrlen = 0;
  1626. hints.ai_canonname = NULL;
  1627. hints.ai_addr = NULL;
  1628. hints.ai_next = NULL;
  1629. rc = pg_getaddrinfo_all(local_addr_s, NULL, &hints, &la);
  1630. if (rc || !la)
  1631. {
  1632. /* we don't expect this to happen */
  1633. ident_return = false;
  1634. goto ident_inet_done;
  1635. }
  1636. sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
  1637. ident_serv->ai_protocol);
  1638. if (sock_fd == PGINVALID_SOCKET)
  1639. {
  1640. ereport(LOG,
  1641. (errcode_for_socket_access(),
  1642. errmsg("could not create socket for Ident connection: %m")));
  1643. ident_return = false;
  1644. goto ident_inet_done;
  1645. }
  1646. /*
  1647. * Bind to the address which the client originally contacted, otherwise
  1648. * the ident server won't be able to match up the right connection. This
  1649. * is necessary if the PostgreSQL server is running on an IP alias.
  1650. */
  1651. rc = bind(sock_fd, la->ai_addr, la->ai_addrlen);
  1652. if (rc != 0)
  1653. {
  1654. ereport(LOG,
  1655. (errcode_for_socket_access(),
  1656. errmsg("could not bind to local address \"%s\": %m",
  1657. local_addr_s)));
  1658. ident_return = false;
  1659. goto ident_inet_done;
  1660. }
  1661. rc = connect(sock_fd, ident_serv->ai_addr,
  1662. ident_serv->ai_addrlen);
  1663. if (rc != 0)
  1664. {
  1665. ereport(LOG,
  1666. (errcode_for_socket_access(),
  1667. errmsg("could not connect to Ident server at address \"%s\", port %s: %m",
  1668. remote_addr_s, ident_port)));
  1669. ident_return = false;
  1670. goto ident_inet_done;
  1671. }
  1672. /* The query we send to the Ident server */
  1673. snprintf(ident_query, sizeof(ident_query), "%s,%s\r\n",
  1674. remote_port, local_port);
  1675. /* loop in case send is interrupted */
  1676. do
  1677. {
  1678. CHECK_FOR_INTERRUPTS();
  1679. rc = send(sock_fd, ident_query, strlen(ident_query), 0);
  1680. } while (rc < 0 && errno == EINTR);
  1681. if (rc < 0)
  1682. {
  1683. ereport(LOG,
  1684. (errcode_for_socket_access(),
  1685. errmsg("could not send query to Ident server at address \"%s\", port %s: %m",
  1686. remote_addr_s, ident_port)));
  1687. ident_return = false;
  1688. goto ident_inet_done;
  1689. }
  1690. do
  1691. {
  1692. CHECK_FOR_INTERRUPTS();
  1693. rc = recv(sock_fd, ident_response, sizeof(ident_response) - 1, 0);
  1694. } while (rc < 0 && errno == EINTR);
  1695. if (rc < 0)
  1696. {
  1697. ereport(LOG,
  1698. (errcode_for_socket_access(),
  1699. errmsg("could not receive response from Ident server at address \"%s\", port %s: %m",
  1700. remote_addr_s, ident_port)));
  1701. ident_return = false;
  1702. goto ident_inet_done;
  1703. }
  1704. ident_response[rc] = '\0';
  1705. ident_return = interpret_ident_response(ident_response, ident_user);
  1706. if (!ident_return)
  1707. ereport(LOG,
  1708. (errmsg("invalidly formatted response from Ident server: \"%s\"",
  1709. ident_response)));
  1710. ident_inet_done:
  1711. if (sock_fd != PGINVALID_SOCKET)
  1712. closesocket(sock_fd);
  1713. if (ident_serv)
  1714. pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
  1715. if (la)
  1716. pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
  1717. if (ident_return)
  1718. /* Success! Check the usermap */
  1719. return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
  1720. return STATUS_ERROR;
  1721. }
  1722. /*----------------------------------------------------------------
  1723. * Peer authentication system
  1724. *----------------------------------------------------------------
  1725. */
  1726. /*
  1727. * Ask kernel about the credentials of the connecting process,
  1728. * determine the symbolic name of the corresponding user, and check
  1729. * if valid per the usermap.
  1730. *
  1731. * Iff authorized, return STATUS_OK, otherwise return STATUS_ERROR.
  1732. */
  1733. static int
  1734. auth_peer(hbaPort *port)
  1735. {
  1736. uid_t uid;
  1737. gid_t gid;
  1738. #ifndef WIN32
  1739. struct passwd *pw;
  1740. char *peer_user;
  1741. int ret;
  1742. #endif
  1743. if (getpeereid(port->sock, &uid, &gid) != 0)
  1744. {
  1745. /* Provide special error message if getpeereid is a stub */
  1746. if (errno == ENOSYS)
  1747. ereport(LOG,
  1748. (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
  1749. errmsg("peer authentication is not supported on this platform")));
  1750. else
  1751. ereport(LOG,
  1752. (errcode_for_socket_access(),
  1753. errmsg("could not get peer credentials: %m")));
  1754. return STATUS_ERROR;
  1755. }
  1756. #ifndef WIN32
  1757. errno = 0; /* clear errno before call */
  1758. pw = getpwuid(uid);
  1759. if (!pw)
  1760. {
  1761. int save_errno = errno;
  1762. ereport(LOG,
  1763. (errmsg("could not look up local user ID %ld: %s",
  1764. (long) uid,
  1765. save_errno ? strerror(save_errno) : _("user does not exist"))));
  1766. return STATUS_ERROR;
  1767. }
  1768. /* Make a copy of static getpw*() result area. */
  1769. peer_user = pstrdup(pw->pw_name);
  1770. ret = check_usermap(port->hba->usermap, port->user_name, peer_user, false);
  1771. pfree(peer_user);
  1772. return ret;
  1773. #else
  1774. /* should have failed with ENOSYS above */
  1775. Assert(false);
  1776. return STATUS_ERROR;
  1777. #endif
  1778. }
  1779. /*----------------------------------------------------------------
  1780. * PAM authentication system
  1781. *----------------------------------------------------------------
  1782. */
  1783. #ifdef USE_PAM
  1784. /*
  1785. * PAM conversation function
  1786. */
  1787. static int
  1788. pam_passwd_conv_proc(int num_msg, const struct pam_message **msg,
  1789. struct pam_response **resp, void *appdata_ptr)
  1790. {
  1791. const char *passwd;
  1792. struct pam_response *reply;
  1793. int i;
  1794. if (appdata_ptr)
  1795. passwd = (char *) appdata_ptr;
  1796. else
  1797. {
  1798. /*
  1799. * Workaround for Solaris 2.6 where the PAM library is broken and does
  1800. * not pass appdata_ptr to the conversation routine
  1801. */
  1802. passwd = pam_passwd;
  1803. }
  1804. *resp = NULL; /* in case of error exit */
  1805. if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG)
  1806. return PAM_CONV_ERR;
  1807. /*
  1808. * Explicitly not using palloc here - PAM will free this memory in
  1809. * pam_end()
  1810. */
  1811. if ((reply = calloc(num_msg, sizeof(struct pam_response))) == NULL)
  1812. {
  1813. ereport(LOG,
  1814. (errcode(ERRCODE_OUT_OF_MEMORY),
  1815. errmsg("out of memory")));
  1816. return PAM_CONV_ERR;
  1817. }
  1818. for (i = 0; i < num_msg; i++)
  1819. {
  1820. switch (msg[i]->msg_style)
  1821. {
  1822. case PAM_PROMPT_ECHO_OFF:
  1823. if (strlen(passwd) == 0)
  1824. {
  1825. /*
  1826. * Password wasn't passed to PAM the first time around -
  1827. * let's go ask the client to send a password, which we
  1828. * then stuff into PAM.
  1829. */
  1830. sendAuthRequest(pam_port_cludge, AUTH_REQ_PASSWORD, NULL, 0);
  1831. passwd = recv_password_packet(pam_port_cludge);
  1832. if (passwd == NULL)
  1833. {
  1834. /*
  1835. * Client didn't want to send password. We
  1836. * intentionally do not log anything about this,
  1837. * either here or at higher levels.
  1838. */
  1839. pam_no_password = true;
  1840. goto fail;
  1841. }
  1842. }
  1843. if ((reply[i].resp = strdup(passwd)) == NULL)
  1844. goto fail;
  1845. reply[i].resp_retcode = PAM_SUCCESS;
  1846. break;
  1847. case PAM_ERROR_MSG:
  1848. ereport(LOG,
  1849. (errmsg("error from underlying PAM layer: %s",
  1850. msg[i]->msg)));
  1851. /* FALL THROUGH */
  1852. case PAM_TEXT_INFO:
  1853. /* we don't bother to log TEXT_INFO messages */
  1854. if ((reply[i].resp = strdup("")) == NULL)
  1855. goto fail;
  1856. reply[i].resp_retcode = PAM_SUCCESS;
  1857. break;
  1858. default:
  1859. elog(LOG, "unsupported PAM conversation %d/\"%s\"",
  1860. msg[i]->msg_style,
  1861. msg[i]->msg ? msg[i]->msg : "(none)");
  1862. goto fail;
  1863. }
  1864. }
  1865. *resp = reply;
  1866. return PAM_SUCCESS;
  1867. fail:
  1868. /* free up whatever we allocated */
  1869. for (i = 0; i < num_msg; i++)
  1870. {
  1871. if (reply[i].resp != NULL)
  1872. free(reply[i].resp);
  1873. }
  1874. free(reply);
  1875. return PAM_CONV_ERR;
  1876. }
  1877. /*
  1878. * Check authentication against PAM.
  1879. */
  1880. static int
  1881. CheckPAMAuth(Port *port, const char *user, const char *password)
  1882. {
  1883. int retval;
  1884. pam_handle_t *pamh = NULL;
  1885. /*
  1886. * We can't entirely rely on PAM to pass through appdata --- it appears
  1887. * not to work on at least Solaris 2.6. So use these ugly static
  1888. * variables instead.
  1889. */
  1890. pam_passwd = password;
  1891. pam_port_cludge = port;
  1892. pam_no_password = false;
  1893. /*
  1894. * Set the application data portion of the conversation struct. This is
  1895. * later used inside the PAM conversation to pass the password to the
  1896. * authentication module.
  1897. */
  1898. pam_passw_conv.appdata_ptr = unconstify(char *, password); /* from password above,
  1899. * not allocated */
  1900. /* Optionally, one can set the service name in pg_hba.conf */
  1901. if (port->hba->pamservice && port->hba->pamservice[0] != '\0')
  1902. retval = pam_start(port->hba->pamservice, "pgsql@",
  1903. &pam_passw_conv, &pamh);
  1904. else
  1905. retval = pam_start(PGSQL_PAM_SERVICE, "pgsql@",
  1906. &pam_passw_conv, &pamh);
  1907. if (retval != PAM_SUCCESS)
  1908. {
  1909. ereport(LOG,
  1910. (errmsg("could not create PAM authenticator: %s",
  1911. pam_strerror(pamh, retval))));
  1912. pam_passwd = NULL; /* Unset pam_passwd */
  1913. return STATUS_ERROR;
  1914. }
  1915. retval = pam_set_item(pamh, PAM_USER, user);
  1916. if (retval != PAM_SUCCESS)
  1917. {
  1918. ereport(LOG,
  1919. (errmsg("pam_set_item(PAM_USER) failed: %s",
  1920. pam_strerror(pamh, retval))));
  1921. pam_passwd = NULL; /* Unset pam_passwd */
  1922. return STATUS_ERROR;
  1923. }
  1924. if (port->hba->conntype != ctLocal)
  1925. {
  1926. char hostinfo[NI_MAXHOST];
  1927. int flags;
  1928. if (port->hba->pam_use_hostname)
  1929. flags = 0;
  1930. else
  1931. flags = NI_NUMERICHOST | NI_NUMERICSERV;
  1932. retval = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
  1933. hostinfo, sizeof(hostinfo), NULL, 0,
  1934. flags);
  1935. if (retval != 0)
  1936. {
  1937. ereport(WARNING,
  1938. (errmsg_internal("pg_getnameinfo_all() failed: %s",
  1939. gai_strerror(retval))));
  1940. return STATUS_ERROR;
  1941. }
  1942. retval = pam_set_item(pamh, PAM_RHOST, hostinfo);
  1943. if (retval != PAM_SUCCESS)
  1944. {
  1945. ereport(LOG,
  1946. (errmsg("pam_set_item(PAM_RHOST) failed: %s",
  1947. pam_strerror(pamh, retval))));
  1948. pam_passwd = NULL;
  1949. return STATUS_ERROR;
  1950. }
  1951. }
  1952. retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv);
  1953. if (retval != PAM_SUCCESS)
  1954. {
  1955. ereport(LOG,
  1956. (errmsg("pam_set_item(PAM_CONV) failed: %s",
  1957. pam_strerror(pamh, retval))));
  1958. pam_passwd = NULL; /* Unset pam_passwd */
  1959. return STATUS_ERROR;
  1960. }
  1961. retval = pam_authenticate(pamh, 0);
  1962. if (retval != PAM_SUCCESS)
  1963. {
  1964. /* If pam_passwd_conv_proc saw EOF, don't log anything */
  1965. if (!pam_no_password)
  1966. ereport(LOG,
  1967. (errmsg("pam_authenticate failed: %s",
  1968. pam_strerror(pamh, retval))));
  1969. pam_passwd = NULL; /* Unset pam_passwd */
  1970. return pam_no_password ? STATUS_EOF : STATUS_ERROR;
  1971. }
  1972. retval = pam_acct_mgmt(pamh, 0);
  1973. if (retval != PAM_SUCCESS)
  1974. {
  1975. /* If pam_passwd_conv_proc saw EOF, don't log anything */
  1976. if (!pam_no_password)
  1977. ereport(LOG,
  1978. (errmsg("pam_acct_mgmt failed: %s",
  1979. pam_strerror(pamh, retval))));
  1980. pam_passwd = NULL; /* Unset pam_passwd */
  1981. return pam_no_password ? STATUS_EOF : STATUS_ERROR;
  1982. }
  1983. retval = pam_end(pamh, retval);
  1984. if (retval != PAM_SUCCESS)
  1985. {
  1986. ereport(LOG,
  1987. (errmsg("could not release PAM authenticator: %s",
  1988. pam_strerror(pamh, retval))));
  1989. }
  1990. pam_passwd = NULL; /* Unset pam_passwd */
  1991. return (retval == PAM_SUCCESS ? STATUS_OK : STATUS_ERROR);
  1992. }
  1993. #endif /* USE_PAM */
  1994. /*----------------------------------------------------------------
  1995. * BSD authentication system
  1996. *----------------------------------------------------------------
  1997. */
  1998. #ifdef USE_BSD_AUTH
  1999. static int
  2000. CheckBSDAuth(Port *port, char *user)
  2001. {
  2002. char *passwd;
  2003. int retval;
  2004. /* Send regular password request to client, and get the response */
  2005. sendAuthRequest(port, AUTH_REQ_PASSWORD, NULL, 0);
  2006. passwd = recv_password_packet(port);
  2007. if (passwd == NULL)
  2008. return STATUS_EOF;
  2009. /*
  2010. * Ask the BSD auth system to verify password. Note that auth_userokay
  2011. * will overwrite the password string with zeroes, but it's just a
  2012. * temporary string so we don't care.
  2013. */
  2014. retval = auth_userokay(user, NULL, "auth-postgresql", passwd);
  2015. pfree(passwd);
  2016. if (!retval)
  2017. return STATUS_ERROR;
  2018. return STATUS_OK;
  2019. }
  2020. #endif /* USE_BSD_AUTH */
  2021. /*----------------------------------------------------------------
  2022. * LDAP authentication system
  2023. *----------------------------------------------------------------
  2024. */
  2025. #ifdef USE_LDAP
  2026. static int errdetail_for_ldap(LDAP *ldap);
  2027. /*
  2028. * Initialize a connection to the LDAP server, including setting up
  2029. * TLS if requested.
  2030. */
  2031. static int
  2032. InitializeLDAPConnection(Port *port, LDAP **ldap)
  2033. {
  2034. const char *scheme;
  2035. int ldapversion = LDAP_VERSION3;
  2036. int r;
  2037. scheme = port->hba->ldapscheme;
  2038. if (scheme == NULL)
  2039. scheme = "ldap";
  2040. #ifdef WIN32
  2041. if (strcmp(scheme, "ldaps") == 0)
  2042. *ldap = ldap_sslinit(port->hba->ldapserver, port->hba->ldapport, 1);
  2043. else
  2044. *ldap = ldap_init(port->hba->ldapserver, port->hba->ldapport);
  2045. if (!*ldap)
  2046. {
  2047. ereport(LOG,
  2048. (errmsg("could not initialize LDAP: error code %d",
  2049. (int) LdapGetLastError())));
  2050. return STATUS_ERROR;
  2051. }
  2052. #else
  2053. #ifdef HAVE_LDAP_INITIALIZE
  2054. /*
  2055. * OpenLDAP provides a non-standard extension ldap_initialize() that takes
  2056. * a list of URIs, allowing us to request "ldaps" instead of "ldap". It
  2057. * also provides ldap_domain2hostlist() to find LDAP servers automatically
  2058. * using DNS SRV. They were introduced in the same version, so for now we
  2059. * don't have an extra configure check for the latter.
  2060. */
  2061. {
  2062. StringInfoData uris;
  2063. char *hostlist = NULL;
  2064. char *p;
  2065. bool append_port;
  2066. /* We'll build a space-separated scheme://hostname:port list here */
  2067. initStringInfo(&uris);
  2068. /*
  2069. * If pg_hba.conf provided no hostnames, we can ask OpenLDAP to try to
  2070. * find some by extracting a domain name from the base DN and looking
  2071. * up DSN SRV records for _ldap._tcp.<domain>.
  2072. */
  2073. if (!port->hba->ldapserver || port->hba->ldapserver[0] == '\0')
  2074. {
  2075. char *domain;
  2076. /* ou=blah,dc=foo,dc=bar -> foo.bar */
  2077. if (ldap_dn2domain(port->hba->ldapbasedn, &domain))
  2078. {
  2079. ereport(LOG,
  2080. (errmsg("could not extract domain name from ldapbasedn")));
  2081. return STATUS_ERROR;
  2082. }
  2083. /* Look up a list of LDAP server hosts and port numbers */
  2084. if (ldap_domain2hostlist(domain, &hostlist))
  2085. {
  2086. ereport(LOG,
  2087. (errmsg("LDAP authentication could not find DNS SRV records for \"%s\"",
  2088. domain),
  2089. (errhint("Set an LDAP server name explicitly."))));
  2090. ldap_memfree(domain);
  2091. return STATUS_ERROR;
  2092. }
  2093. ldap_memfree(domain);
  2094. /* We have a space-separated list of host:port entries */
  2095. p = hostlist;
  2096. append_port = false;
  2097. }
  2098. else
  2099. {
  2100. /* We have a space-separated list of hosts from pg_hba.conf */
  2101. p = port->hba->ldapserver;
  2102. append_port = true;
  2103. }
  2104. /* Convert the list of host[:port] entries to full URIs */
  2105. do
  2106. {
  2107. size_t size;
  2108. /* Find the span of the next entry */
  2109. size = strcspn(p, " ");
  2110. /* Append a space separator if this isn't the first URI */
  2111. if (uris.len > 0)
  2112. appendStringInfoChar(&uris, ' ');
  2113. /* Append scheme://host:port */
  2114. appendStringInfoString(&uris, scheme);
  2115. appendStringInfoString(&uris, "://");
  2116. appendBinaryStringInfo(&uris, p, size);
  2117. if (append_port)
  2118. appendStringInfo(&uris, ":%d", port->hba->ldapport);
  2119. /* Step over this entry and any number of trailing spaces */
  2120. p += size;
  2121. while (*p == ' ')
  2122. ++p;
  2123. } while (*p);
  2124. /* Free memory from OpenLDAP if we looked up SRV records */
  2125. if (hostlist)
  2126. ldap_memfree(hostlist);
  2127. /* Finally, try to connect using the URI list */
  2128. r = ldap_initialize(ldap, uris.data);
  2129. pfree(uris.data);
  2130. if (r != LDAP_SUCCESS)
  2131. {
  2132. ereport(LOG,
  2133. (errmsg("could not initialize LDAP: %s",
  2134. ldap_err2string(r))));
  2135. return STATUS_ERROR;
  2136. }
  2137. }
  2138. #else
  2139. if (strcmp(scheme, "ldaps") == 0)
  2140. {
  2141. ereport(LOG,
  2142. (errmsg("ldaps not supported with this LDAP library")));
  2143. return STATUS_ERROR;
  2144. }
  2145. *ldap = ldap_init(port->hba->ldapserver, port->hba->ldapport);
  2146. if (!*ldap)
  2147. {
  2148. ereport(LOG,
  2149. (errmsg("could not initialize LDAP: %m")));
  2150. return STATUS_ERROR;
  2151. }
  2152. #endif
  2153. #endif
  2154. if ((r = ldap_set_option(*ldap, LDAP_OPT_PROTOCOL_VERSION, &ldapversion)) != LDAP_SUCCESS)
  2155. {
  2156. ereport(LOG,
  2157. (errmsg("could not set LDAP protocol version: %s",
  2158. ldap_err2string(r)),
  2159. errdetail_for_ldap(*ldap)));
  2160. ldap_unbind(*ldap);
  2161. return STATUS_ERROR;
  2162. }
  2163. if (port->hba->ldaptls)
  2164. {
  2165. #ifndef WIN32
  2166. if ((r = ldap_start_tls_s(*ldap, NULL, NULL)) != LDAP_SUCCESS)
  2167. #else
  2168. static __ldap_start_tls_sA _ldap_start_tls_sA = NULL;
  2169. if (_ldap_start_tls_sA == NULL)
  2170. {
  2171. /*
  2172. * Need to load this function dynamically because it may not exist
  2173. * on Windows, and causes a load error for the whole exe if
  2174. * referenced.
  2175. */
  2176. HANDLE ldaphandle;
  2177. ldaphandle = LoadLibrary("WLDAP32.DLL");
  2178. if (ldaphandle == NULL)
  2179. {
  2180. /*
  2181. * should never happen since we import other files from
  2182. * wldap32, but check anyway
  2183. */
  2184. ereport(LOG,
  2185. (errmsg("could not load library \"%s\": error code %lu",
  2186. "WLDAP32.DLL", GetLastError())));
  2187. ldap_unbind(*ldap);
  2188. return STATUS_ERROR;
  2189. }
  2190. _ldap_start_tls_sA = (__ldap_start_tls_sA) GetProcAddress(ldaphandle, "ldap_start_tls_sA");
  2191. if (_ldap_start_tls_sA == NULL)
  2192. {
  2193. ereport(LOG,
  2194. (errmsg("could not load function _ldap_start_tls_sA in wldap32.dll"),
  2195. errdetail("LDAP over SSL is not supported on this platform.")));
  2196. ldap_unbind(*ldap);
  2197. FreeLibrary(ldaphandle);
  2198. return STATUS_ERROR;
  2199. }
  2200. /*
  2201. * Leak LDAP handle on purpose, because we need the library to
  2202. * stay open. This is ok because it will only ever be leaked once
  2203. * per process and is automatically cleaned up on process exit.
  2204. */
  2205. }
  2206. if ((r = _ldap_start_tls_sA(*ldap, NULL, NULL, NULL, NULL)) != LDAP_SUCCESS)
  2207. #endif
  2208. {
  2209. ereport(LOG,
  2210. (errmsg("could not start LDAP TLS session: %s",
  2211. ldap_err2string(r)),
  2212. errdetail_for_ldap(*ldap)));
  2213. ldap_unbind(*ldap);
  2214. return STATUS_ERROR;
  2215. }
  2216. }
  2217. return STATUS_OK;
  2218. }
  2219. /* Placeholders recognized by FormatSearchFilter. For now just one. */
  2220. #define LPH_USERNAME "$username"
  2221. #define LPH_USERNAME_LEN (sizeof(LPH_USERNAME) - 1)
  2222. /* Not all LDAP implementations define this. */
  2223. #ifndef LDAP_NO_ATTRS
  2224. #define LDAP_NO_ATTRS "1.1"
  2225. #endif
  2226. /* Not all LDAP implementations define this. */
  2227. #ifndef LDAPS_PORT
  2228. #define LDAPS_PORT 636
  2229. #endif
  2230. /*
  2231. * Return a newly allocated C string copied from "pattern" with all
  2232. * occurrences of the placeholder "$username" replaced with "user_name".
  2233. */
  2234. static char *
  2235. FormatSearchFilter(const char *pattern, const char *user_name)
  2236. {
  2237. StringInfoData output;
  2238. initStringInfo(&output);
  2239. while (*pattern != '\0')
  2240. {
  2241. if (strncmp(pattern, LPH_USERNAME, LPH_USERNAME_LEN) == 0)
  2242. {
  2243. appendStringInfoString(&output, user_name);
  2244. pattern += LPH_USERNAME_LEN;
  2245. }
  2246. else
  2247. appendStringInfoChar(&output, *pattern++);
  2248. }
  2249. return output.data;
  2250. }
  2251. /*
  2252. * Perform LDAP authentication
  2253. */
  2254. static int
  2255. CheckLDAPAuth(Port *port)
  2256. {
  2257. char *passwd;
  2258. LDAP *ldap;
  2259. int r;
  2260. char *fulluser;
  2261. const char *server_name;
  2262. #ifdef HAVE_LDAP_INITIALIZE
  2263. /*
  2264. * For OpenLDAP, allow empty hostname if we have a basedn. We'll look for
  2265. * servers with DNS SRV records via OpenLDAP library facilities.
  2266. */
  2267. if ((!port->hba->ldapserver || port->hba->ldapserver[0] == '\0') &&
  2268. (!port->hba->ldapbasedn || port->hba->ldapbasedn[0] == '\0'))
  2269. {
  2270. ereport(LOG,
  2271. (errmsg("LDAP server not specified, and no ldapbasedn")));
  2272. return STATUS_ERROR;
  2273. }
  2274. #else
  2275. if (!port->hba->ldapserver || port->hba->ldapserver[0] == '\0')
  2276. {
  2277. ereport(LOG,
  2278. (errmsg("LDAP server not specified")));
  2279. return STATUS_ERROR;
  2280. }
  2281. #endif
  2282. /*
  2283. * If we're using SRV records, we don't have a server name so we'll just
  2284. * show an empty string in error messages.
  2285. */
  2286. server_name = port->hba->ldapserver ? port->hba->ldapserver : "";
  2287. if (port->hba->ldapport == 0)
  2288. {
  2289. if (port->hba->ldapscheme != NULL &&
  2290. strcmp(port->hba->ldapscheme, "ldaps") == 0)
  2291. port->hba->ldapport = LDAPS_PORT;
  2292. else
  2293. port->hba->ldapport = LDAP_PORT;
  2294. }
  2295. sendAuthRequest(port, AUTH_REQ_PASSWORD, NULL, 0);
  2296. passwd = recv_password_packet(port);
  2297. if (passwd == NULL)
  2298. return STATUS_EOF; /* client wouldn't send password */
  2299. if (InitializeLDAPConnection(port, &ldap) == STATUS_ERROR)
  2300. {
  2301. /* Error message already sent */
  2302. pfree(passwd);
  2303. return STATUS_ERROR;
  2304. }
  2305. if (port->hba->ldapbasedn)
  2306. {
  2307. /*
  2308. * First perform an LDAP search to find the DN for the user we are
  2309. * trying to log in as.
  2310. */
  2311. char *filter;
  2312. LDAPMessage *search_message;
  2313. LDAPMessage *entry;
  2314. char *attributes[] = {LDAP_NO_ATTRS, NULL};
  2315. char *dn;
  2316. char *c;
  2317. int count;
  2318. /*
  2319. * Disallow any characters that we would otherwise need to escape,
  2320. * since they aren't really reasonable in a username anyway. Allowing
  2321. * them would make it possible to inject any kind of custom filters in
  2322. * the LDAP filter.
  2323. */
  2324. for (c = port->user_name; *c; c++)
  2325. {
  2326. if (*c == '*' ||
  2327. *c == '(' ||
  2328. *c == ')' ||
  2329. *c == '\\' ||
  2330. *c == '/')
  2331. {
  2332. ereport(LOG,
  2333. (errmsg("invalid character in user name for LDAP authentication")));
  2334. ldap_unbind(ldap);
  2335. pfree(passwd);
  2336. return STATUS_ERROR;
  2337. }
  2338. }
  2339. /*
  2340. * Bind with a pre-defined username/password (if available) for
  2341. * searching. If none is specified, this turns into an anonymous bind.
  2342. */
  2343. r = ldap_simple_bind_s(ldap,
  2344. port->hba->ldapbinddn ? port->hba->ldapbinddn : "",
  2345. port->hba->ldapbindpasswd ? port->hba->ldapbindpasswd : "");
  2346. if (r != LDAP_SUCCESS)
  2347. {
  2348. ereport(LOG,
  2349. (errmsg("could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s",
  2350. port->hba->ldapbinddn ? port->hba->ldapbinddn : "",
  2351. server_name,
  2352. ldap_err2string(r)),
  2353. errdetail_for_ldap(ldap)));
  2354. ldap_unbind(ldap);
  2355. pfree(passwd);
  2356. return STATUS_ERROR;
  2357. }
  2358. /* Build a custom filter or a single attribute filter? */
  2359. if (port->hba->ldapsearchfilter)
  2360. filter = FormatSearchFilter(port->hba->ldapsearchfilter, port->user_name);
  2361. else if (port->hba->ldapsearchattribute)
  2362. filter = psprintf("(%s=%s)", port->hba->ldapsearchattribute, port->user_name);
  2363. else
  2364. filter = psprintf("(uid=%s)", port->user_name);
  2365. r = ldap_search_s(ldap,
  2366. port->hba->ldapbasedn,
  2367. port->hba->ldapscope,
  2368. filter,
  2369. attributes,
  2370. 0,
  2371. &search_message);
  2372. if (r != LDAP_SUCCESS)
  2373. {
  2374. ereport(LOG,
  2375. (errmsg("could not search LDAP for filter \"%s\" on server \"%s\": %s",
  2376. filter, server_name, ldap_err2string(r)),
  2377. errdetail_for_ldap(ldap)));
  2378. ldap_unbind(ldap);
  2379. pfree(passwd);
  2380. pfree(filter);
  2381. return STATUS_ERROR;
  2382. }
  2383. count = ldap_count_entries(ldap, search_message);
  2384. if (count != 1)
  2385. {
  2386. if (count == 0)
  2387. ereport(LOG,
  2388. (errmsg("LDAP user \"%s\" does not exist", port->user_name),
  2389. errdetail("LDAP search for filter \"%s\" on server \"%s\" returned no entries.",
  2390. filter, server_name)));
  2391. else
  2392. ereport(LOG,
  2393. (errmsg("LDAP user \"%s\" is not unique", port->user_name),
  2394. errdetail_plural("LDAP search for filter \"%s\" on server \"%s\" returned %d entry.",
  2395. "LDAP search for filter \"%s\" on server \"%s\" returned %d entries.",
  2396. count,
  2397. filter, server_name, count)));
  2398. ldap_unbind(ldap);
  2399. pfree(passwd);
  2400. pfree(filter);
  2401. ldap_msgfree(search_message);
  2402. return STATUS_ERROR;
  2403. }
  2404. entry = ldap_first_entry(ldap, search_message);
  2405. dn = ldap_get_dn(ldap, entry);
  2406. if (dn == NULL)
  2407. {
  2408. int error;
  2409. (void) ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &error);
  2410. ereport(LOG,
  2411. (errmsg("could not get dn for the first entry matching \"%s\" on server \"%s\": %s",
  2412. filter, server_name,
  2413. ldap_err2string(error)),
  2414. errdetail_for_ldap(ldap)));
  2415. ldap_unbind(ldap);
  2416. pfree(passwd);
  2417. pfree(filter);
  2418. ldap_msgfree(search_message);
  2419. return STATUS_ERROR;
  2420. }
  2421. fulluser = pstrdup(dn);
  2422. pfree(filter);
  2423. ldap_memfree(dn);
  2424. ldap_msgfree(search_message);
  2425. /* Unbind and disconnect from the LDAP server */
  2426. r = ldap_unbind_s(ldap);
  2427. if (r != LDAP_SUCCESS)
  2428. {
  2429. ereport(LOG,
  2430. (errmsg("could not unbind after searching for user \"%s\" on server \"%s\"",
  2431. fulluser, server_name)));
  2432. pfree(passwd);
  2433. pfree(fulluser);
  2434. return STATUS_ERROR;
  2435. }
  2436. /*
  2437. * Need to re-initialize the LDAP connection, so that we can bind to
  2438. * it with a different username.
  2439. */
  2440. if (InitializeLDAPConnection(port, &ldap) == STATUS_ERROR)
  2441. {
  2442. pfree(passwd);
  2443. pfree(fulluser);
  2444. /* Error message already sent */
  2445. return STATUS_ERROR;
  2446. }
  2447. }
  2448. else
  2449. fulluser = psprintf("%s%s%s",
  2450. port->hba->ldapprefix ? port->hba->ldapprefix : "",
  2451. port->user_name,
  2452. port->hba->ldapsuffix ? port->hba->ldapsuffix : "");
  2453. r = ldap_simple_bind_s(ldap, fulluser, passwd);
  2454. if (r != LDAP_SUCCESS)
  2455. {
  2456. ereport(LOG,
  2457. (errmsg("LDAP login failed for user \"%s\" on server \"%s\": %s",
  2458. fulluser, server_name, ldap_err2string(r)),
  2459. errdetail_for_ldap(ldap)));
  2460. ldap_unbind(ldap);
  2461. pfree(passwd);
  2462. pfree(fulluser);
  2463. return STATUS_ERROR;
  2464. }
  2465. ldap_unbind(ldap);
  2466. pfree(passwd);
  2467. pfree(fulluser);
  2468. return STATUS_OK;
  2469. }
  2470. /*
  2471. * Add a detail error message text to the current error if one can be
  2472. * constructed from the LDAP 'diagnostic message'.
  2473. */
  2474. static int
  2475. errdetail_for_ldap(LDAP *ldap)
  2476. {
  2477. char *message;
  2478. int rc;
  2479. rc = ldap_get_option(ldap, LDAP_OPT_DIAGNOSTIC_MESSAGE, &message);
  2480. if (rc == LDAP_SUCCESS && message != NULL)
  2481. {
  2482. errdetail("LDAP diagnostics: %s", message);
  2483. ldap_memfree(message);
  2484. }
  2485. return 0;
  2486. }
  2487. #endif /* USE_LDAP */
  2488. /*----------------------------------------------------------------
  2489. * SSL client certificate authentication
  2490. *----------------------------------------------------------------
  2491. */
  2492. #ifdef USE_SSL
  2493. static int
  2494. CheckCertAuth(Port *port)
  2495. {
  2496. int status_check_usermap = STATUS_ERROR;
  2497. Assert(port->ssl);
  2498. /* Make sure we have received a username in the certificate */
  2499. if (port->peer_cn == NULL ||
  2500. strlen(port->peer_cn) <= 0)
  2501. {
  2502. ereport(LOG,
  2503. (errmsg("certificate authentication failed for user \"%s\": client certificate contains no user name",
  2504. port->user_name)));
  2505. return STATUS_ERROR;
  2506. }
  2507. /* Just pass the certificate cn to the usermap check */
  2508. status_check_usermap = check_usermap(port->hba->usermap, port->user_name, port->peer_cn, false);
  2509. if (status_check_usermap != STATUS_OK)
  2510. {
  2511. /*
  2512. * If clientcert=verify-full was specified and the authentication
  2513. * method is other than uaCert, log the reason for rejecting the
  2514. * authentication.
  2515. */
  2516. if (port->hba->clientcert == clientCertFull && port->hba->auth_method != uaCert)
  2517. {
  2518. ereport(LOG,
  2519. (errmsg("certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch",
  2520. port->user_name)));
  2521. }
  2522. }
  2523. return status_check_usermap;
  2524. }
  2525. #endif
  2526. /*----------------------------------------------------------------
  2527. * RADIUS authentication
  2528. *----------------------------------------------------------------
  2529. */
  2530. /*
  2531. * RADIUS authentication is described in RFC2865 (and several others).
  2532. */
  2533. #define RADIUS_VECTOR_LENGTH 16
  2534. #define RADIUS_HEADER_LENGTH 20
  2535. #define RADIUS_MAX_PASSWORD_LENGTH 128
  2536. /* Maximum size of a RADIUS packet we will create or accept */
  2537. #define RADIUS_BUFFER_SIZE 1024
  2538. typedef struct
  2539. {
  2540. uint8 attribute;
  2541. uint8 length;
  2542. uint8 data[FLEXIBLE_ARRAY_MEMBER];
  2543. } radius_attribute;
  2544. typedef struct
  2545. {
  2546. uint8 code;
  2547. uint8 id;
  2548. uint16 length;
  2549. uint8 vector[RADIUS_VECTOR_LENGTH];
  2550. /* this is a bit longer than strictly necessary: */
  2551. char pad[RADIUS_BUFFER_SIZE - RADIUS_VECTOR_LENGTH];
  2552. } radius_packet;
  2553. /* RADIUS packet types */
  2554. #define RADIUS_ACCESS_REQUEST 1
  2555. #define RADIUS_ACCESS_ACCEPT 2
  2556. #define RADIUS_ACCESS_REJECT 3
  2557. /* RADIUS attributes */
  2558. #define RADIUS_USER_NAME 1
  2559. #define RADIUS_PASSWORD 2
  2560. #define RADIUS_SERVICE_TYPE 6
  2561. #define RADIUS_NAS_IDENTIFIER 32
  2562. /* RADIUS service types */
  2563. #define RADIUS_AUTHENTICATE_ONLY 8
  2564. /* Seconds to wait - XXX: should be in a config variable! */
  2565. #define RADIUS_TIMEOUT 3
  2566. static void
  2567. radius_add_attribute(radius_packet *packet, uint8 type, const unsigned char *data, int len)
  2568. {
  2569. radius_attribute *attr;
  2570. if (packet->length + len > RADIUS_BUFFER_SIZE)
  2571. {
  2572. /*
  2573. * With remotely realistic data, this can never happen. But catch it
  2574. * just to make sure we don't overrun a buffer. We'll just skip adding
  2575. * the broken attribute, which will in the end cause authentication to
  2576. * fail.
  2577. */
  2578. elog(WARNING,
  2579. "adding attribute code %d with length %d to radius packet would create oversize packet, ignoring",
  2580. type, len);
  2581. return;
  2582. }
  2583. attr = (radius_attribute *) ((unsigned char *) packet + packet->length);
  2584. attr->attribute = type;
  2585. attr->length = len + 2; /* total size includes type and length */
  2586. memcpy(attr->data, data, len);
  2587. packet->length += attr->length;
  2588. }
  2589. static int
  2590. CheckRADIUSAuth(Port *port)
  2591. {
  2592. char *passwd;
  2593. ListCell *server,
  2594. *secrets,
  2595. *radiusports,
  2596. *identifiers;
  2597. /* Make sure struct alignment is correct */
  2598. Assert(offsetof(radius_packet, vector) == 4);
  2599. /* Verify parameters */
  2600. if (list_length(port->hba->radiusservers) < 1)
  2601. {
  2602. ereport(LOG,
  2603. (errmsg("RADIUS server not specified")));
  2604. return STATUS_ERROR;
  2605. }
  2606. if (list_length(port->hba->radiussecrets) < 1)
  2607. {
  2608. ereport(LOG,
  2609. (errmsg("RADIUS secret not specified")));
  2610. return STATUS_ERROR;
  2611. }
  2612. /* Send regular password request to client, and get the response */
  2613. sendAuthRequest(port, AUTH_REQ_PASSWORD, NULL, 0);
  2614. passwd = recv_password_packet(port);
  2615. if (passwd == NULL)
  2616. return STATUS_EOF; /* client wouldn't send password */
  2617. if (strlen(passwd) > RADIUS_MAX_PASSWORD_LENGTH)
  2618. {
  2619. ereport(LOG,
  2620. (errmsg("RADIUS authentication does not support passwords longer than %d characters", RADIUS_MAX_PASSWORD_LENGTH)));
  2621. pfree(passwd);
  2622. return STATUS_ERROR;
  2623. }
  2624. /*
  2625. * Loop over and try each server in order.
  2626. */
  2627. secrets = list_head(port->hba->radiussecrets);
  2628. radiusports = list_head(port->hba->radiusports);
  2629. identifiers = list_head(port->hba->radiusidentifiers);
  2630. foreach(server, port->hba->radiusservers)
  2631. {
  2632. int ret = PerformRadiusTransaction(lfirst(server),
  2633. lfirst(secrets),
  2634. radiusports ? lfirst(radiusports) : NULL,
  2635. identifiers ? lfirst(identifiers) : NULL,
  2636. port->user_name,
  2637. passwd);
  2638. /*------
  2639. * STATUS_OK = Login OK
  2640. * STATUS_ERROR = Login not OK, but try next server
  2641. * STATUS_EOF = Login not OK, and don't try next server
  2642. *------
  2643. */
  2644. if (ret == STATUS_OK)
  2645. {
  2646. pfree(passwd);
  2647. return STATUS_OK;
  2648. }
  2649. else if (ret == STATUS_EOF)
  2650. {
  2651. pfree(passwd);
  2652. return STATUS_ERROR;
  2653. }
  2654. /*
  2655. * secret, port and identifiers either have length 0 (use default),
  2656. * length 1 (use the same everywhere) or the same length as servers.
  2657. * So if the length is >1, we advance one step. In other cases, we
  2658. * don't and will then reuse the correct value.
  2659. */
  2660. if (list_length(port->hba->radiussecrets) > 1)
  2661. secrets = lnext(port->hba->radiussecrets, secrets);
  2662. if (list_length(port->hba->radiusports) > 1)
  2663. radiusports = lnext(port->hba->radiusports, radiusports);
  2664. if (list_length(port->hba->radiusidentifiers) > 1)
  2665. identifiers = lnext(port->hba->radiusidentifiers, identifiers);
  2666. }
  2667. /* No servers left to try, so give up */
  2668. pfree(passwd);
  2669. return STATUS_ERROR;
  2670. }
  2671. static int
  2672. PerformRadiusTransaction(const char *server, const char *secret, const char *portstr, const char *identifier, const char *user_name, const char *passwd)
  2673. {
  2674. radius_packet radius_send_pack;
  2675. radius_packet radius_recv_pack;
  2676. radius_packet *packet = &radius_send_pack;
  2677. radius_packet *receivepacket = &radius_recv_pack;
  2678. char *radius_buffer = (char *) &radius_send_pack;
  2679. char *receive_buffer = (char *) &radius_recv_pack;
  2680. int32 service = pg_hton32(RADIUS_AUTHENTICATE_ONLY);
  2681. uint8 *cryptvector;
  2682. int encryptedpasswordlen;
  2683. uint8 encryptedpassword[RADIUS_MAX_PASSWORD_LENGTH];
  2684. uint8 *md5trailer;
  2685. int packetlength;
  2686. pgsocket sock;
  2687. #ifdef HAVE_IPV6
  2688. struct sockaddr_in6 localaddr;
  2689. struct sockaddr_in6 remoteaddr;
  2690. #else
  2691. struct sockaddr_in localaddr;
  2692. struct sockaddr_in remoteaddr;
  2693. #endif
  2694. struct addrinfo hint;
  2695. struct addrinfo *serveraddrs;
  2696. int port;
  2697. ACCEPT_TYPE_ARG3 addrsize;
  2698. fd_set fdset;
  2699. struct timeval endtime;
  2700. int i,
  2701. j,
  2702. r;
  2703. /* Assign default values */
  2704. if (portstr == NULL)
  2705. portstr = "1812";
  2706. if (identifier == NULL)
  2707. identifier = "postgresql";
  2708. MemSet(&hint, 0, sizeof(hint));
  2709. hint.ai_socktype = SOCK_DGRAM;
  2710. hint.ai_family = AF_UNSPEC;
  2711. port = atoi(portstr);
  2712. r = pg_getaddrinfo_all(server, portstr, &hint, &serveraddrs);
  2713. if (r || !serveraddrs)
  2714. {
  2715. ereport(LOG,
  2716. (errmsg("could not translate RADIUS server name \"%s\" to address: %s",
  2717. server, gai_strerror(r))));
  2718. if (serveraddrs)
  2719. pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
  2720. return STATUS_ERROR;
  2721. }
  2722. /* XXX: add support for multiple returned addresses? */
  2723. /* Construct RADIUS packet */
  2724. packet->code = RADIUS_ACCESS_REQUEST;
  2725. packet->length = RADIUS_HEADER_LENGTH;
  2726. if (!pg_strong_random(packet->vector, RADIUS_VECTOR_LENGTH))
  2727. {
  2728. ereport(LOG,
  2729. (errmsg("could not generate random encryption vector")));
  2730. pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
  2731. return STATUS_ERROR;
  2732. }
  2733. packet->id = packet->vector[0];
  2734. radius_add_attribute(packet, RADIUS_SERVICE_TYPE, (const unsigned char *) &service, sizeof(service));
  2735. radius_add_attribute(packet, RADIUS_USER_NAME, (const unsigned char *) user_name, strlen(user_name));
  2736. radius_add_attribute(packet, RADIUS_NAS_IDENTIFIER, (const unsigned char *) identifier, strlen(identifier));
  2737. /*
  2738. * RADIUS password attributes are calculated as: e[0] = p[0] XOR
  2739. * MD5(secret + Request Authenticator) for the first group of 16 octets,
  2740. * and then: e[i] = p[i] XOR MD5(secret + e[i-1]) for the following ones
  2741. * (if necessary)
  2742. */
  2743. encryptedpasswordlen = ((strlen(passwd) + RADIUS_VECTOR_LENGTH - 1) / RADIUS_VECTOR_LENGTH) * RADIUS_VECTOR_LENGTH;
  2744. cryptvector = palloc(strlen(secret) + RADIUS_VECTOR_LENGTH);
  2745. memcpy(cryptvector, secret, strlen(secret));
  2746. /* for the first iteration, we use the Request Authenticator vector */
  2747. md5trailer = packet->vector;
  2748. for (i = 0; i < encryptedpasswordlen; i += RADIUS_VECTOR_LENGTH)
  2749. {
  2750. memcpy(cryptvector + strlen(secret), md5trailer, RADIUS_VECTOR_LENGTH);
  2751. /*
  2752. * .. and for subsequent iterations the result of the previous XOR
  2753. * (calculated below)
  2754. */
  2755. md5trailer = encryptedpassword + i;
  2756. if (!pg_md5_binary(cryptvector, strlen(secret) + RADIUS_VECTOR_LENGTH, encryptedpassword + i))
  2757. {
  2758. ereport(LOG,
  2759. (errmsg("could not perform MD5 encryption of password")));
  2760. pfree(cryptvector);
  2761. pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
  2762. return STATUS_ERROR;
  2763. }
  2764. for (j = i; j < i + RADIUS_VECTOR_LENGTH; j++)
  2765. {
  2766. if (j < strlen(passwd))
  2767. encryptedpassword[j] = passwd[j] ^ encryptedpassword[j];
  2768. else
  2769. encryptedpassword[j] = '\0' ^ encryptedpassword[j];
  2770. }
  2771. }
  2772. pfree(cryptvector);
  2773. radius_add_attribute(packet, RADIUS_PASSWORD, encryptedpassword, encryptedpasswordlen);
  2774. /* Length needs to be in network order on the wire */
  2775. packetlength = packet->length;
  2776. packet->length = pg_hton16(packet->length);
  2777. sock = socket(serveraddrs[0].ai_family, SOCK_DGRAM, 0);
  2778. if (sock == PGINVALID_SOCKET)
  2779. {
  2780. ereport(LOG,
  2781. (errmsg("could not create RADIUS socket: %m")));
  2782. pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
  2783. return STATUS_ERROR;
  2784. }
  2785. memset(&localaddr, 0, sizeof(localaddr));
  2786. #ifdef HAVE_IPV6
  2787. localaddr.sin6_family = serveraddrs[0].ai_family;
  2788. localaddr.sin6_addr = in6addr_any;
  2789. if (localaddr.sin6_family == AF_INET6)
  2790. addrsize = sizeof(struct sockaddr_in6);
  2791. else
  2792. addrsize = sizeof(struct sockaddr_in);
  2793. #else
  2794. localaddr.sin_family = serveraddrs[0].ai_family;
  2795. localaddr.sin_addr.s_addr = INADDR_ANY;
  2796. addrsize = sizeof(struct sockaddr_in);
  2797. #endif
  2798. if (bind(sock, (struct sockaddr *) &localaddr, addrsize))
  2799. {
  2800. ereport(LOG,
  2801. (errmsg("could not bind local RADIUS socket: %m")));
  2802. closesocket(sock);
  2803. pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
  2804. return STATUS_ERROR;
  2805. }
  2806. if (sendto(sock, radius_buffer, packetlength, 0,
  2807. serveraddrs[0].ai_addr, serveraddrs[0].ai_addrlen) < 0)
  2808. {
  2809. ereport(LOG,
  2810. (errmsg("could not send RADIUS packet: %m")));
  2811. closesocket(sock);
  2812. pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
  2813. return STATUS_ERROR;
  2814. }
  2815. /* Don't need the server address anymore */
  2816. pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
  2817. /*
  2818. * Figure out at what time we should time out. We can't just use a single
  2819. * call to select() with a timeout, since somebody can be sending invalid
  2820. * packets to our port thus causing us to retry in a loop and never time
  2821. * out.
  2822. *
  2823. * XXX: Using WaitLatchOrSocket() and doing a CHECK_FOR_INTERRUPTS() if
  2824. * the latch was set would improve the responsiveness to
  2825. * timeouts/cancellations.
  2826. */
  2827. gettimeofday(&endtime, NULL);
  2828. endtime.tv_sec += RADIUS_TIMEOUT;
  2829. while (true)
  2830. {
  2831. struct timeval timeout;
  2832. struct timeval now;
  2833. int64 timeoutval;
  2834. gettimeofday(&now, NULL);
  2835. timeoutval = (endtime.tv_sec * 1000000 + endtime.tv_usec) - (now.tv_sec * 1000000 + now.tv_usec);
  2836. if (timeoutval <= 0)
  2837. {
  2838. ereport(LOG,
  2839. (errmsg("timeout waiting for RADIUS response from %s",
  2840. server)));
  2841. closesocket(sock);
  2842. return STATUS_ERROR;
  2843. }
  2844. timeout.tv_sec = timeoutval / 1000000;
  2845. timeout.tv_usec = timeoutval % 1000000;
  2846. FD_ZERO(&fdset);
  2847. FD_SET(sock, &fdset);
  2848. r = select(sock + 1, &fdset, NULL, NULL, &timeout);
  2849. if (r < 0)
  2850. {
  2851. if (errno == EINTR)
  2852. continue;
  2853. /* Anything else is an actual error */
  2854. ereport(LOG,
  2855. (errmsg("could not check status on RADIUS socket: %m")));
  2856. closesocket(sock);
  2857. return STATUS_ERROR;
  2858. }
  2859. if (r == 0)
  2860. {
  2861. ereport(LOG,
  2862. (errmsg("timeout waiting for RADIUS response from %s",
  2863. server)));
  2864. closesocket(sock);
  2865. return STATUS_ERROR;
  2866. }
  2867. /*
  2868. * Attempt to read the response packet, and verify the contents.
  2869. *
  2870. * Any packet that's not actually a RADIUS packet, or otherwise does
  2871. * not validate as an explicit reject, is just ignored and we retry
  2872. * for another packet (until we reach the timeout). This is to avoid
  2873. * the possibility to denial-of-service the login by flooding the
  2874. * server with invalid packets on the port that we're expecting the
  2875. * RADIUS response on.
  2876. */
  2877. addrsize = sizeof(remoteaddr);
  2878. packetlength = recvfrom(sock, receive_buffer, RADIUS_BUFFER_SIZE, 0,
  2879. (struct sockaddr *) &remoteaddr, &addrsize);
  2880. if (packetlength < 0)
  2881. {
  2882. ereport(LOG,
  2883. (errmsg("could not read RADIUS response: %m")));
  2884. closesocket(sock);
  2885. return STATUS_ERROR;
  2886. }
  2887. #ifdef HAVE_IPV6
  2888. if (remoteaddr.sin6_port != pg_hton16(port))
  2889. #else
  2890. if (remoteaddr.sin_port != pg_hton16(port))
  2891. #endif
  2892. {
  2893. #ifdef HAVE_IPV6
  2894. ereport(LOG,
  2895. (errmsg("RADIUS response from %s was sent from incorrect port: %d",
  2896. server, pg_ntoh16(remoteaddr.sin6_port))));
  2897. #else
  2898. ereport(LOG,
  2899. (errmsg("RADIUS response from %s was sent from incorrect port: %d",
  2900. server, pg_ntoh16(remoteaddr.sin_port))));
  2901. #endif
  2902. continue;
  2903. }
  2904. if (packetlength < RADIUS_HEADER_LENGTH)
  2905. {
  2906. ereport(LOG,
  2907. (errmsg("RADIUS response from %s too short: %d", server, packetlength)));
  2908. continue;
  2909. }
  2910. if (packetlength != pg_ntoh16(receivepacket->length))
  2911. {
  2912. ereport(LOG,
  2913. (errmsg("RADIUS response from %s has corrupt length: %d (actual length %d)",
  2914. server, pg_ntoh16(receivepacket->length), packetlength)));
  2915. continue;
  2916. }
  2917. if (packet->id != receivepacket->id)
  2918. {
  2919. ereport(LOG,
  2920. (errmsg("RADIUS response from %s is to a different request: %d (should be %d)",
  2921. server, receivepacket->id, packet->id)));
  2922. continue;
  2923. }
  2924. /*
  2925. * Verify the response authenticator, which is calculated as
  2926. * MD5(Code+ID+Length+RequestAuthenticator+Attributes+Secret)
  2927. */
  2928. cryptvector = palloc(packetlength + strlen(secret));
  2929. memcpy(cryptvector, receivepacket, 4); /* code+id+length */
  2930. memcpy(cryptvector + 4, packet->vector, RADIUS_VECTOR_LENGTH); /* request
  2931. * authenticator, from
  2932. * original packet */
  2933. if (packetlength > RADIUS_HEADER_LENGTH) /* there may be no
  2934. * attributes at all */
  2935. memcpy(cryptvector + RADIUS_HEADER_LENGTH, receive_buffer + RADIUS_HEADER_LENGTH, packetlength - RADIUS_HEADER_LENGTH);
  2936. memcpy(cryptvector + packetlength, secret, strlen(secret));
  2937. if (!pg_md5_binary(cryptvector,
  2938. packetlength + strlen(secret),
  2939. encryptedpassword))
  2940. {
  2941. ereport(LOG,
  2942. (errmsg("could not perform MD5 encryption of received packet")));
  2943. pfree(cryptvector);
  2944. continue;
  2945. }
  2946. pfree(cryptvector);
  2947. if (memcmp(receivepacket->vector, encryptedpassword, RADIUS_VECTOR_LENGTH) != 0)
  2948. {
  2949. ereport(LOG,
  2950. (errmsg("RADIUS response from %s has incorrect MD5 signature",
  2951. server)));
  2952. continue;
  2953. }
  2954. if (receivepacket->code == RADIUS_ACCESS_ACCEPT)
  2955. {
  2956. closesocket(sock);
  2957. return STATUS_OK;
  2958. }
  2959. else if (receivepacket->code == RADIUS_ACCESS_REJECT)
  2960. {
  2961. closesocket(sock);
  2962. return STATUS_EOF;
  2963. }
  2964. else
  2965. {
  2966. ereport(LOG,
  2967. (errmsg("RADIUS response from %s has invalid code (%d) for user \"%s\"",
  2968. server, receivepacket->code, user_name)));
  2969. continue;
  2970. }
  2971. } /* while (true) */
  2972. }