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