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