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