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