PageRenderTime 64ms CodeModel.GetById 23ms RepoModel.GetById 1ms 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

Large files files are truncated, but you can click here to view the full file

  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 p…

Large files files are truncated, but you can click here to view the full file