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