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