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