OSDN Git Service

Update copyright for 2009.
[pg-rex/syncrep.git] / src / backend / libpq / auth.c
1 /*-------------------------------------------------------------------------
2  *
3  * auth.c
4  *        Routines to handle network authentication
5  *
6  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.175 2009/01/01 17:23:42 momjian Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15
16 #include "postgres.h"
17
18 #include <sys/param.h>
19 #include <sys/socket.h>
20 #if defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || defined(HAVE_STRUCT_SOCKCRED)
21 #include <sys/uio.h>
22 #include <sys/ucred.h>
23 #endif
24 #ifdef HAVE_UCRED_H
25 # include <ucred.h>
26 #endif
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
29 #include <unistd.h>
30
31 #include "libpq/auth.h"
32 #include "libpq/crypt.h"
33 #include "libpq/ip.h"
34 #include "libpq/libpq.h"
35 #include "libpq/pqformat.h"
36 #include "storage/ipc.h"
37
38 /*----------------------------------------------------------------
39  * Global authentication functions 
40  *----------------------------------------------------------------
41  */
42 static void sendAuthRequest(Port *port, AuthRequest areq);
43 static void auth_failed(Port *port, int status);
44 static char *recv_password_packet(Port *port);
45 static int      recv_and_check_password_packet(Port *port);
46
47
48 /*----------------------------------------------------------------
49  * Ident authentication
50  *----------------------------------------------------------------
51  */
52 /* Max size of username ident server can return */
53 #define IDENT_USERNAME_MAX 512
54
55 /* Standard TCP port number for Ident service.  Assigned by IANA */
56 #define IDENT_PORT 113
57
58 static int  authident(hbaPort *port);
59
60
61 /*----------------------------------------------------------------
62  * PAM authentication
63  *----------------------------------------------------------------
64  */
65 #ifdef USE_PAM
66 #ifdef HAVE_PAM_PAM_APPL_H
67 #include <pam/pam_appl.h>
68 #endif
69 #ifdef HAVE_SECURITY_PAM_APPL_H
70 #include <security/pam_appl.h>
71 #endif
72
73 #define PGSQL_PAM_SERVICE "postgresql"  /* Service name passed to PAM */
74
75 static int      CheckPAMAuth(Port *port, char *user, char *password);
76 static int pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg,
77                                          struct pam_response ** resp, void *appdata_ptr);
78
79 static struct pam_conv pam_passw_conv = {
80         &pam_passwd_conv_proc,
81         NULL
82 };
83
84 static char *pam_passwd = NULL; /* Workaround for Solaris 2.6 brokenness */
85 static Port *pam_port_cludge;   /* Workaround for passing "Port *port" into
86                                                                  * pam_passwd_conv_proc */
87 #endif   /* USE_PAM */
88
89
90 /*----------------------------------------------------------------
91  * LDAP authentication
92  *----------------------------------------------------------------
93  */
94 #ifdef USE_LDAP
95 #ifndef WIN32
96 /* We use a deprecated function to keep the codepath the same as win32. */
97 #define LDAP_DEPRECATED 1
98 #include <ldap.h>
99 #else
100 #include <winldap.h>
101
102 /* Correct header from the Platform SDK */
103 typedef
104 ULONG(*__ldap_start_tls_sA) (
105                                                          IN PLDAP ExternalHandle,
106                                                          OUT PULONG ServerReturnValue,
107                                                          OUT LDAPMessage ** result,
108                                                          IN PLDAPControlA * ServerControls,
109                                                          IN PLDAPControlA * ClientControls
110 );
111 #endif
112
113 static int      CheckLDAPAuth(Port *port);
114 #endif /* USE_LDAP */
115
116 /*----------------------------------------------------------------
117  * Cert authentication
118  *----------------------------------------------------------------
119  */
120 #ifdef USE_SSL
121 static int      CheckCertAuth(Port *port);
122 #endif
123
124
125 /*----------------------------------------------------------------
126  * Kerberos and GSSAPI GUCs
127  *----------------------------------------------------------------
128  */
129 char       *pg_krb_server_keyfile;
130 char       *pg_krb_srvnam;
131 bool            pg_krb_caseins_users;
132 char       *pg_krb_server_hostname = NULL;
133 char       *pg_krb_realm = NULL;
134
135
136 /*----------------------------------------------------------------
137  * MIT Kerberos authentication system - protocol version 5
138  *----------------------------------------------------------------
139  */
140 #ifdef KRB5
141 static int pg_krb5_recvauth(Port *port);
142
143 #include <krb5.h>
144 /* Some old versions of Kerberos do not include <com_err.h> in <krb5.h> */
145 #if !defined(__COM_ERR_H) && !defined(__COM_ERR_H__)
146 #include <com_err.h>
147 #endif
148 /*
149  * Various krb5 state which is not connection specfic, and a flag to
150  * indicate whether we have initialised it yet.
151  */
152 static int      pg_krb5_initialised;
153 static krb5_context pg_krb5_context;
154 static krb5_keytab pg_krb5_keytab;
155 static krb5_principal pg_krb5_server;
156 #endif /* KRB5 */
157
158
159 /*----------------------------------------------------------------
160  * GSSAPI Authentication
161  *----------------------------------------------------------------
162  */
163 #ifdef ENABLE_GSS
164 #if defined(HAVE_GSSAPI_H)
165 #include <gssapi.h>
166 #else
167 #include <gssapi/gssapi.h>
168 #endif
169
170 static int pg_GSS_recvauth(Port *port);
171 #endif /* ENABLE_GSS */
172
173
174 /*----------------------------------------------------------------
175  * SSPI Authentication
176  *----------------------------------------------------------------
177  */
178 #ifdef ENABLE_SSPI
179 typedef         SECURITY_STATUS
180                         (WINAPI * QUERY_SECURITY_CONTEXT_TOKEN_FN) (
181                                                                                                            PCtxtHandle, void **);
182 static int pg_SSPI_recvauth(Port *port);
183 #endif
184
185
186
187 /*----------------------------------------------------------------
188  * Global authentication functions
189  *----------------------------------------------------------------
190  */
191
192
193 /*
194  * Tell the user the authentication failed, but not (much about) why.
195  *
196  * There is a tradeoff here between security concerns and making life
197  * unnecessarily difficult for legitimate users.  We would not, for example,
198  * want to report the password we were expecting to receive...
199  * But it seems useful to report the username and authorization method
200  * in use, and these are items that must be presumed known to an attacker
201  * anyway.
202  * Note that many sorts of failure report additional information in the
203  * postmaster log, which we hope is only readable by good guys.
204  */
205 static void
206 auth_failed(Port *port, int status)
207 {
208         const char *errstr;
209
210         /*
211          * If we failed due to EOF from client, just quit; there's no point in
212          * trying to send a message to the client, and not much point in logging
213          * the failure in the postmaster log.  (Logging the failure might be
214          * desirable, were it not for the fact that libpq closes the connection
215          * unceremoniously if challenged for a password when it hasn't got one to
216          * send.  We'll get a useless log entry for every psql connection under
217          * password auth, even if it's perfectly successful, if we log STATUS_EOF
218          * events.)
219          */
220         if (status == STATUS_EOF)
221                 proc_exit(0);
222
223         switch (port->hba->auth_method)
224         {
225                 case uaReject:
226                         errstr = gettext_noop("authentication failed for user \"%s\": host rejected");
227                         break;
228                 case uaKrb5:
229                         errstr = gettext_noop("Kerberos 5 authentication failed for user \"%s\"");
230                         break;
231                 case uaGSS:
232                         errstr = gettext_noop("GSSAPI authentication failed for user \"%s\"");
233                         break;
234                 case uaSSPI:
235                         errstr = gettext_noop("SSPI authentication failed for user \"%s\"");
236                         break;
237                 case uaTrust:
238                         errstr = gettext_noop("\"trust\" authentication failed for user \"%s\"");
239                         break;
240                 case uaIdent:
241                         errstr = gettext_noop("Ident authentication failed for user \"%s\"");
242                         break;
243                 case uaMD5:
244                 case uaPassword:
245                         errstr = gettext_noop("password authentication failed for user \"%s\"");
246                         break;
247                 case uaPAM:
248                         errstr = gettext_noop("PAM authentication failed for user \"%s\"");
249                         break;
250                 case uaLDAP:
251                         errstr = gettext_noop("LDAP authentication failed for user \"%s\"");
252                         break;
253                 default:
254                         errstr = gettext_noop("authentication failed for user \"%s\": invalid authentication method");
255                         break;
256         }
257
258         ereport(FATAL,
259                         (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
260                          errmsg(errstr, port->user_name)));
261         /* doesn't return */
262 }
263
264
265 /*
266  * Client authentication starts here.  If there is an error, this
267  * function does not return and the backend process is terminated.
268  */
269 void
270 ClientAuthentication(Port *port)
271 {
272         int                     status = STATUS_ERROR;
273
274         /*
275          * Get the authentication method to use for this frontend/database
276          * combination.  Note: a failure return indicates a problem with the hba
277          * config file, not with the request.  hba.c should have dropped an error
278          * message into the postmaster logfile if it failed.
279          */
280         if (hba_getauthmethod(port) != STATUS_OK)
281                 ereport(FATAL,
282                                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
283                                  errmsg("missing or erroneous pg_hba.conf file"),
284                                  errhint("See server log for details.")));
285
286         /*
287          * This is the first point where we have access to the hba record for
288          * the current connection, so perform any verifications based on the
289          * hba options field that should be done *before* the authentication
290          * here.
291          */
292         if (port->hba->clientcert)
293         {
294                 /*
295                  * When we parse pg_hba.conf, we have already made sure that we have
296                  * been able to load a certificate store. Thus, if a certificate is
297                  * present on the client, it has been verified against our root
298                  * certificate store, and the connection would have been aborted
299                  * already if it didn't verify ok.
300                  */
301 #ifdef USE_SSL
302                 if (!port->peer)
303                 {
304                         ereport(FATAL,
305                                         (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
306                                          errmsg("connection requires a valid client certificate")));
307                 }
308 #else
309                 /*
310                  * hba.c makes sure hba->clientcert can't be set unless OpenSSL
311                  * is present.
312                  */
313                 Assert(false);
314 #endif
315         }
316
317         /*
318          * Now proceed to do the actual authentication check
319          */
320         switch (port->hba->auth_method)
321         {
322                 case uaReject:
323
324                         /*
325                          * This could have come from an explicit "reject" entry in
326                          * pg_hba.conf, but more likely it means there was no matching
327                          * entry.  Take pity on the poor user and issue a helpful error
328                          * message.  NOTE: this is not a security breach, because all the
329                          * info reported here is known at the frontend and must be assumed
330                          * known to bad guys. We're merely helping out the less clueful
331                          * good guys.
332                          */
333                         {
334                                 char            hostinfo[NI_MAXHOST];
335
336                                 pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
337                                                                    hostinfo, sizeof(hostinfo),
338                                                                    NULL, 0,
339                                                                    NI_NUMERICHOST);
340
341 #ifdef USE_SSL
342                                 ereport(FATAL,
343                                                 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
344                                                  errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
345                                                           hostinfo, port->user_name, port->database_name,
346                                                                 port->ssl ? _("SSL on") : _("SSL off"))));
347 #else
348                                 ereport(FATAL,
349                                                 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
350                                                  errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"",
351                                                    hostinfo, port->user_name, port->database_name)));
352 #endif
353                                 break;
354                         }
355
356                 case uaKrb5:
357 #ifdef KRB5
358                         sendAuthRequest(port, AUTH_REQ_KRB5);
359                         status = pg_krb5_recvauth(port);
360 #else
361                         Assert(false);
362 #endif
363                         break;
364
365                 case uaGSS:
366 #ifdef ENABLE_GSS
367                         sendAuthRequest(port, AUTH_REQ_GSS);
368                         status = pg_GSS_recvauth(port);
369 #else
370                         Assert(false);
371 #endif
372                         break;
373
374                 case uaSSPI:
375 #ifdef ENABLE_SSPI
376                         sendAuthRequest(port, AUTH_REQ_SSPI);
377                         status = pg_SSPI_recvauth(port);
378 #else
379                         Assert(false);
380 #endif
381                         break;
382
383                 case uaIdent:
384
385                         /*
386                          * If we are doing ident on unix-domain sockets, use SCM_CREDS
387                          * only if it is defined and SO_PEERCRED isn't.
388                          */
389 #if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && \
390         (defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || \
391          (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS)))
392                         if (port->raddr.addr.ss_family == AF_UNIX)
393                         {
394 #if defined(HAVE_STRUCT_FCRED) || defined(HAVE_STRUCT_SOCKCRED)
395
396                                 /*
397                                  * Receive credentials on next message receipt, BSD/OS,
398                                  * NetBSD. We need to set this before the client sends the
399                                  * next packet.
400                                  */
401                                 int                     on = 1;
402
403                                 if (setsockopt(port->sock, 0, LOCAL_CREDS, &on, sizeof(on)) < 0)
404                                         ereport(FATAL,
405                                                         (errcode_for_socket_access(),
406                                            errmsg("could not enable credential reception: %m")));
407 #endif
408
409                                 sendAuthRequest(port, AUTH_REQ_SCM_CREDS);
410                         }
411 #endif
412                         status = authident(port);
413                         break;
414
415                 case uaMD5:
416                         if (Db_user_namespace)
417                                 ereport(FATAL,
418                                                 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
419                                                  errmsg("MD5 authentication is not supported when \"db_user_namespace\" is enabled")));
420                         sendAuthRequest(port, AUTH_REQ_MD5);
421                         status = recv_and_check_password_packet(port);
422                         break;
423
424                 case uaPassword:
425                         sendAuthRequest(port, AUTH_REQ_PASSWORD);
426                         status = recv_and_check_password_packet(port);
427                         break;
428
429                 case uaPAM:
430 #ifdef USE_PAM
431                         pam_port_cludge = port;
432                         status = CheckPAMAuth(port, port->user_name, "");
433 #else
434                         Assert(false);
435 #endif   /* USE_PAM */
436                         break;
437
438                 case uaLDAP:
439 #ifdef USE_LDAP
440                         status = CheckLDAPAuth(port);
441 #else
442                         Assert(false);
443 #endif
444                         break;
445
446                 case uaCert:
447 #ifdef USE_SSL
448                         status = CheckCertAuth(port);
449 #else
450                         Assert(false);
451 #endif
452                         break;
453
454                 case uaTrust:
455                         status = STATUS_OK;
456                         break;
457         }
458
459         if (status == STATUS_OK)
460                 sendAuthRequest(port, AUTH_REQ_OK);
461         else
462                 auth_failed(port, status);
463 }
464
465
466 /*
467  * Send an authentication request packet to the frontend.
468  */
469 static void
470 sendAuthRequest(Port *port, AuthRequest areq)
471 {
472         StringInfoData buf;
473
474         pq_beginmessage(&buf, 'R');
475         pq_sendint(&buf, (int32) areq, sizeof(int32));
476
477         /* Add the salt for encrypted passwords. */
478         if (areq == AUTH_REQ_MD5)
479                 pq_sendbytes(&buf, port->md5Salt, 4);
480
481 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
482
483         /*
484          * Add the authentication data for the next step of the GSSAPI or SSPI
485          * negotiation.
486          */
487         else if (areq == AUTH_REQ_GSS_CONT)
488         {
489                 if (port->gss->outbuf.length > 0)
490                 {
491                         elog(DEBUG4, "sending GSS token of length %u",
492                                  (unsigned int) port->gss->outbuf.length);
493
494                         pq_sendbytes(&buf, port->gss->outbuf.value, port->gss->outbuf.length);
495                 }
496         }
497 #endif
498
499         pq_endmessage(&buf);
500
501         /*
502          * Flush message so client will see it, except for AUTH_REQ_OK, which need
503          * not be sent until we are ready for queries.
504          */
505         if (areq != AUTH_REQ_OK)
506                 pq_flush();
507 }
508
509 /*
510  * Collect password response packet from frontend.
511  *
512  * Returns NULL if couldn't get password, else palloc'd string.
513  */
514 static char *
515 recv_password_packet(Port *port)
516 {
517         StringInfoData buf;
518
519         if (PG_PROTOCOL_MAJOR(port->proto) >= 3)
520         {
521                 /* Expect 'p' message type */
522                 int                     mtype;
523
524                 mtype = pq_getbyte();
525                 if (mtype != 'p')
526                 {
527                         /*
528                          * If the client just disconnects without offering a password,
529                          * don't make a log entry.  This is legal per protocol spec and in
530                          * fact commonly done by psql, so complaining just clutters the
531                          * log.
532                          */
533                         if (mtype != EOF)
534                                 ereport(COMMERROR,
535                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
536                                         errmsg("expected password response, got message type %d",
537                                                    mtype)));
538                         return NULL;            /* EOF or bad message type */
539                 }
540         }
541         else
542         {
543                 /* For pre-3.0 clients, avoid log entry if they just disconnect */
544                 if (pq_peekbyte() == EOF)
545                         return NULL;            /* EOF */
546         }
547
548         initStringInfo(&buf);
549         if (pq_getmessage(&buf, 1000))          /* receive password */
550         {
551                 /* EOF - pq_getmessage already logged a suitable message */
552                 pfree(buf.data);
553                 return NULL;
554         }
555
556         /*
557          * Apply sanity check: password packet length should agree with length of
558          * contained string.  Note it is safe to use strlen here because
559          * StringInfo is guaranteed to have an appended '\0'.
560          */
561         if (strlen(buf.data) + 1 != buf.len)
562                 ereport(COMMERROR,
563                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
564                                  errmsg("invalid password packet size")));
565
566         /* Do not echo password to logs, for security. */
567         ereport(DEBUG5,
568                         (errmsg("received password packet")));
569
570         /*
571          * Return the received string.  Note we do not attempt to do any
572          * character-set conversion on it; since we don't yet know the client's
573          * encoding, there wouldn't be much point.
574          */
575         return buf.data;
576 }
577
578
579 /*----------------------------------------------------------------
580  * MD5 and crypt authentication
581  *----------------------------------------------------------------
582  */
583
584 /*
585  * Called when we have sent an authorization request for a password.
586  * Get the response and check it.
587  */
588 static int
589 recv_and_check_password_packet(Port *port)
590 {
591         char       *passwd;
592         int                     result;
593
594         passwd = recv_password_packet(port);
595
596         if (passwd == NULL)
597                 return STATUS_EOF;              /* client wouldn't send password */
598
599         result = md5_crypt_verify(port, port->user_name, passwd);
600
601         pfree(passwd);
602
603         return result;
604 }
605
606
607 /*----------------------------------------------------------------
608  * MIT Kerberos authentication system - protocol version 5
609  *----------------------------------------------------------------
610  */
611 #ifdef KRB5
612
613 static int
614 pg_krb5_init(void)
615 {
616         krb5_error_code retval;
617         char       *khostname;
618
619         if (pg_krb5_initialised)
620                 return STATUS_OK;
621
622         retval = krb5_init_context(&pg_krb5_context);
623         if (retval)
624         {
625                 ereport(LOG,
626                                 (errmsg("Kerberos initialization returned error %d",
627                                                 retval)));
628                 com_err("postgres", retval, "while initializing krb5");
629                 return STATUS_ERROR;
630         }
631
632         retval = krb5_kt_resolve(pg_krb5_context, pg_krb_server_keyfile, &pg_krb5_keytab);
633         if (retval)
634         {
635                 ereport(LOG,
636                                 (errmsg("Kerberos keytab resolving returned error %d",
637                                                 retval)));
638                 com_err("postgres", retval, "while resolving keytab file \"%s\"",
639                                 pg_krb_server_keyfile);
640                 krb5_free_context(pg_krb5_context);
641                 return STATUS_ERROR;
642         }
643
644         /*
645          * If no hostname was specified, pg_krb_server_hostname is already NULL.
646          * If it's set to blank, force it to NULL.
647          */
648         khostname = pg_krb_server_hostname;
649         if (khostname && khostname[0] == '\0')
650                 khostname = NULL;
651
652         retval = krb5_sname_to_principal(pg_krb5_context,
653                                                                          khostname,
654                                                                          pg_krb_srvnam,
655                                                                          KRB5_NT_SRV_HST,
656                                                                          &pg_krb5_server);
657         if (retval)
658         {
659                 ereport(LOG,
660                                 (errmsg("Kerberos sname_to_principal(\"%s\", \"%s\") returned error %d",
661                  khostname ? khostname : "server hostname", pg_krb_srvnam, retval)));
662                 com_err("postgres", retval,
663                 "while getting server principal for server \"%s\" for service \"%s\"",
664                                 khostname ? khostname : "server hostname", pg_krb_srvnam);
665                 krb5_kt_close(pg_krb5_context, pg_krb5_keytab);
666                 krb5_free_context(pg_krb5_context);
667                 return STATUS_ERROR;
668         }
669
670         pg_krb5_initialised = 1;
671         return STATUS_OK;
672 }
673
674
675 /*
676  * pg_krb5_recvauth -- server routine to receive authentication information
677  *                                         from the client
678  *
679  * We still need to compare the username obtained from the client's setup
680  * packet to the authenticated name.
681  *
682  * We have our own keytab file because postgres is unlikely to run as root,
683  * and so cannot read the default keytab.
684  */
685 static int
686 pg_krb5_recvauth(Port *port)
687 {
688         krb5_error_code retval;
689         int                     ret;
690         krb5_auth_context auth_context = NULL;
691         krb5_ticket *ticket;
692         char       *kusername;
693         char       *cp;
694
695         if (get_role_line(port->user_name) == NULL)
696                 return STATUS_ERROR;
697
698         ret = pg_krb5_init();
699         if (ret != STATUS_OK)
700                 return ret;
701
702         retval = krb5_recvauth(pg_krb5_context, &auth_context,
703                                                    (krb5_pointer) & port->sock, pg_krb_srvnam,
704                                                    pg_krb5_server, 0, pg_krb5_keytab, &ticket);
705         if (retval)
706         {
707                 ereport(LOG,
708                                 (errmsg("Kerberos recvauth returned error %d",
709                                                 retval)));
710                 com_err("postgres", retval, "from krb5_recvauth");
711                 return STATUS_ERROR;
712         }
713
714         /*
715          * The "client" structure comes out of the ticket and is therefore
716          * authenticated.  Use it to check the username obtained from the
717          * postmaster startup packet.
718          */
719 #if defined(HAVE_KRB5_TICKET_ENC_PART2)
720         retval = krb5_unparse_name(pg_krb5_context,
721                                                            ticket->enc_part2->client, &kusername);
722 #elif defined(HAVE_KRB5_TICKET_CLIENT)
723         retval = krb5_unparse_name(pg_krb5_context,
724                                                            ticket->client, &kusername);
725 #else
726 #error "bogus configuration"
727 #endif
728         if (retval)
729         {
730                 ereport(LOG,
731                                 (errmsg("Kerberos unparse_name returned error %d",
732                                                 retval)));
733                 com_err("postgres", retval, "while unparsing client name");
734                 krb5_free_ticket(pg_krb5_context, ticket);
735                 krb5_auth_con_free(pg_krb5_context, auth_context);
736                 return STATUS_ERROR;
737         }
738
739         cp = strchr(kusername, '@');
740         if (cp)
741         {
742                 *cp = '\0';
743                 cp++;
744
745                 if (pg_krb_realm != NULL && strlen(pg_krb_realm))
746                 {
747                         /* Match realm against configured */
748                         if (pg_krb_caseins_users)
749                                 ret = pg_strcasecmp(pg_krb_realm, cp);
750                         else
751                                 ret = strcmp(pg_krb_realm, cp);
752
753                         if (ret)
754                         {
755                                 elog(DEBUG2,
756                                          "krb5 realm (%s) and configured realm (%s) don't match",
757                                          cp, pg_krb_realm);
758
759                                 krb5_free_ticket(pg_krb5_context, ticket);
760                                 krb5_auth_con_free(pg_krb5_context, auth_context);
761                                 return STATUS_ERROR;
762                         }
763                 }
764         }
765         else if (pg_krb_realm && strlen(pg_krb_realm))
766         {
767                 elog(DEBUG2,
768                          "krb5 did not return realm but realm matching was requested");
769
770                 krb5_free_ticket(pg_krb5_context, ticket);
771                 krb5_auth_con_free(pg_krb5_context, auth_context);
772                 return STATUS_ERROR;
773         }
774
775         ret = check_usermap(port->hba->usermap, port->user_name, kusername,
776                                                 pg_krb_caseins_users);
777
778         krb5_free_ticket(pg_krb5_context, ticket);
779         krb5_auth_con_free(pg_krb5_context, auth_context);
780         free(kusername);
781
782         return ret;
783 }
784 #endif   /* KRB5 */
785
786
787 /*----------------------------------------------------------------
788  * GSSAPI authentication system
789  *----------------------------------------------------------------
790  */
791 #ifdef ENABLE_GSS
792
793 #if defined(WIN32) && !defined(WIN32_ONLY_COMPILER)
794 /*
795  * MIT Kerberos GSSAPI DLL doesn't properly export the symbols for MingW
796  * that contain the OIDs required. Redefine here, values copied
797  * from src/athena/auth/krb5/src/lib/gssapi/generic/gssapi_generic.c
798  */
799 static const gss_OID_desc GSS_C_NT_USER_NAME_desc =
800 {10, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"};
801 static GSS_DLLIMP gss_OID GSS_C_NT_USER_NAME = &GSS_C_NT_USER_NAME_desc;
802 #endif
803
804
805 static void
806 pg_GSS_error(int severity, char *errmsg, OM_uint32 maj_stat, OM_uint32 min_stat)
807 {
808         gss_buffer_desc gmsg;
809         OM_uint32       lmaj_s,
810                                 lmin_s,
811                                 msg_ctx;
812         char            msg_major[128],
813                                 msg_minor[128];
814
815         /* Fetch major status message */
816         msg_ctx = 0;
817         lmaj_s = gss_display_status(&lmin_s, maj_stat, GSS_C_GSS_CODE,
818                                                                 GSS_C_NO_OID, &msg_ctx, &gmsg);
819         strlcpy(msg_major, gmsg.value, sizeof(msg_major));
820         gss_release_buffer(&lmin_s, &gmsg);
821
822         if (msg_ctx)
823
824                 /*
825                  * More than one message available. XXX: Should we loop and read all
826                  * messages? (same below)
827                  */
828                 ereport(WARNING,
829                                 (errmsg_internal("incomplete GSS error report")));
830
831         /* Fetch mechanism minor status message */
832         msg_ctx = 0;
833         lmaj_s = gss_display_status(&lmin_s, min_stat, GSS_C_MECH_CODE,
834                                                                 GSS_C_NO_OID, &msg_ctx, &gmsg);
835         strlcpy(msg_minor, gmsg.value, sizeof(msg_minor));
836         gss_release_buffer(&lmin_s, &gmsg);
837
838         if (msg_ctx)
839                 ereport(WARNING,
840                                 (errmsg_internal("incomplete GSS minor error report")));
841
842         /*
843          * errmsg_internal, since translation of the first part must be done
844          * before calling this function anyway.
845          */
846         ereport(severity,
847                         (errmsg_internal("%s", errmsg),
848                          errdetail("%s: %s", msg_major, msg_minor)));
849 }
850
851 static int
852 pg_GSS_recvauth(Port *port)
853 {
854         OM_uint32       maj_stat,
855                                 min_stat,
856                                 lmin_s,
857                                 gflags;
858         int                     mtype;
859         int                     ret;
860         StringInfoData buf;
861         gss_buffer_desc gbuf;
862
863         /*
864          * GSS auth is not supported for protocol versions before 3, because it
865          * relies on the overall message length word to determine the GSS payload
866          * size in AuthenticationGSSContinue and PasswordMessage messages.
867          * (This is, in fact, a design error in our GSS support, because protocol
868          * messages are supposed to be parsable without relying on the length
869          * word; but it's not worth changing it now.)
870          */
871         if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
872                 ereport(FATAL,
873                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
874                                  errmsg("GSSAPI is not supported in protocol version 2")));
875
876         if (pg_krb_server_keyfile && strlen(pg_krb_server_keyfile) > 0)
877         {
878                 /*
879                  * Set default Kerberos keytab file for the Krb5 mechanism.
880                  *
881                  * setenv("KRB5_KTNAME", pg_krb_server_keyfile, 0); except setenv()
882                  * not always available.
883                  */
884                 if (getenv("KRB5_KTNAME") == NULL)
885                 {
886                         size_t  kt_len = strlen(pg_krb_server_keyfile) + 14;
887                         char   *kt_path = malloc(kt_len);
888
889                         if (!kt_path)
890                         {
891                                 ereport(LOG,
892                                                 (errcode(ERRCODE_OUT_OF_MEMORY),
893                                                  errmsg("out of memory")));
894                                 return STATUS_ERROR;
895                         }
896                         snprintf(kt_path, kt_len, "KRB5_KTNAME=%s", pg_krb_server_keyfile);
897                         putenv(kt_path);
898                 }
899         }
900
901         /*
902          * We accept any service principal that's present in our keytab. This
903          * increases interoperability between kerberos implementations that see
904          * for example case sensitivity differently, while not really opening up
905          * any vector of attack.
906          */
907         port->gss->cred = GSS_C_NO_CREDENTIAL;
908
909         /*
910          * Initialize sequence with an empty context
911          */
912         port->gss->ctx = GSS_C_NO_CONTEXT;
913
914         /*
915          * Loop through GSSAPI message exchange. This exchange can consist of
916          * multiple messags sent in both directions. First message is always from
917          * the client. All messages from client to server are password packets
918          * (type 'p').
919          */
920         do
921         {
922                 mtype = pq_getbyte();
923                 if (mtype != 'p')
924                 {
925                         /* Only log error if client didn't disconnect. */
926                         if (mtype != EOF)
927                                 ereport(COMMERROR,
928                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
929                                                  errmsg("expected GSS response, got message type %d",
930                                                                 mtype)));
931                         return STATUS_ERROR;
932                 }
933
934                 /* Get the actual GSS token */
935                 initStringInfo(&buf);
936                 if (pq_getmessage(&buf, 2000))
937                 {
938                         /* EOF - pq_getmessage already logged error */
939                         pfree(buf.data);
940                         return STATUS_ERROR;
941                 }
942
943                 /* Map to GSSAPI style buffer */
944                 gbuf.length = buf.len;
945                 gbuf.value = buf.data;
946
947                 elog(DEBUG4, "Processing received GSS token of length %u",
948                          (unsigned int) gbuf.length);
949
950                 maj_stat = gss_accept_sec_context(
951                                                                                   &min_stat,
952                                                                                   &port->gss->ctx,
953                                                                                   port->gss->cred,
954                                                                                   &gbuf,
955                                                                                   GSS_C_NO_CHANNEL_BINDINGS,
956                                                                                   &port->gss->name,
957                                                                                   NULL,
958                                                                                   &port->gss->outbuf,
959                                                                                   &gflags,
960                                                                                   NULL,
961                                                                                   NULL);
962
963                 /* gbuf no longer used */
964                 pfree(buf.data);
965
966                 elog(DEBUG5, "gss_accept_sec_context major: %d, "
967                          "minor: %d, outlen: %u, outflags: %x",
968                          maj_stat, min_stat,
969                          (unsigned int) port->gss->outbuf.length, gflags);
970
971                 if (port->gss->outbuf.length != 0)
972                 {
973                         /*
974                          * Negotiation generated data to be sent to the client.
975                          */
976                         OM_uint32       lmin_s;
977
978                         elog(DEBUG4, "sending GSS response token of length %u",
979                                  (unsigned int) port->gss->outbuf.length);
980
981                         sendAuthRequest(port, AUTH_REQ_GSS_CONT);
982
983                         gss_release_buffer(&lmin_s, &port->gss->outbuf);
984                 }
985
986                 if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
987                 {
988                         OM_uint32       lmin_s;
989
990                         gss_delete_sec_context(&lmin_s, &port->gss->ctx, GSS_C_NO_BUFFER);
991                         pg_GSS_error(ERROR,
992                                            gettext_noop("accepting GSS security context failed"),
993                                                  maj_stat, min_stat);
994                 }
995
996                 if (maj_stat == GSS_S_CONTINUE_NEEDED)
997                         elog(DEBUG4, "GSS continue needed");
998
999         } while (maj_stat == GSS_S_CONTINUE_NEEDED);
1000
1001         if (port->gss->cred != GSS_C_NO_CREDENTIAL)
1002         {
1003                 /*
1004                  * Release service principal credentials
1005                  */
1006                 gss_release_cred(&min_stat, &port->gss->cred);
1007         }
1008
1009         /*
1010          * GSS_S_COMPLETE indicates that authentication is now complete.
1011          *
1012          * Get the name of the user that authenticated, and compare it to the pg
1013          * username that was specified for the connection.
1014          */
1015         maj_stat = gss_display_name(&min_stat, port->gss->name, &gbuf, NULL);
1016         if (maj_stat != GSS_S_COMPLETE)
1017                 pg_GSS_error(ERROR,
1018                                          gettext_noop("retrieving GSS user name failed"),
1019                                          maj_stat, min_stat);
1020
1021         /*
1022          * Split the username at the realm separator
1023          */
1024         if (strchr(gbuf.value, '@'))
1025         {
1026                 char       *cp = strchr(gbuf.value, '@');
1027
1028                 *cp = '\0';
1029                 cp++;
1030
1031                 if (pg_krb_realm != NULL && strlen(pg_krb_realm))
1032                 {
1033                         /*
1034                          * Match the realm part of the name first
1035                          */
1036                         if (pg_krb_caseins_users)
1037                                 ret = pg_strcasecmp(pg_krb_realm, cp);
1038                         else
1039                                 ret = strcmp(pg_krb_realm, cp);
1040
1041                         if (ret)
1042                         {
1043                                 /* GSS realm does not match */
1044                                 elog(DEBUG2,
1045                                    "GSSAPI realm (%s) and configured realm (%s) don't match",
1046                                          cp, pg_krb_realm);
1047                                 gss_release_buffer(&lmin_s, &gbuf);
1048                                 return STATUS_ERROR;
1049                         }
1050                 }
1051         }
1052         else if (pg_krb_realm && strlen(pg_krb_realm))
1053         {
1054                 elog(DEBUG2,
1055                          "GSSAPI did not return realm but realm matching was requested");
1056
1057                 gss_release_buffer(&lmin_s, &gbuf);
1058                 return STATUS_ERROR;
1059         }
1060
1061         ret = check_usermap(port->hba->usermap, port->user_name, gbuf.value,
1062                                                 pg_krb_caseins_users);
1063
1064         gss_release_buffer(&lmin_s, &gbuf);
1065
1066         return STATUS_OK;
1067 }
1068 #endif   /* ENABLE_GSS */
1069
1070
1071 /*----------------------------------------------------------------
1072  * SSPI authentication system
1073  *----------------------------------------------------------------
1074  */
1075 #ifdef ENABLE_SSPI
1076 static void
1077 pg_SSPI_error(int severity, char *errmsg, SECURITY_STATUS r)
1078 {
1079         char            sysmsg[256];
1080
1081         if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, r, 0, sysmsg, sizeof(sysmsg), NULL) == 0)
1082                 ereport(severity,
1083                                 (errmsg_internal("%s", errmsg),
1084                                  errdetail("SSPI error %x", (unsigned int) r)));
1085         else
1086                 ereport(severity,
1087                                 (errmsg_internal("%s", errmsg),
1088                                  errdetail("%s (%x)", sysmsg, (unsigned int) r)));
1089 }
1090
1091 static int
1092 pg_SSPI_recvauth(Port *port)
1093 {
1094         int                     mtype;
1095         StringInfoData buf;
1096         SECURITY_STATUS r;
1097         CredHandle      sspicred;
1098         CtxtHandle *sspictx = NULL,
1099                                 newctx;
1100         TimeStamp       expiry;
1101         ULONG           contextattr;
1102         SecBufferDesc inbuf;
1103         SecBufferDesc outbuf;
1104         SecBuffer       OutBuffers[1];
1105         SecBuffer       InBuffers[1];
1106         HANDLE          token;
1107         TOKEN_USER *tokenuser;
1108         DWORD           retlen;
1109         char            accountname[MAXPGPATH];
1110         char            domainname[MAXPGPATH];
1111         DWORD           accountnamesize = sizeof(accountname);
1112         DWORD           domainnamesize = sizeof(domainname);
1113         SID_NAME_USE accountnameuse;
1114         HMODULE         secur32;
1115         QUERY_SECURITY_CONTEXT_TOKEN_FN _QuerySecurityContextToken;
1116
1117         /*
1118          * SSPI auth is not supported for protocol versions before 3, because it
1119          * relies on the overall message length word to determine the SSPI payload
1120          * size in AuthenticationGSSContinue and PasswordMessage messages.
1121          * (This is, in fact, a design error in our SSPI support, because protocol
1122          * messages are supposed to be parsable without relying on the length
1123          * word; but it's not worth changing it now.)
1124          */
1125         if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
1126                 ereport(FATAL,
1127                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1128                                  errmsg("SSPI is not supported in protocol version 2")));
1129
1130         /*
1131          * Acquire a handle to the server credentials.
1132          */
1133         r = AcquireCredentialsHandle(NULL,
1134                                                                  "negotiate",
1135                                                                  SECPKG_CRED_INBOUND,
1136                                                                  NULL,
1137                                                                  NULL,
1138                                                                  NULL,
1139                                                                  NULL,
1140                                                                  &sspicred,
1141                                                                  &expiry);
1142         if (r != SEC_E_OK)
1143                 pg_SSPI_error(ERROR,
1144                            gettext_noop("could not acquire SSPI credentials handle"), r);
1145
1146         /*
1147          * Loop through SSPI message exchange. This exchange can consist of
1148          * multiple messags sent in both directions. First message is always from
1149          * the client. All messages from client to server are password packets
1150          * (type 'p').
1151          */
1152         do
1153         {
1154                 mtype = pq_getbyte();
1155                 if (mtype != 'p')
1156                 {
1157                         /* Only log error if client didn't disconnect. */
1158                         if (mtype != EOF)
1159                                 ereport(COMMERROR,
1160                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
1161                                                  errmsg("expected SSPI response, got message type %d",
1162                                                                 mtype)));
1163                         return STATUS_ERROR;
1164                 }
1165
1166                 /* Get the actual SSPI token */
1167                 initStringInfo(&buf);
1168                 if (pq_getmessage(&buf, 2000))
1169                 {
1170                         /* EOF - pq_getmessage already logged error */
1171                         pfree(buf.data);
1172                         return STATUS_ERROR;
1173                 }
1174
1175                 /* Map to SSPI style buffer */
1176                 inbuf.ulVersion = SECBUFFER_VERSION;
1177                 inbuf.cBuffers = 1;
1178                 inbuf.pBuffers = InBuffers;
1179                 InBuffers[0].pvBuffer = buf.data;
1180                 InBuffers[0].cbBuffer = buf.len;
1181                 InBuffers[0].BufferType = SECBUFFER_TOKEN;
1182
1183                 /* Prepare output buffer */
1184                 OutBuffers[0].pvBuffer = NULL;
1185                 OutBuffers[0].BufferType = SECBUFFER_TOKEN;
1186                 OutBuffers[0].cbBuffer = 0;
1187                 outbuf.cBuffers = 1;
1188                 outbuf.pBuffers = OutBuffers;
1189                 outbuf.ulVersion = SECBUFFER_VERSION;
1190
1191
1192                 elog(DEBUG4, "Processing received SSPI token of length %u",
1193                          (unsigned int) buf.len);
1194
1195                 r = AcceptSecurityContext(&sspicred,
1196                                                                   sspictx,
1197                                                                   &inbuf,
1198                                                                   ASC_REQ_ALLOCATE_MEMORY,
1199                                                                   SECURITY_NETWORK_DREP,
1200                                                                   &newctx,
1201                                                                   &outbuf,
1202                                                                   &contextattr,
1203                                                                   NULL);
1204
1205                 /* input buffer no longer used */
1206                 pfree(buf.data);
1207
1208                 if (outbuf.cBuffers > 0 && outbuf.pBuffers[0].cbBuffer > 0)
1209                 {
1210                         /*
1211                          * Negotiation generated data to be sent to the client.
1212                          */
1213                         elog(DEBUG4, "sending SSPI response token of length %u",
1214                                  (unsigned int) outbuf.pBuffers[0].cbBuffer);
1215
1216                         port->gss->outbuf.length = outbuf.pBuffers[0].cbBuffer;
1217                         port->gss->outbuf.value = outbuf.pBuffers[0].pvBuffer;
1218
1219                         sendAuthRequest(port, AUTH_REQ_GSS_CONT);
1220
1221                         FreeContextBuffer(outbuf.pBuffers[0].pvBuffer);
1222                 }
1223
1224                 if (r != SEC_E_OK && r != SEC_I_CONTINUE_NEEDED)
1225                 {
1226                         if (sspictx != NULL)
1227                         {
1228                                 DeleteSecurityContext(sspictx);
1229                                 free(sspictx);
1230                         }
1231                         FreeCredentialsHandle(&sspicred);
1232                         pg_SSPI_error(ERROR,
1233                                   gettext_noop("could not accept SSPI security context"), r);
1234                 }
1235
1236                 if (sspictx == NULL)
1237                 {
1238                         sspictx = malloc(sizeof(CtxtHandle));
1239                         if (sspictx == NULL)
1240                                 ereport(ERROR,
1241                                                 (errmsg("out of memory")));
1242
1243                         memcpy(sspictx, &newctx, sizeof(CtxtHandle));
1244                 }
1245
1246                 if (r == SEC_I_CONTINUE_NEEDED)
1247                         elog(DEBUG4, "SSPI continue needed");
1248
1249         } while (r == SEC_I_CONTINUE_NEEDED);
1250
1251
1252         /*
1253          * Release service principal credentials
1254          */
1255         FreeCredentialsHandle(&sspicred);
1256
1257
1258         /*
1259          * SEC_E_OK indicates that authentication is now complete.
1260          *
1261          * Get the name of the user that authenticated, and compare it to the pg
1262          * username that was specified for the connection.
1263          *
1264          * MingW is missing the export for QuerySecurityContextToken in the
1265          * secur32 library, so we have to load it dynamically.
1266          */
1267
1268         secur32 = LoadLibrary("SECUR32.DLL");
1269         if (secur32 == NULL)
1270                 ereport(ERROR,
1271                                 (errmsg_internal("could not load secur32.dll: %d",
1272                                                                  (int) GetLastError())));
1273
1274         _QuerySecurityContextToken = (QUERY_SECURITY_CONTEXT_TOKEN_FN)
1275                 GetProcAddress(secur32, "QuerySecurityContextToken");
1276         if (_QuerySecurityContextToken == NULL)
1277         {
1278                 FreeLibrary(secur32);
1279                 ereport(ERROR,
1280                                 (errmsg_internal("could not locate QuerySecurityContextToken in secur32.dll: %d",
1281                                                                  (int) GetLastError())));
1282         }
1283
1284         r = (_QuerySecurityContextToken) (sspictx, &token);
1285         if (r != SEC_E_OK)
1286         {
1287                 FreeLibrary(secur32);
1288                 pg_SSPI_error(ERROR,
1289                            gettext_noop("could not get security token from context"), r);
1290         }
1291
1292         FreeLibrary(secur32);
1293
1294         /*
1295          * No longer need the security context, everything from here on uses the
1296          * token instead.
1297          */
1298         DeleteSecurityContext(sspictx);
1299         free(sspictx);
1300
1301         if (!GetTokenInformation(token, TokenUser, NULL, 0, &retlen) && GetLastError() != 122)
1302                 ereport(ERROR,
1303                          (errmsg_internal("could not get token user size: error code %d",
1304                                                           (int) GetLastError())));
1305
1306         tokenuser = malloc(retlen);
1307         if (tokenuser == NULL)
1308                 ereport(ERROR,
1309                                 (errmsg("out of memory")));
1310
1311         if (!GetTokenInformation(token, TokenUser, tokenuser, retlen, &retlen))
1312                 ereport(ERROR,
1313                                 (errmsg_internal("could not get user token: error code %d",
1314                                                                  (int) GetLastError())));
1315
1316         if (!LookupAccountSid(NULL, tokenuser->User.Sid, accountname, &accountnamesize,
1317                                                   domainname, &domainnamesize, &accountnameuse))
1318                 ereport(ERROR,
1319                           (errmsg_internal("could not lookup acconut sid: error code %d",
1320                                                            (int) GetLastError())));
1321
1322         free(tokenuser);
1323
1324         /*
1325          * Compare realm/domain if requested. In SSPI, always compare case
1326          * insensitive.
1327          */
1328         if (pg_krb_realm && strlen(pg_krb_realm))
1329         {
1330                 if (pg_strcasecmp(pg_krb_realm, domainname))
1331                 {
1332                         elog(DEBUG2,
1333                                  "SSPI domain (%s) and configured domain (%s) don't match",
1334                                  domainname, pg_krb_realm);
1335
1336                         return STATUS_ERROR;
1337                 }
1338         }
1339
1340         /*
1341          * We have the username (without domain/realm) in accountname, compare to
1342          * the supplied value. In SSPI, always compare case insensitive.
1343          */
1344         return check_usermap(port->hba->usermap, port->user_name, accountname, true);
1345 }
1346 #endif   /* ENABLE_SSPI */
1347
1348
1349
1350 /*----------------------------------------------------------------
1351  * Ident authentication system
1352  *----------------------------------------------------------------
1353  */
1354
1355 /*
1356  *      Parse the string "*ident_response" as a response from a query to an Ident
1357  *      server.  If it's a normal response indicating a user name, return true
1358  *      and store the user name at *ident_user. If it's anything else,
1359  *      return false.
1360  */
1361 static bool
1362 interpret_ident_response(const char *ident_response,
1363                                                  char *ident_user)
1364 {
1365         const char *cursor = ident_response;            /* Cursor into *ident_response */
1366
1367         /*
1368          * Ident's response, in the telnet tradition, should end in crlf (\r\n).
1369          */
1370         if (strlen(ident_response) < 2)
1371                 return false;
1372         else if (ident_response[strlen(ident_response) - 2] != '\r')
1373                 return false;
1374         else
1375         {
1376                 while (*cursor != ':' && *cursor != '\r')
1377                         cursor++;                       /* skip port field */
1378
1379                 if (*cursor != ':')
1380                         return false;
1381                 else
1382                 {
1383                         /* We're positioned to colon before response type field */
1384                         char            response_type[80];
1385                         int                     i;              /* Index into *response_type */
1386
1387                         cursor++;                       /* Go over colon */
1388                         while (pg_isblank(*cursor))
1389                                 cursor++;               /* skip blanks */
1390                         i = 0;
1391                         while (*cursor != ':' && *cursor != '\r' && !pg_isblank(*cursor) &&
1392                                    i < (int) (sizeof(response_type) - 1))
1393                                 response_type[i++] = *cursor++;
1394                         response_type[i] = '\0';
1395                         while (pg_isblank(*cursor))
1396                                 cursor++;               /* skip blanks */
1397                         if (strcmp(response_type, "USERID") != 0)
1398                                 return false;
1399                         else
1400                         {
1401                                 /*
1402                                  * It's a USERID response.  Good.  "cursor" should be pointing
1403                                  * to the colon that precedes the operating system type.
1404                                  */
1405                                 if (*cursor != ':')
1406                                         return false;
1407                                 else
1408                                 {
1409                                         cursor++;       /* Go over colon */
1410                                         /* Skip over operating system field. */
1411                                         while (*cursor != ':' && *cursor != '\r')
1412                                                 cursor++;
1413                                         if (*cursor != ':')
1414                                                 return false;
1415                                         else
1416                                         {
1417                                                 int                     i;      /* Index into *ident_user */
1418
1419                                                 cursor++;               /* Go over colon */
1420                                                 while (pg_isblank(*cursor))
1421                                                         cursor++;       /* skip blanks */
1422                                                 /* Rest of line is user name.  Copy it over. */
1423                                                 i = 0;
1424                                                 while (*cursor != '\r' && i < IDENT_USERNAME_MAX)
1425                                                         ident_user[i++] = *cursor++;
1426                                                 ident_user[i] = '\0';
1427                                                 return true;
1428                                         }
1429                                 }
1430                         }
1431                 }
1432         }
1433 }
1434
1435
1436 /*
1437  *      Talk to the ident server on host "remote_ip_addr" and find out who
1438  *      owns the tcp connection from his port "remote_port" to port
1439  *      "local_port_addr" on host "local_ip_addr".      Return the user name the
1440  *      ident server gives as "*ident_user".
1441  *
1442  *      IP addresses and port numbers are in network byte order.
1443  *
1444  *      But iff we're unable to get the information from ident, return false.
1445  */
1446 static bool
1447 ident_inet(const SockAddr remote_addr,
1448                    const SockAddr local_addr,
1449                    char *ident_user)
1450 {
1451         int                     sock_fd,                /* File descriptor for socket on which we talk
1452                                                                  * to Ident */
1453                                 rc;                             /* Return code from a locally called function */
1454         bool            ident_return;
1455         char            remote_addr_s[NI_MAXHOST];
1456         char            remote_port[NI_MAXSERV];
1457         char            local_addr_s[NI_MAXHOST];
1458         char            local_port[NI_MAXSERV];
1459         char            ident_port[NI_MAXSERV];
1460         char            ident_query[80];
1461         char            ident_response[80 + IDENT_USERNAME_MAX];
1462         struct addrinfo *ident_serv = NULL,
1463                            *la = NULL,
1464                                 hints;
1465
1466         /*
1467          * Might look a little weird to first convert it to text and then back to
1468          * sockaddr, but it's protocol independent.
1469          */
1470         pg_getnameinfo_all(&remote_addr.addr, remote_addr.salen,
1471                                            remote_addr_s, sizeof(remote_addr_s),
1472                                            remote_port, sizeof(remote_port),
1473                                            NI_NUMERICHOST | NI_NUMERICSERV);
1474         pg_getnameinfo_all(&local_addr.addr, local_addr.salen,
1475                                            local_addr_s, sizeof(local_addr_s),
1476                                            local_port, sizeof(local_port),
1477                                            NI_NUMERICHOST | NI_NUMERICSERV);
1478
1479         snprintf(ident_port, sizeof(ident_port), "%d", IDENT_PORT);
1480         hints.ai_flags = AI_NUMERICHOST;
1481         hints.ai_family = remote_addr.addr.ss_family;
1482         hints.ai_socktype = SOCK_STREAM;
1483         hints.ai_protocol = 0;
1484         hints.ai_addrlen = 0;
1485         hints.ai_canonname = NULL;
1486         hints.ai_addr = NULL;
1487         hints.ai_next = NULL;
1488         rc = pg_getaddrinfo_all(remote_addr_s, ident_port, &hints, &ident_serv);
1489         if (rc || !ident_serv)
1490         {
1491                 if (ident_serv)
1492                         pg_freeaddrinfo_all(hints.ai_family, ident_serv);
1493                 return false;                   /* we don't expect this to happen */
1494         }
1495
1496         hints.ai_flags = AI_NUMERICHOST;
1497         hints.ai_family = local_addr.addr.ss_family;
1498         hints.ai_socktype = SOCK_STREAM;
1499         hints.ai_protocol = 0;
1500         hints.ai_addrlen = 0;
1501         hints.ai_canonname = NULL;
1502         hints.ai_addr = NULL;
1503         hints.ai_next = NULL;
1504         rc = pg_getaddrinfo_all(local_addr_s, NULL, &hints, &la);
1505         if (rc || !la)
1506         {
1507                 if (la)
1508                         pg_freeaddrinfo_all(hints.ai_family, la);
1509                 return false;                   /* we don't expect this to happen */
1510         }
1511
1512         sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
1513                                          ident_serv->ai_protocol);
1514         if (sock_fd < 0)
1515         {
1516                 ereport(LOG,
1517                                 (errcode_for_socket_access(),
1518                                  errmsg("could not create socket for Ident connection: %m")));
1519                 ident_return = false;
1520                 goto ident_inet_done;
1521         }
1522
1523         /*
1524          * Bind to the address which the client originally contacted, otherwise
1525          * the ident server won't be able to match up the right connection. This
1526          * is necessary if the PostgreSQL server is running on an IP alias.
1527          */
1528         rc = bind(sock_fd, la->ai_addr, la->ai_addrlen);
1529         if (rc != 0)
1530         {
1531                 ereport(LOG,
1532                                 (errcode_for_socket_access(),
1533                                  errmsg("could not bind to local address \"%s\": %m",
1534                                                 local_addr_s)));
1535                 ident_return = false;
1536                 goto ident_inet_done;
1537         }
1538
1539         rc = connect(sock_fd, ident_serv->ai_addr,
1540                                  ident_serv->ai_addrlen);
1541         if (rc != 0)
1542         {
1543                 ereport(LOG,
1544                                 (errcode_for_socket_access(),
1545                                  errmsg("could not connect to Ident server at address \"%s\", port %s: %m",
1546                                                 remote_addr_s, ident_port)));
1547                 ident_return = false;
1548                 goto ident_inet_done;
1549         }
1550
1551         /* The query we send to the Ident server */
1552         snprintf(ident_query, sizeof(ident_query), "%s,%s\r\n",
1553                          remote_port, local_port);
1554
1555         /* loop in case send is interrupted */
1556         do
1557         {
1558                 rc = send(sock_fd, ident_query, strlen(ident_query), 0);
1559         } while (rc < 0 && errno == EINTR);
1560
1561         if (rc < 0)
1562         {
1563                 ereport(LOG,
1564                                 (errcode_for_socket_access(),
1565                                  errmsg("could not send query to Ident server at address \"%s\", port %s: %m",
1566                                                 remote_addr_s, ident_port)));
1567                 ident_return = false;
1568                 goto ident_inet_done;
1569         }
1570
1571         do
1572         {
1573                 rc = recv(sock_fd, ident_response, sizeof(ident_response) - 1, 0);
1574         } while (rc < 0 && errno == EINTR);
1575
1576         if (rc < 0)
1577         {
1578                 ereport(LOG,
1579                                 (errcode_for_socket_access(),
1580                                  errmsg("could not receive response from Ident server at address \"%s\", port %s: %m",
1581                                                 remote_addr_s, ident_port)));
1582                 ident_return = false;
1583                 goto ident_inet_done;
1584         }
1585
1586         ident_response[rc] = '\0';
1587         ident_return = interpret_ident_response(ident_response, ident_user);
1588         if (!ident_return)
1589                 ereport(LOG,
1590                         (errmsg("invalidly formatted response from Ident server: \"%s\"",
1591                                         ident_response)));
1592
1593 ident_inet_done:
1594         if (sock_fd >= 0)
1595                 closesocket(sock_fd);
1596         pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
1597         pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
1598         return ident_return;
1599 }
1600
1601 /*
1602  *      Ask kernel about the credentials of the connecting process and
1603  *      determine the symbolic name of the corresponding user.
1604  *
1605  *      Returns either true and the username put into "ident_user",
1606  *      or false if we were unable to determine the username.
1607  */
1608 #ifdef HAVE_UNIX_SOCKETS
1609
1610 static bool
1611 ident_unix(int sock, char *ident_user)
1612 {
1613 #if defined(HAVE_GETPEEREID)
1614         /* OpenBSD style:  */
1615         uid_t           uid;
1616         gid_t           gid;
1617         struct passwd *pass;
1618
1619         errno = 0;
1620         if (getpeereid(sock, &uid, &gid) != 0)
1621         {
1622                 /* We didn't get a valid credentials struct. */
1623                 ereport(LOG,
1624                                 (errcode_for_socket_access(),
1625                                  errmsg("could not get peer credentials: %m")));
1626                 return false;
1627         }
1628
1629         pass = getpwuid(uid);
1630
1631         if (pass == NULL)
1632         {
1633                 ereport(LOG,
1634                                 (errmsg("local user with ID %d does not exist",
1635                                                 (int) uid)));
1636                 return false;
1637         }
1638
1639         strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
1640
1641         return true;
1642 #elif defined(SO_PEERCRED)
1643         /* Linux style: use getsockopt(SO_PEERCRED) */
1644         struct ucred peercred;
1645         ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);
1646         struct passwd *pass;
1647
1648         errno = 0;
1649         if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 ||
1650                 so_len != sizeof(peercred))
1651         {
1652                 /* We didn't get a valid credentials struct. */
1653                 ereport(LOG,
1654                                 (errcode_for_socket_access(),
1655                                  errmsg("could not get peer credentials: %m")));
1656                 return false;
1657         }
1658
1659         pass = getpwuid(peercred.uid);
1660
1661         if (pass == NULL)
1662         {
1663                 ereport(LOG,
1664                                 (errmsg("local user with ID %d does not exist",
1665                                                 (int) peercred.uid)));
1666                 return false;
1667         }
1668
1669         strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
1670
1671         return true;
1672 #elif defined(HAVE_GETPEERUCRED)
1673         /* Solaris > 10 */
1674         uid_t           uid;
1675         struct passwd *pass;
1676         ucred_t    *ucred;
1677
1678         ucred = NULL; /* must be initialized to NULL */
1679         if (getpeerucred(sock, &ucred) == -1)
1680         {
1681                 ereport(LOG,
1682                                 (errcode_for_socket_access(),
1683                                  errmsg("could not get peer credentials: %m")));
1684                 return false;
1685         }
1686
1687         if ((uid = ucred_geteuid(ucred)) == -1)
1688         {
1689                 ereport(LOG,
1690                                 (errcode_for_socket_access(),
1691                                  errmsg("could not get effective UID from peer credentials: %m")));
1692                 return false;
1693         }
1694
1695         ucred_free(ucred);
1696
1697         pass = getpwuid(uid);
1698         if (pass == NULL)
1699         {
1700                 ereport(LOG,
1701                         (errmsg("local user with ID %d does not exist",
1702                                         (int) uid)));
1703                 return false;
1704         }
1705
1706         strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
1707
1708         return true;
1709 #elif defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS))
1710         struct msghdr msg;
1711
1712 /* Credentials structure */
1713 #if defined(HAVE_STRUCT_CMSGCRED)
1714         typedef struct cmsgcred Cred;
1715
1716 #define cruid cmcred_uid
1717 #elif defined(HAVE_STRUCT_FCRED)
1718         typedef struct fcred Cred;
1719
1720 #define cruid fc_uid
1721 #elif defined(HAVE_STRUCT_SOCKCRED)
1722         typedef struct sockcred Cred;
1723
1724 #define cruid sc_uid
1725 #endif
1726         Cred       *cred;
1727
1728         /* Compute size without padding */
1729         char            cmsgmem[ALIGN(sizeof(struct cmsghdr)) + ALIGN(sizeof(Cred))];   /* for NetBSD */
1730
1731         /* Point to start of first structure */
1732         struct cmsghdr *cmsg = (struct cmsghdr *) cmsgmem;
1733
1734         struct iovec iov;
1735         char            buf;
1736         struct passwd *pw;
1737
1738         memset(&msg, 0, sizeof(msg));
1739         msg.msg_iov = &iov;
1740         msg.msg_iovlen = 1;
1741         msg.msg_control = (char *) cmsg;
1742         msg.msg_controllen = sizeof(cmsgmem);
1743         memset(cmsg, 0, sizeof(cmsgmem));
1744
1745         /*
1746          * The one character which is received here is not meaningful; its
1747          * purposes is only to make sure that recvmsg() blocks long enough for the
1748          * other side to send its credentials.
1749          */
1750         iov.iov_base = &buf;
1751         iov.iov_len = 1;
1752
1753         if (recvmsg(sock, &msg, 0) < 0 ||
1754                 cmsg->cmsg_len < sizeof(cmsgmem) ||
1755                 cmsg->cmsg_type != SCM_CREDS)
1756         {
1757                 ereport(LOG,
1758                                 (errcode_for_socket_access(),
1759                                  errmsg("could not get peer credentials: %m")));
1760                 return false;
1761         }
1762
1763         cred = (Cred *) CMSG_DATA(cmsg);
1764
1765         pw = getpwuid(cred->cruid);
1766
1767         if (pw == NULL)
1768         {
1769                 ereport(LOG,
1770                                 (errmsg("local user with ID %d does not exist",
1771                                                 (int) cred->cruid)));
1772                 return false;
1773         }
1774
1775         strlcpy(ident_user, pw->pw_name, IDENT_USERNAME_MAX + 1);
1776
1777         return true;
1778 #else
1779         ereport(LOG,
1780                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1781                          errmsg("Ident authentication is not supported on local connections on this platform")));
1782
1783         return false;
1784 #endif
1785 }
1786 #endif   /* HAVE_UNIX_SOCKETS */
1787
1788
1789 /*
1790  *      Determine the username of the initiator of the connection described
1791  *      by "port".      Then look in the usermap file under the usermap
1792  *      port->hba->usermap and see if that user is equivalent to Postgres user
1793  *      port->user.
1794  *
1795  *      Return STATUS_OK if yes, STATUS_ERROR if no match (or couldn't get info).
1796  */
1797 static int
1798 authident(hbaPort *port)
1799 {
1800         char            ident_user[IDENT_USERNAME_MAX + 1];
1801
1802         if (get_role_line(port->user_name) == NULL)
1803                 return STATUS_ERROR;
1804
1805         switch (port->raddr.addr.ss_family)
1806         {
1807                 case AF_INET:
1808 #ifdef  HAVE_IPV6
1809                 case AF_INET6:
1810 #endif
1811                         if (!ident_inet(port->raddr, port->laddr, ident_user))
1812                                 return STATUS_ERROR;
1813                         break;
1814
1815 #ifdef HAVE_UNIX_SOCKETS
1816                 case AF_UNIX:
1817                         if (!ident_unix(port->sock, ident_user))
1818                                 return STATUS_ERROR;
1819                         break;
1820 #endif
1821
1822                 default:
1823                         return STATUS_ERROR;
1824         }
1825
1826         return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
1827 }
1828
1829
1830 /*----------------------------------------------------------------
1831  * PAM authentication system
1832  *----------------------------------------------------------------
1833  */
1834 #ifdef USE_PAM
1835
1836 /*
1837  * PAM conversation function
1838  */
1839
1840 static int
1841 pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg,
1842                                          struct pam_response ** resp, void *appdata_ptr)
1843 {
1844         if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF)
1845         {
1846                 switch (msg[0]->msg_style)
1847                 {
1848                         case PAM_ERROR_MSG:
1849                                 ereport(LOG,
1850                                                 (errmsg("error from underlying PAM layer: %s",
1851                                                                 msg[0]->msg)));
1852                                 return PAM_CONV_ERR;
1853                         default:
1854                                 ereport(LOG,
1855                                                 (errmsg("unsupported PAM conversation %d/%s",
1856                                                                 msg[0]->msg_style, msg[0]->msg)));
1857                                 return PAM_CONV_ERR;
1858                 }
1859         }
1860
1861         if (!appdata_ptr)
1862         {
1863                 /*
1864                  * Workaround for Solaris 2.6 where the PAM library is broken and does
1865                  * not pass appdata_ptr to the conversation routine
1866                  */
1867                 appdata_ptr = pam_passwd;
1868         }
1869
1870         /*
1871          * Password wasn't passed to PAM the first time around - let's go ask the
1872          * client to send a password, which we then stuff into PAM.
1873          */
1874         if (strlen(appdata_ptr) == 0)
1875         {
1876                 char       *passwd;
1877
1878                 sendAuthRequest(pam_port_cludge, AUTH_REQ_PASSWORD);
1879                 passwd = recv_password_packet(pam_port_cludge);
1880
1881                 if (passwd == NULL)
1882                         return PAM_CONV_ERR;    /* client didn't want to send password */
1883
1884                 if (strlen(passwd) == 0)
1885                 {
1886                         ereport(LOG,
1887                                         (errmsg("empty password returned by client")));
1888                         return PAM_CONV_ERR;
1889                 }
1890                 appdata_ptr = passwd;
1891         }
1892
1893         /*
1894          * Explicitly not using palloc here - PAM will free this memory in
1895          * pam_end()
1896          */
1897         *resp = calloc(num_msg, sizeof(struct pam_response));
1898         if (!*resp)
1899         {
1900                 ereport(LOG,
1901                                 (errcode(ERRCODE_OUT_OF_MEMORY),
1902                                  errmsg("out of memory")));
1903                 return PAM_CONV_ERR;
1904         }
1905
1906         (*resp)[0].resp = strdup((char *) appdata_ptr);
1907         (*resp)[0].resp_retcode = 0;
1908
1909         return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR);
1910 }
1911
1912
1913 /*
1914  * Check authentication against PAM.
1915  */
1916 static int
1917 CheckPAMAuth(Port *port, char *user, char *password)
1918 {
1919         int                     retval;
1920         pam_handle_t *pamh = NULL;
1921
1922         /*
1923          * Apparently, Solaris 2.6 is broken, and needs ugly static variable
1924          * workaround
1925          */
1926         pam_passwd = password;
1927
1928         /*
1929          * Set the application data portion of the conversation struct This is
1930          * later used inside the PAM conversation to pass the password to the
1931          * authentication module.
1932          */
1933         pam_passw_conv.appdata_ptr = (char *) password;         /* from password above,
1934                                                                                                                  * not allocated */
1935
1936         /* Optionally, one can set the service name in pg_hba.conf */
1937         if (port->hba->pamservice && port->hba->pamservice[0] != '\0')
1938                 retval = pam_start(port->hba->pamservice, "pgsql@",
1939                                                    &pam_passw_conv, &pamh);
1940         else
1941                 retval = pam_start(PGSQL_PAM_SERVICE, "pgsql@",
1942                                                    &pam_passw_conv, &pamh);
1943
1944         if (retval != PAM_SUCCESS)
1945         {
1946                 ereport(LOG,
1947                                 (errmsg("could not create PAM authenticator: %s",
1948                                                 pam_strerror(pamh, retval))));
1949                 pam_passwd = NULL;              /* Unset pam_passwd */
1950                 return STATUS_ERROR;
1951         }
1952
1953         retval = pam_set_item(pamh, PAM_USER, user);
1954
1955         if (retval != PAM_SUCCESS)
1956         {
1957                 ereport(LOG,
1958                                 (errmsg("pam_set_item(PAM_USER) failed: %s",
1959                                                 pam_strerror(pamh, retval))));
1960                 pam_passwd = NULL;              /* Unset pam_passwd */
1961                 return STATUS_ERROR;
1962         }
1963
1964         retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv);
1965
1966         if (retval != PAM_SUCCESS)
1967         {
1968                 ereport(LOG,
1969                                 (errmsg("pam_set_item(PAM_CONV) failed: %s",
1970                                                 pam_strerror(pamh, retval))));
1971                 pam_passwd = NULL;              /* Unset pam_passwd */
1972                 return STATUS_ERROR;
1973         }
1974
1975         retval = pam_authenticate(pamh, 0);
1976
1977         if (retval != PAM_SUCCESS)
1978         {
1979                 ereport(LOG,
1980                                 (errmsg("pam_authenticate failed: %s",
1981                                                 pam_strerror(pamh, retval))));
1982                 pam_passwd = NULL;              /* Unset pam_passwd */
1983                 return STATUS_ERROR;
1984         }
1985
1986         retval = pam_acct_mgmt(pamh, 0);
1987
1988         if (retval != PAM_SUCCESS)
1989         {
1990                 ereport(LOG,
1991                                 (errmsg("pam_acct_mgmt failed: %s",
1992                                                 pam_strerror(pamh, retval))));
1993                 pam_passwd = NULL;              /* Unset pam_passwd */
1994                 return STATUS_ERROR;
1995         }
1996
1997         retval = pam_end(pamh, retval);
1998
1999         if (retval != PAM_SUCCESS)
2000         {
2001                 ereport(LOG,
2002                                 (errmsg("could not release PAM authenticator: %s",
2003                                                 pam_strerror(pamh, retval))));
2004         }
2005
2006         pam_passwd = NULL;                      /* Unset pam_passwd */
2007
2008         return (retval == PAM_SUCCESS ? STATUS_OK : STATUS_ERROR);
2009 }
2010 #endif   /* USE_PAM */
2011
2012
2013
2014 /*----------------------------------------------------------------
2015  * LDAP authentication system
2016  *----------------------------------------------------------------
2017  */
2018 #ifdef USE_LDAP
2019
2020 static int
2021 CheckLDAPAuth(Port *port)
2022 {
2023         char       *passwd;
2024         LDAP       *ldap;
2025         int                     r;
2026         int                     ldapversion = LDAP_VERSION3;
2027         char            fulluser[NAMEDATALEN + 256 + 1];
2028
2029         if (!port->hba->ldapserver|| port->hba->ldapserver[0] == '\0')
2030         {
2031                 ereport(LOG,
2032                                 (errmsg("LDAP server not specified")));
2033                 return STATUS_ERROR;
2034         }
2035
2036         if (port->hba->ldapport == 0)
2037                 port->hba->ldapport = LDAP_PORT;
2038
2039         sendAuthRequest(port, AUTH_REQ_PASSWORD);
2040
2041         passwd = recv_password_packet(port);
2042         if (passwd == NULL)
2043                 return STATUS_EOF;              /* client wouldn't send password */
2044
2045         ldap = ldap_init(port->hba->ldapserver, port->hba->ldapport);
2046         if (!ldap)
2047         {
2048 #ifndef WIN32
2049                 ereport(LOG,
2050                                 (errmsg("could not initialize LDAP: error code %d",
2051                                                 errno)));
2052 #else
2053                 ereport(LOG,
2054                                 (errmsg("could not initialize LDAP: error code %d",
2055                                                 (int) LdapGetLastError())));
2056 #endif
2057                 return STATUS_ERROR;
2058         }
2059
2060         if ((r = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldapversion)) != LDAP_SUCCESS)
2061         {
2062                 ldap_unbind(ldap);
2063                 ereport(LOG,
2064                   (errmsg("could not set LDAP protocol version: error code %d", r)));
2065                 return STATUS_ERROR;
2066         }
2067
2068         if (port->hba->ldaptls)
2069         {
2070 #ifndef WIN32
2071                 if ((r = ldap_start_tls_s(ldap, NULL, NULL)) != LDAP_SUCCESS)
2072 #else
2073                 static __ldap_start_tls_sA _ldap_start_tls_sA = NULL;
2074
2075                 if (_ldap_start_tls_sA == NULL)
2076                 {
2077                         /*
2078                          * Need to load this function dynamically because it does not
2079                          * exist on Windows 2000, and causes a load error for the whole
2080                          * exe if referenced.
2081                          */
2082                         HANDLE          ldaphandle;
2083
2084                         ldaphandle = LoadLibrary("WLDAP32.DLL");
2085                         if (ldaphandle == NULL)
2086                         {
2087                                 /*
2088                                  * should never happen since we import other files from
2089                                  * wldap32, but check anyway
2090                                  */
2091                                 ldap_unbind(ldap);
2092                                 ereport(LOG,
2093                                                 (errmsg("could not load wldap32.dll")));
2094                                 return STATUS_ERROR;
2095                         }
2096                         _ldap_start_tls_sA = (__ldap_start_tls_sA) GetProcAddress(ldaphandle, "ldap_start_tls_sA");
2097                         if (_ldap_start_tls_sA == NULL)
2098                         {
2099                                 ldap_unbind(ldap);
2100                                 ereport(LOG,
2101                                                 (errmsg("could not load function _ldap_start_tls_sA in wldap32.dll"),
2102                                                  errdetail("LDAP over SSL is not supported on this platform.")));
2103                                 return STATUS_ERROR;
2104                         }
2105
2106                         /*
2107                          * Leak LDAP handle on purpose, because we need the library to
2108                          * stay open. This is ok because it will only ever be leaked once
2109                          * per process and is automatically cleaned up on process exit.
2110                          */
2111                 }
2112                 if ((r = _ldap_start_tls_sA(ldap, NULL, NULL, NULL, NULL)) != LDAP_SUCCESS)
2113 #endif
2114                 {
2115                         ldap_unbind(ldap);
2116                         ereport(LOG,
2117                          (errmsg("could not start LDAP TLS session: error code %d", r)));
2118                         return STATUS_ERROR;
2119                 }
2120         }
2121
2122         snprintf(fulluser, sizeof(fulluser), "%s%s%s",
2123                          port->hba->ldapprefix ? port->hba->ldapprefix : "",
2124                          port->user_name,
2125                          port->hba->ldapsuffix ? port->hba->ldapsuffix : "");
2126         fulluser[sizeof(fulluser) - 1] = '\0';
2127
2128         r = ldap_simple_bind_s(ldap, fulluser, passwd);
2129         ldap_unbind(ldap);
2130
2131         if (r != LDAP_SUCCESS)
2132         {
2133                 ereport(LOG,
2134                                 (errmsg("LDAP login failed for user \"%s\" on server \"%s\": error code %d",
2135                                                 fulluser, port->hba->ldapserver, r)));
2136                 return STATUS_ERROR;
2137         }
2138
2139         return STATUS_OK;
2140 }
2141 #endif   /* USE_LDAP */
2142
2143
2144 /*----------------------------------------------------------------
2145  * SSL client certificate authentication
2146  *----------------------------------------------------------------
2147  */
2148 #ifdef USE_SSL
2149 static int
2150 CheckCertAuth(Port *port)
2151 {
2152         Assert(port->ssl);
2153
2154         /* Make sure we have received a username in the certificate */
2155         if (port->peer_cn == NULL ||
2156                 strlen(port->peer_cn) <= 0)
2157         {
2158                 ereport(LOG,
2159                                 (errmsg("Certificate login failed for user \"%s\": client certificate contains no username",
2160                                                 port->user_name)));
2161                 return STATUS_ERROR;
2162         }
2163
2164         /* Just pass the certificate CN to the usermap check */
2165         return check_usermap(port->hba->usermap, port->user_name, port->peer_cn, false);
2166 }
2167 #endif