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