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