]> granicus.if.org Git - postgresql/blob - src/interfaces/libpq/fe-auth.c
Update copyright for 2014
[postgresql] / src / interfaces / libpq / fe-auth.c
1 /*-------------------------------------------------------------------------
2  *
3  * fe-auth.c
4  *         The front-end (client) authorization routines
5  *
6  * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  *        src/interfaces/libpq/fe-auth.c
11  *
12  *-------------------------------------------------------------------------
13  */
14
15 /*
16  * INTERFACE ROUTINES
17  *         frontend (client) routines:
18  *              pg_fe_sendauth                  send authentication information
19  *              pg_fe_getauthname               get user's name according to the client side
20  *                                                              of the authentication system
21  */
22
23 #include "postgres_fe.h"
24
25 #ifdef WIN32
26 #include "win32.h"
27 #else
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <sys/param.h>                  /* for MAXHOSTNAMELEN on most */
31 #include <sys/socket.h>
32 #ifdef HAVE_SYS_UCRED_H
33 #include <sys/ucred.h>
34 #endif
35 #ifndef  MAXHOSTNAMELEN
36 #include <netdb.h>                              /* for MAXHOSTNAMELEN on some */
37 #endif
38 #include <pwd.h>
39 #endif
40
41 #include "libpq-fe.h"
42 #include "fe-auth.h"
43 #include "libpq/md5.h"
44
45
46 #ifdef KRB5
47 /*
48  * MIT Kerberos authentication system - protocol version 5
49  */
50
51 #include <krb5.h>
52 /* Some old versions of Kerberos do not include <com_err.h> in <krb5.h> */
53 #if !defined(__COM_ERR_H) && !defined(__COM_ERR_H__)
54 #include <com_err.h>
55 #endif
56
57 /*
58  * Heimdal doesn't have a free function for unparsed names. Just pass it to
59  * standard free() which should work in these cases.
60  */
61 #ifndef HAVE_KRB5_FREE_UNPARSED_NAME
62 static void
63 krb5_free_unparsed_name(krb5_context context, char *val)
64 {
65         free(val);
66 }
67 #endif
68
69 /*
70  * pg_an_to_ln -- return the local name corresponding to an authentication
71  *                                name
72  *
73  * XXX Assumes that the first aname component is the user name.  This is NOT
74  *         necessarily so, since an aname can actually be something out of your
75  *         worst X.400 nightmare, like
76  *                ORGANIZATION=U. C. Berkeley/NAME=Paul M. Aoki@CS.BERKELEY.EDU
77  *         Note that the MIT an_to_ln code does the same thing if you don't
78  *         provide an aname mapping database...it may be a better idea to use
79  *         krb5_an_to_ln, except that it punts if multiple components are found,
80  *         and we can't afford to punt.
81  *
82  * For WIN32, convert username to lowercase because the Win32 kerberos library
83  * generates tickets with the username as the user entered it instead of as
84  * it is entered in the directory.
85  */
86 static char *
87 pg_an_to_ln(char *aname)
88 {
89         char       *p;
90
91         if ((p = strchr(aname, '/')) || (p = strchr(aname, '@')))
92                 *p = '\0';
93 #ifdef WIN32
94         for (p = aname; *p; p++)
95                 *p = pg_tolower((unsigned char) *p);
96 #endif
97
98         return aname;
99 }
100
101
102 /*
103  * Various krb5 state which is not connection specific, and a flag to
104  * indicate whether we have initialised it yet.
105  */
106 /*
107 static int      pg_krb5_initialised;
108 static krb5_context pg_krb5_context;
109 static krb5_ccache pg_krb5_ccache;
110 static krb5_principal pg_krb5_client;
111 static char *pg_krb5_name;
112 */
113
114 struct krb5_info
115 {
116         int                     pg_krb5_initialised;
117         krb5_context pg_krb5_context;
118         krb5_ccache pg_krb5_ccache;
119         krb5_principal pg_krb5_client;
120         char       *pg_krb5_name;
121 };
122
123
124 static int
125 pg_krb5_init(PQExpBuffer errorMessage, struct krb5_info * info)
126 {
127         krb5_error_code retval;
128
129         if (info->pg_krb5_initialised)
130                 return STATUS_OK;
131
132         retval = krb5_init_context(&(info->pg_krb5_context));
133         if (retval)
134         {
135                 printfPQExpBuffer(errorMessage,
136                                                   "pg_krb5_init: krb5_init_context: %s\n",
137                                                   error_message(retval));
138                 return STATUS_ERROR;
139         }
140
141         retval = krb5_cc_default(info->pg_krb5_context, &(info->pg_krb5_ccache));
142         if (retval)
143         {
144                 printfPQExpBuffer(errorMessage,
145                                                   "pg_krb5_init: krb5_cc_default: %s\n",
146                                                   error_message(retval));
147                 krb5_free_context(info->pg_krb5_context);
148                 return STATUS_ERROR;
149         }
150
151         retval = krb5_cc_get_principal(info->pg_krb5_context, info->pg_krb5_ccache,
152                                                                    &(info->pg_krb5_client));
153         if (retval)
154         {
155                 printfPQExpBuffer(errorMessage,
156                                                   "pg_krb5_init: krb5_cc_get_principal: %s\n",
157                                                   error_message(retval));
158                 krb5_cc_close(info->pg_krb5_context, info->pg_krb5_ccache);
159                 krb5_free_context(info->pg_krb5_context);
160                 return STATUS_ERROR;
161         }
162
163         retval = krb5_unparse_name(info->pg_krb5_context, info->pg_krb5_client, &(info->pg_krb5_name));
164         if (retval)
165         {
166                 printfPQExpBuffer(errorMessage,
167                                                   "pg_krb5_init: krb5_unparse_name: %s\n",
168                                                   error_message(retval));
169                 krb5_free_principal(info->pg_krb5_context, info->pg_krb5_client);
170                 krb5_cc_close(info->pg_krb5_context, info->pg_krb5_ccache);
171                 krb5_free_context(info->pg_krb5_context);
172                 return STATUS_ERROR;
173         }
174
175         info->pg_krb5_name = pg_an_to_ln(info->pg_krb5_name);
176
177         info->pg_krb5_initialised = 1;
178         return STATUS_OK;
179 }
180
181 static void
182 pg_krb5_destroy(struct krb5_info * info)
183 {
184         krb5_free_principal(info->pg_krb5_context, info->pg_krb5_client);
185         krb5_cc_close(info->pg_krb5_context, info->pg_krb5_ccache);
186         krb5_free_unparsed_name(info->pg_krb5_context, info->pg_krb5_name);
187         krb5_free_context(info->pg_krb5_context);
188 }
189
190
191 /*
192  * pg_krb5_sendauth -- client routine to send authentication information to
193  *                                         the server
194  */
195 static int
196 pg_krb5_sendauth(PGconn *conn)
197 {
198         krb5_error_code retval;
199         int                     ret;
200         krb5_principal server;
201         krb5_auth_context auth_context = NULL;
202         krb5_error *err_ret = NULL;
203         struct krb5_info info;
204
205         info.pg_krb5_initialised = 0;
206
207         if (!(conn->pghost && conn->pghost[0] != '\0'))
208         {
209                 printfPQExpBuffer(&conn->errorMessage,
210                                                   libpq_gettext("host name must be specified\n"));
211                 return STATUS_ERROR;
212         }
213
214         ret = pg_krb5_init(&conn->errorMessage, &info);
215         if (ret != STATUS_OK)
216                 return ret;
217
218         retval = krb5_sname_to_principal(info.pg_krb5_context, conn->pghost,
219                                                                          conn->krbsrvname,
220                                                                          KRB5_NT_SRV_HST, &server);
221         if (retval)
222         {
223                 printfPQExpBuffer(&conn->errorMessage,
224                                                   "pg_krb5_sendauth: krb5_sname_to_principal: %s\n",
225                                                   error_message(retval));
226                 pg_krb5_destroy(&info);
227                 return STATUS_ERROR;
228         }
229
230         /*
231          * libpq uses a non-blocking socket. But kerberos needs a blocking socket,
232          * and we have to block somehow to do mutual authentication anyway. So we
233          * temporarily make it blocking.
234          */
235         if (!pg_set_block(conn->sock))
236         {
237                 char            sebuf[256];
238
239                 printfPQExpBuffer(&conn->errorMessage,
240                                                   libpq_gettext("could not set socket to blocking mode: %s\n"), pqStrerror(errno, sebuf, sizeof(sebuf)));
241                 krb5_free_principal(info.pg_krb5_context, server);
242                 pg_krb5_destroy(&info);
243                 return STATUS_ERROR;
244         }
245
246         retval = krb5_sendauth(info.pg_krb5_context, &auth_context,
247                                           (krb5_pointer) & conn->sock, (char *) conn->krbsrvname,
248                                                    info.pg_krb5_client, server,
249                                                    AP_OPTS_MUTUAL_REQUIRED,
250                                                    NULL, 0,             /* no creds, use ccache instead */
251                                                    info.pg_krb5_ccache, &err_ret, NULL, NULL);
252         if (retval)
253         {
254                 if (retval == KRB5_SENDAUTH_REJECTED && err_ret)
255                 {
256 #if defined(HAVE_KRB5_ERROR_TEXT_DATA)
257                         printfPQExpBuffer(&conn->errorMessage,
258                                   libpq_gettext("Kerberos 5 authentication rejected: %*s\n"),
259                                                           (int) err_ret->text.length, err_ret->text.data);
260 #elif defined(HAVE_KRB5_ERROR_E_DATA)
261                         printfPQExpBuffer(&conn->errorMessage,
262                                   libpq_gettext("Kerberos 5 authentication rejected: %*s\n"),
263                                                           (int) err_ret->e_data->length,
264                                                           (const char *) err_ret->e_data->data);
265 #else
266 #error "bogus configuration"
267 #endif
268                 }
269                 else
270                 {
271                         printfPQExpBuffer(&conn->errorMessage,
272                                                           "krb5_sendauth: %s\n", error_message(retval));
273                 }
274
275                 if (err_ret)
276                         krb5_free_error(info.pg_krb5_context, err_ret);
277
278                 ret = STATUS_ERROR;
279         }
280
281         krb5_free_principal(info.pg_krb5_context, server);
282
283         if (!pg_set_noblock(conn->sock))
284         {
285                 char            sebuf[256];
286
287                 printfPQExpBuffer(&conn->errorMessage,
288                  libpq_gettext("could not restore nonblocking mode on socket: %s\n"),
289                                                   pqStrerror(errno, sebuf, sizeof(sebuf)));
290                 ret = STATUS_ERROR;
291         }
292         pg_krb5_destroy(&info);
293
294         return ret;
295 }
296 #endif   /* KRB5 */
297
298 #ifdef ENABLE_GSS
299 /*
300  * GSSAPI authentication system.
301  */
302
303 #if defined(WIN32) && !defined(WIN32_ONLY_COMPILER)
304 /*
305  * MIT Kerberos GSSAPI DLL doesn't properly export the symbols for MingW
306  * that contain the OIDs required. Redefine here, values copied
307  * from src/athena/auth/krb5/src/lib/gssapi/generic/gssapi_generic.c
308  */
309 static const gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_desc =
310 {10, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"};
311 static GSS_DLLIMP gss_OID GSS_C_NT_HOSTBASED_SERVICE = &GSS_C_NT_HOSTBASED_SERVICE_desc;
312 #endif
313
314 /*
315  * Fetch all errors of a specific type and append to "str".
316  */
317 static void
318 pg_GSS_error_int(PQExpBuffer str, const char *mprefix,
319                                  OM_uint32 stat, int type)
320 {
321         OM_uint32       lmin_s;
322         gss_buffer_desc lmsg;
323         OM_uint32       msg_ctx = 0;
324
325         do
326         {
327                 gss_display_status(&lmin_s, stat, type,
328                                                    GSS_C_NO_OID, &msg_ctx, &lmsg);
329                 appendPQExpBuffer(str, "%s: %s\n", mprefix, (char *) lmsg.value);
330                 gss_release_buffer(&lmin_s, &lmsg);
331         } while (msg_ctx);
332 }
333
334 /*
335  * GSSAPI errors contain two parts; put both into conn->errorMessage.
336  */
337 static void
338 pg_GSS_error(const char *mprefix, PGconn *conn,
339                          OM_uint32 maj_stat, OM_uint32 min_stat)
340 {
341         resetPQExpBuffer(&conn->errorMessage);
342
343         /* Fetch major error codes */
344         pg_GSS_error_int(&conn->errorMessage, mprefix, maj_stat, GSS_C_GSS_CODE);
345
346         /* Add the minor codes as well */
347         pg_GSS_error_int(&conn->errorMessage, mprefix, min_stat, GSS_C_MECH_CODE);
348 }
349
350 /*
351  * Continue GSS authentication with next token as needed.
352  */
353 static int
354 pg_GSS_continue(PGconn *conn)
355 {
356         OM_uint32       maj_stat,
357                                 min_stat,
358                                 lmin_s;
359
360         maj_stat = gss_init_sec_context(&min_stat,
361                                                                         GSS_C_NO_CREDENTIAL,
362                                                                         &conn->gctx,
363                                                                         conn->gtarg_nam,
364                                                                         GSS_C_NO_OID,
365                                                                         GSS_C_MUTUAL_FLAG,
366                                                                         0,
367                                                                         GSS_C_NO_CHANNEL_BINDINGS,
368                   (conn->gctx == GSS_C_NO_CONTEXT) ? GSS_C_NO_BUFFER : &conn->ginbuf,
369                                                                         NULL,
370                                                                         &conn->goutbuf,
371                                                                         NULL,
372                                                                         NULL);
373
374         if (conn->gctx != GSS_C_NO_CONTEXT)
375         {
376                 free(conn->ginbuf.value);
377                 conn->ginbuf.value = NULL;
378                 conn->ginbuf.length = 0;
379         }
380
381         if (conn->goutbuf.length != 0)
382         {
383                 /*
384                  * GSS generated data to send to the server. We don't care if it's the
385                  * first or subsequent packet, just send the same kind of password
386                  * packet.
387                  */
388                 if (pqPacketSend(conn, 'p',
389                                                  conn->goutbuf.value, conn->goutbuf.length)
390                         != STATUS_OK)
391                 {
392                         gss_release_buffer(&lmin_s, &conn->goutbuf);
393                         return STATUS_ERROR;
394                 }
395         }
396         gss_release_buffer(&lmin_s, &conn->goutbuf);
397
398         if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
399         {
400                 pg_GSS_error(libpq_gettext("GSSAPI continuation error"),
401                                          conn,
402                                          maj_stat, min_stat);
403                 gss_release_name(&lmin_s, &conn->gtarg_nam);
404                 if (conn->gctx)
405                         gss_delete_sec_context(&lmin_s, &conn->gctx, GSS_C_NO_BUFFER);
406                 return STATUS_ERROR;
407         }
408
409         if (maj_stat == GSS_S_COMPLETE)
410                 gss_release_name(&lmin_s, &conn->gtarg_nam);
411
412         return STATUS_OK;
413 }
414
415 /*
416  * Send initial GSS authentication token
417  */
418 static int
419 pg_GSS_startup(PGconn *conn)
420 {
421         OM_uint32       maj_stat,
422                                 min_stat;
423         int                     maxlen;
424         gss_buffer_desc temp_gbuf;
425
426         if (!(conn->pghost && conn->pghost[0] != '\0'))
427         {
428                 printfPQExpBuffer(&conn->errorMessage,
429                                                   libpq_gettext("host name must be specified\n"));
430                 return STATUS_ERROR;
431         }
432
433         if (conn->gctx)
434         {
435                 printfPQExpBuffer(&conn->errorMessage,
436                                         libpq_gettext("duplicate GSS authentication request\n"));
437                 return STATUS_ERROR;
438         }
439
440         /*
441          * Import service principal name so the proper ticket can be acquired by
442          * the GSSAPI system.
443          */
444         maxlen = NI_MAXHOST + strlen(conn->krbsrvname) + 2;
445         temp_gbuf.value = (char *) malloc(maxlen);
446         if (!temp_gbuf.value)
447         {
448                 printfPQExpBuffer(&conn->errorMessage,
449                                                   libpq_gettext("out of memory\n"));
450                 return STATUS_ERROR;
451         }
452         snprintf(temp_gbuf.value, maxlen, "%s@%s",
453                          conn->krbsrvname, conn->pghost);
454         temp_gbuf.length = strlen(temp_gbuf.value);
455
456         maj_stat = gss_import_name(&min_stat, &temp_gbuf,
457                                                            GSS_C_NT_HOSTBASED_SERVICE, &conn->gtarg_nam);
458         free(temp_gbuf.value);
459
460         if (maj_stat != GSS_S_COMPLETE)
461         {
462                 pg_GSS_error(libpq_gettext("GSSAPI name import error"),
463                                          conn,
464                                          maj_stat, min_stat);
465                 return STATUS_ERROR;
466         }
467
468         /*
469          * Initial packet is the same as a continuation packet with no initial
470          * context.
471          */
472         conn->gctx = GSS_C_NO_CONTEXT;
473
474         return pg_GSS_continue(conn);
475 }
476 #endif   /* ENABLE_GSS */
477
478
479 #ifdef ENABLE_SSPI
480 /*
481  * SSPI authentication system (Windows only)
482  */
483
484 static void
485 pg_SSPI_error(PGconn *conn, const char *mprefix, SECURITY_STATUS r)
486 {
487         char            sysmsg[256];
488
489         if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, r, 0,
490                                           sysmsg, sizeof(sysmsg), NULL) == 0)
491                 printfPQExpBuffer(&conn->errorMessage, "%s: SSPI error %x",
492                                                   mprefix, (unsigned int) r);
493         else
494                 printfPQExpBuffer(&conn->errorMessage, "%s: %s (%x)",
495                                                   mprefix, sysmsg, (unsigned int) r);
496 }
497
498 /*
499  * Continue SSPI authentication with next token as needed.
500  */
501 static int
502 pg_SSPI_continue(PGconn *conn)
503 {
504         SECURITY_STATUS r;
505         CtxtHandle      newContext;
506         ULONG           contextAttr;
507         SecBufferDesc inbuf;
508         SecBufferDesc outbuf;
509         SecBuffer       OutBuffers[1];
510         SecBuffer       InBuffers[1];
511
512         if (conn->sspictx != NULL)
513         {
514                 /*
515                  * On runs other than the first we have some data to send. Put this
516                  * data in a SecBuffer type structure.
517                  */
518                 inbuf.ulVersion = SECBUFFER_VERSION;
519                 inbuf.cBuffers = 1;
520                 inbuf.pBuffers = InBuffers;
521                 InBuffers[0].pvBuffer = conn->ginbuf.value;
522                 InBuffers[0].cbBuffer = conn->ginbuf.length;
523                 InBuffers[0].BufferType = SECBUFFER_TOKEN;
524         }
525
526         OutBuffers[0].pvBuffer = NULL;
527         OutBuffers[0].BufferType = SECBUFFER_TOKEN;
528         OutBuffers[0].cbBuffer = 0;
529         outbuf.cBuffers = 1;
530         outbuf.pBuffers = OutBuffers;
531         outbuf.ulVersion = SECBUFFER_VERSION;
532
533         r = InitializeSecurityContext(conn->sspicred,
534                                                                   conn->sspictx,
535                                                                   conn->sspitarget,
536                                                                   ISC_REQ_ALLOCATE_MEMORY,
537                                                                   0,
538                                                                   SECURITY_NETWORK_DREP,
539                                                                   (conn->sspictx == NULL) ? NULL : &inbuf,
540                                                                   0,
541                                                                   &newContext,
542                                                                   &outbuf,
543                                                                   &contextAttr,
544                                                                   NULL);
545
546         if (r != SEC_E_OK && r != SEC_I_CONTINUE_NEEDED)
547         {
548                 pg_SSPI_error(conn, libpq_gettext("SSPI continuation error"), r);
549
550                 return STATUS_ERROR;
551         }
552
553         if (conn->sspictx == NULL)
554         {
555                 /* On first run, transfer retreived context handle */
556                 conn->sspictx = malloc(sizeof(CtxtHandle));
557                 if (conn->sspictx == NULL)
558                 {
559                         printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
560                         return STATUS_ERROR;
561                 }
562                 memcpy(conn->sspictx, &newContext, sizeof(CtxtHandle));
563         }
564         else
565         {
566                 /*
567                  * On subsequent runs when we had data to send, free buffers that
568                  * contained this data.
569                  */
570                 free(conn->ginbuf.value);
571                 conn->ginbuf.value = NULL;
572                 conn->ginbuf.length = 0;
573         }
574
575         /*
576          * If SSPI returned any data to be sent to the server (as it normally
577          * would), send this data as a password packet.
578          */
579         if (outbuf.cBuffers > 0)
580         {
581                 if (outbuf.cBuffers != 1)
582                 {
583                         /*
584                          * This should never happen, at least not for Kerberos
585                          * authentication. Keep check in case it shows up with other
586                          * authentication methods later.
587                          */
588                         printfPQExpBuffer(&conn->errorMessage, "SSPI returned invalid number of output buffers\n");
589                         return STATUS_ERROR;
590                 }
591
592                 /*
593                  * If the negotiation is complete, there may be zero bytes to send.
594                  * The server is at this point not expecting any more data, so don't
595                  * send it.
596                  */
597                 if (outbuf.pBuffers[0].cbBuffer > 0)
598                 {
599                         if (pqPacketSend(conn, 'p',
600                                    outbuf.pBuffers[0].pvBuffer, outbuf.pBuffers[0].cbBuffer))
601                         {
602                                 FreeContextBuffer(outbuf.pBuffers[0].pvBuffer);
603                                 return STATUS_ERROR;
604                         }
605                 }
606                 FreeContextBuffer(outbuf.pBuffers[0].pvBuffer);
607         }
608
609         /* Cleanup is handled by the code in freePGconn() */
610         return STATUS_OK;
611 }
612
613 /*
614  * Send initial SSPI authentication token.
615  * If use_negotiate is 0, use kerberos authentication package which is
616  * compatible with Unix. If use_negotiate is 1, use the negotiate package
617  * which supports both kerberos and NTLM, but is not compatible with Unix.
618  */
619 static int
620 pg_SSPI_startup(PGconn *conn, int use_negotiate)
621 {
622         SECURITY_STATUS r;
623         TimeStamp       expire;
624
625         conn->sspictx = NULL;
626
627         /*
628          * Retreive credentials handle
629          */
630         conn->sspicred = malloc(sizeof(CredHandle));
631         if (conn->sspicred == NULL)
632         {
633                 printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
634                 return STATUS_ERROR;
635         }
636
637         r = AcquireCredentialsHandle(NULL,
638                                                                  use_negotiate ? "negotiate" : "kerberos",
639                                                                  SECPKG_CRED_OUTBOUND,
640                                                                  NULL,
641                                                                  NULL,
642                                                                  NULL,
643                                                                  NULL,
644                                                                  conn->sspicred,
645                                                                  &expire);
646         if (r != SEC_E_OK)
647         {
648                 pg_SSPI_error(conn, libpq_gettext("could not acquire SSPI credentials"), r);
649                 free(conn->sspicred);
650                 conn->sspicred = NULL;
651                 return STATUS_ERROR;
652         }
653
654         /*
655          * Compute target principal name. SSPI has a different format from GSSAPI,
656          * but not more complex. We can skip the @REALM part, because Windows will
657          * fill that in for us automatically.
658          */
659         if (!(conn->pghost && conn->pghost[0] != '\0'))
660         {
661                 printfPQExpBuffer(&conn->errorMessage,
662                                                   libpq_gettext("host name must be specified\n"));
663                 return STATUS_ERROR;
664         }
665         conn->sspitarget = malloc(strlen(conn->krbsrvname) + strlen(conn->pghost) + 2);
666         if (!conn->sspitarget)
667         {
668                 printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
669                 return STATUS_ERROR;
670         }
671         sprintf(conn->sspitarget, "%s/%s", conn->krbsrvname, conn->pghost);
672
673         /*
674          * Indicate that we're in SSPI authentication mode to make sure that
675          * pg_SSPI_continue is called next time in the negotiation.
676          */
677         conn->usesspi = 1;
678
679         return pg_SSPI_continue(conn);
680 }
681 #endif   /* ENABLE_SSPI */
682
683 /*
684  * Respond to AUTH_REQ_SCM_CREDS challenge.
685  *
686  * Note: this is dead code as of Postgres 9.1, because current backends will
687  * never send this challenge.  But we must keep it as long as libpq needs to
688  * interoperate with pre-9.1 servers.  It is believed to be needed only on
689  * Debian/kFreeBSD (ie, FreeBSD kernel with Linux userland, so that the
690  * getpeereid() function isn't provided by libc).
691  */
692 static int
693 pg_local_sendauth(PGconn *conn)
694 {
695 #ifdef HAVE_STRUCT_CMSGCRED
696         char            buf;
697         struct iovec iov;
698         struct msghdr msg;
699         struct cmsghdr *cmsg;
700         union
701         {
702                 struct cmsghdr hdr;
703                 unsigned char buf[CMSG_SPACE(sizeof(struct cmsgcred))];
704         }                       cmsgbuf;
705
706         /*
707          * The backend doesn't care what we send here, but it wants exactly one
708          * character to force recvmsg() to block and wait for us.
709          */
710         buf = '\0';
711         iov.iov_base = &buf;
712         iov.iov_len = 1;
713
714         memset(&msg, 0, sizeof(msg));
715         msg.msg_iov = &iov;
716         msg.msg_iovlen = 1;
717
718         /* We must set up a message that will be filled in by kernel */
719         memset(&cmsgbuf, 0, sizeof(cmsgbuf));
720         msg.msg_control = &cmsgbuf.buf;
721         msg.msg_controllen = sizeof(cmsgbuf.buf);
722         cmsg = CMSG_FIRSTHDR(&msg);
723         cmsg->cmsg_len = CMSG_LEN(sizeof(struct cmsgcred));
724         cmsg->cmsg_level = SOL_SOCKET;
725         cmsg->cmsg_type = SCM_CREDS;
726
727         if (sendmsg(conn->sock, &msg, 0) == -1)
728         {
729                 char            sebuf[256];
730
731                 printfPQExpBuffer(&conn->errorMessage,
732                                                   "pg_local_sendauth: sendmsg: %s\n",
733                                                   pqStrerror(errno, sebuf, sizeof(sebuf)));
734                 return STATUS_ERROR;
735         }
736         return STATUS_OK;
737 #else
738         printfPQExpBuffer(&conn->errorMessage,
739                         libpq_gettext("SCM_CRED authentication method not supported\n"));
740         return STATUS_ERROR;
741 #endif
742 }
743
744 static int
745 pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
746 {
747         int                     ret;
748         char       *crypt_pwd = NULL;
749         const char *pwd_to_send;
750
751         /* Encrypt the password if needed. */
752
753         switch (areq)
754         {
755                 case AUTH_REQ_MD5:
756                         {
757                                 char       *crypt_pwd2;
758
759                                 /* Allocate enough space for two MD5 hashes */
760                                 crypt_pwd = malloc(2 * (MD5_PASSWD_LEN + 1));
761                                 if (!crypt_pwd)
762                                 {
763                                         printfPQExpBuffer(&conn->errorMessage,
764                                                                           libpq_gettext("out of memory\n"));
765                                         return STATUS_ERROR;
766                                 }
767
768                                 crypt_pwd2 = crypt_pwd + MD5_PASSWD_LEN + 1;
769                                 if (!pg_md5_encrypt(password, conn->pguser,
770                                                                         strlen(conn->pguser), crypt_pwd2))
771                                 {
772                                         free(crypt_pwd);
773                                         return STATUS_ERROR;
774                                 }
775                                 if (!pg_md5_encrypt(crypt_pwd2 + strlen("md5"), conn->md5Salt,
776                                                                         sizeof(conn->md5Salt), crypt_pwd))
777                                 {
778                                         free(crypt_pwd);
779                                         return STATUS_ERROR;
780                                 }
781
782                                 pwd_to_send = crypt_pwd;
783                                 break;
784                         }
785                 case AUTH_REQ_PASSWORD:
786                         pwd_to_send = password;
787                         break;
788                 default:
789                         return STATUS_ERROR;
790         }
791         /* Packet has a message type as of protocol 3.0 */
792         if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
793                 ret = pqPacketSend(conn, 'p', pwd_to_send, strlen(pwd_to_send) + 1);
794         else
795                 ret = pqPacketSend(conn, 0, pwd_to_send, strlen(pwd_to_send) + 1);
796         if (crypt_pwd)
797                 free(crypt_pwd);
798         return ret;
799 }
800
801 /*
802  * pg_fe_sendauth
803  *              client demux routine for outgoing authentication information
804  */
805 int
806 pg_fe_sendauth(AuthRequest areq, PGconn *conn)
807 {
808         switch (areq)
809         {
810                 case AUTH_REQ_OK:
811                         break;
812
813                 case AUTH_REQ_KRB4:
814                         printfPQExpBuffer(&conn->errorMessage,
815                                  libpq_gettext("Kerberos 4 authentication not supported\n"));
816                         return STATUS_ERROR;
817
818                 case AUTH_REQ_KRB5:
819 #ifdef KRB5
820                         pglock_thread();
821                         if (pg_krb5_sendauth(conn) != STATUS_OK)
822                         {
823                                 /* Error message already filled in */
824                                 pgunlock_thread();
825                                 return STATUS_ERROR;
826                         }
827                         pgunlock_thread();
828                         break;
829 #else
830                         printfPQExpBuffer(&conn->errorMessage,
831                                  libpq_gettext("Kerberos 5 authentication not supported\n"));
832                         return STATUS_ERROR;
833 #endif
834
835 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
836                 case AUTH_REQ_GSS:
837 #if !defined(ENABLE_SSPI)
838                         /* no native SSPI, so use GSSAPI library for it */
839                 case AUTH_REQ_SSPI:
840 #endif
841                         {
842                                 int                     r;
843
844                                 pglock_thread();
845
846                                 /*
847                                  * If we have both GSS and SSPI support compiled in, use SSPI
848                                  * support by default. This is overridable by a connection
849                                  * string parameter. Note that when using SSPI we still leave
850                                  * the negotiate parameter off, since we want SSPI to use the
851                                  * GSSAPI kerberos protocol. For actual SSPI negotiate
852                                  * protocol, we use AUTH_REQ_SSPI.
853                                  */
854 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
855                                 if (conn->gsslib && (pg_strcasecmp(conn->gsslib, "gssapi") == 0))
856                                         r = pg_GSS_startup(conn);
857                                 else
858                                         r = pg_SSPI_startup(conn, 0);
859 #elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
860                                 r = pg_GSS_startup(conn);
861 #elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
862                                 r = pg_SSPI_startup(conn, 0);
863 #endif
864                                 if (r != STATUS_OK)
865                                 {
866                                         /* Error message already filled in. */
867                                         pgunlock_thread();
868                                         return STATUS_ERROR;
869                                 }
870                                 pgunlock_thread();
871                         }
872                         break;
873
874                 case AUTH_REQ_GSS_CONT:
875                         {
876                                 int                     r;
877
878                                 pglock_thread();
879 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
880                                 if (conn->usesspi)
881                                         r = pg_SSPI_continue(conn);
882                                 else
883                                         r = pg_GSS_continue(conn);
884 #elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
885                                 r = pg_GSS_continue(conn);
886 #elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
887                                 r = pg_SSPI_continue(conn);
888 #endif
889                                 if (r != STATUS_OK)
890                                 {
891                                         /* Error message already filled in. */
892                                         pgunlock_thread();
893                                         return STATUS_ERROR;
894                                 }
895                                 pgunlock_thread();
896                         }
897                         break;
898 #else                                                   /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
899                         /* No GSSAPI *or* SSPI support */
900                 case AUTH_REQ_GSS:
901                 case AUTH_REQ_GSS_CONT:
902                         printfPQExpBuffer(&conn->errorMessage,
903                                          libpq_gettext("GSSAPI authentication not supported\n"));
904                         return STATUS_ERROR;
905 #endif   /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
906
907 #ifdef ENABLE_SSPI
908                 case AUTH_REQ_SSPI:
909
910                         /*
911                          * SSPI has it's own startup message so libpq can decide which
912                          * method to use. Indicate to pg_SSPI_startup that we want SSPI
913                          * negotiation instead of Kerberos.
914                          */
915                         pglock_thread();
916                         if (pg_SSPI_startup(conn, 1) != STATUS_OK)
917                         {
918                                 /* Error message already filled in. */
919                                 pgunlock_thread();
920                                 return STATUS_ERROR;
921                         }
922                         pgunlock_thread();
923                         break;
924 #else
925
926                         /*
927                          * No SSPI support. However, if we have GSSAPI but not SSPI
928                          * support, AUTH_REQ_SSPI will have been handled in the codepath
929                          * for AUTH_REQ_GSSAPI above, so don't duplicate the case label in
930                          * that case.
931                          */
932 #if !defined(ENABLE_GSS)
933                 case AUTH_REQ_SSPI:
934                         printfPQExpBuffer(&conn->errorMessage,
935                                            libpq_gettext("SSPI authentication not supported\n"));
936                         return STATUS_ERROR;
937 #endif   /* !define(ENABLE_GSSAPI) */
938 #endif   /* ENABLE_SSPI */
939
940
941                 case AUTH_REQ_CRYPT:
942                         printfPQExpBuffer(&conn->errorMessage,
943                                           libpq_gettext("Crypt authentication not supported\n"));
944                         return STATUS_ERROR;
945
946                 case AUTH_REQ_MD5:
947                 case AUTH_REQ_PASSWORD:
948                         conn->password_needed = true;
949                         if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
950                         {
951                                 printfPQExpBuffer(&conn->errorMessage,
952                                                                   PQnoPasswordSupplied);
953                                 return STATUS_ERROR;
954                         }
955                         if (pg_password_sendauth(conn, conn->pgpass, areq) != STATUS_OK)
956                         {
957                                 printfPQExpBuffer(&conn->errorMessage,
958                                          "fe_sendauth: error sending password authentication\n");
959                                 return STATUS_ERROR;
960                         }
961                         break;
962
963                 case AUTH_REQ_SCM_CREDS:
964                         if (pg_local_sendauth(conn) != STATUS_OK)
965                                 return STATUS_ERROR;
966                         break;
967
968                 default:
969                         printfPQExpBuffer(&conn->errorMessage,
970                         libpq_gettext("authentication method %u not supported\n"), areq);
971                         return STATUS_ERROR;
972         }
973
974         return STATUS_OK;
975 }
976
977
978 /*
979  * pg_fe_getauthname
980  *
981  * Returns a pointer to dynamic space containing whatever name the user
982  * has authenticated to the system.  If there is an error, return NULL.
983  */
984 char *
985 pg_fe_getauthname(void)
986 {
987         const char *name = NULL;
988         char       *authn;
989
990 #ifdef WIN32
991         char            username[128];
992         DWORD           namesize = sizeof(username) - 1;
993 #else
994         char            pwdbuf[BUFSIZ];
995         struct passwd pwdstr;
996         struct passwd *pw = NULL;
997 #endif
998
999         /*
1000          * Some users are using configure --enable-thread-safety-force, so we
1001          * might as well do the locking within our library to protect
1002          * pqGetpwuid(). In fact, application developers can use getpwuid() in
1003          * their application if they use the locking call we provide, or install
1004          * their own locking function using PQregisterThreadLock().
1005          */
1006         pglock_thread();
1007
1008         if (!name)
1009         {
1010 #ifdef WIN32
1011                 if (GetUserName(username, &namesize))
1012                         name = username;
1013 #else
1014                 if (pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pw) == 0)
1015                         name = pw->pw_name;
1016 #endif
1017         }
1018
1019         authn = name ? strdup(name) : NULL;
1020
1021         pgunlock_thread();
1022
1023         return authn;
1024 }
1025
1026
1027 /*
1028  * PQencryptPassword -- exported routine to encrypt a password
1029  *
1030  * This is intended to be used by client applications that wish to send
1031  * commands like ALTER USER joe PASSWORD 'pwd'.  The password need not
1032  * be sent in cleartext if it is encrypted on the client side.  This is
1033  * good because it ensures the cleartext password won't end up in logs,
1034  * pg_stat displays, etc.  We export the function so that clients won't
1035  * be dependent on low-level details like whether the enceyption is MD5
1036  * or something else.
1037  *
1038  * Arguments are the cleartext password, and the SQL name of the user it
1039  * is for.
1040  *
1041  * Return value is a malloc'd string, or NULL if out-of-memory.  The client
1042  * may assume the string doesn't contain any special characters that would
1043  * require escaping.
1044  */
1045 char *
1046 PQencryptPassword(const char *passwd, const char *user)
1047 {
1048         char       *crypt_pwd;
1049
1050         crypt_pwd = malloc(MD5_PASSWD_LEN + 1);
1051         if (!crypt_pwd)
1052                 return NULL;
1053
1054         if (!pg_md5_encrypt(passwd, user, strlen(user), crypt_pwd))
1055         {
1056                 free(crypt_pwd);
1057                 return NULL;
1058         }
1059
1060         return crypt_pwd;
1061 }