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