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