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