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