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