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