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