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