1 /*-------------------------------------------------------------------------
4 * Routines to handle network authentication
6 * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/libpq/auth.c
13 *-------------------------------------------------------------------------
18 #include <sys/param.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
24 #include "libpq/auth.h"
25 #include "libpq/crypt.h"
27 #include "libpq/libpq.h"
28 #include "libpq/pqformat.h"
29 #include "libpq/md5.h"
30 #include "miscadmin.h"
31 #include "replication/walsender.h"
32 #include "storage/ipc.h"
35 /*----------------------------------------------------------------
36 * Global authentication functions
37 *----------------------------------------------------------------
39 static void sendAuthRequest(Port *port, AuthRequest areq);
40 static void auth_failed(Port *port, int status, char *logdetail);
41 static char *recv_password_packet(Port *port);
42 static int recv_and_check_password_packet(Port *port, char **logdetail);
45 /*----------------------------------------------------------------
46 * Ident authentication
47 *----------------------------------------------------------------
49 /* Max size of username ident server can return */
50 #define IDENT_USERNAME_MAX 512
52 /* Standard TCP port number for Ident service. Assigned by IANA */
53 #define IDENT_PORT 113
55 static int ident_inet(hbaPort *port);
57 #ifdef HAVE_UNIX_SOCKETS
58 static int auth_peer(hbaPort *port);
62 /*----------------------------------------------------------------
64 *----------------------------------------------------------------
67 #ifdef HAVE_PAM_PAM_APPL_H
68 #include <pam/pam_appl.h>
70 #ifdef HAVE_SECURITY_PAM_APPL_H
71 #include <security/pam_appl.h>
74 #define PGSQL_PAM_SERVICE "postgresql" /* Service name passed to PAM */
76 static int CheckPAMAuth(Port *port, char *user, char *password);
77 static int pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg,
78 struct pam_response ** resp, void *appdata_ptr);
80 static struct pam_conv pam_passw_conv = {
81 &pam_passwd_conv_proc,
85 static char *pam_passwd = NULL; /* Workaround for Solaris 2.6 brokenness */
86 static Port *pam_port_cludge; /* Workaround for passing "Port *port" into
87 * pam_passwd_conv_proc */
91 /*----------------------------------------------------------------
93 *----------------------------------------------------------------
97 /* We use a deprecated function to keep the codepath the same as win32. */
98 #define LDAP_DEPRECATED 1
103 /* Correct header from the Platform SDK */
105 ULONG (*__ldap_start_tls_sA) (
106 IN PLDAP ExternalHandle,
107 OUT PULONG ServerReturnValue,
108 OUT LDAPMessage **result,
109 IN PLDAPControlA * ServerControls,
110 IN PLDAPControlA * ClientControls
114 static int CheckLDAPAuth(Port *port);
115 #endif /* USE_LDAP */
117 /*----------------------------------------------------------------
118 * Cert authentication
119 *----------------------------------------------------------------
122 static int CheckCertAuth(Port *port);
126 /*----------------------------------------------------------------
127 * Kerberos and GSSAPI GUCs
128 *----------------------------------------------------------------
130 char *pg_krb_server_keyfile;
131 bool pg_krb_caseins_users;
134 /*----------------------------------------------------------------
135 * GSSAPI Authentication
136 *----------------------------------------------------------------
139 #if defined(HAVE_GSSAPI_H)
142 #include <gssapi/gssapi.h>
145 static int pg_GSS_recvauth(Port *port);
146 #endif /* ENABLE_GSS */
149 /*----------------------------------------------------------------
150 * SSPI Authentication
151 *----------------------------------------------------------------
154 typedef SECURITY_STATUS
155 (WINAPI * QUERY_SECURITY_CONTEXT_TOKEN_FN) (
156 PCtxtHandle, void **);
157 static int pg_SSPI_recvauth(Port *port);
160 /*----------------------------------------------------------------
161 * RADIUS Authentication
162 *----------------------------------------------------------------
165 #include <openssl/rand.h>
167 static int CheckRADIUSAuth(Port *port);
171 * Maximum accepted size of GSS and SSPI authentication tokens.
173 * Kerberos tickets are usually quite small, but the TGTs issued by Windows
174 * domain controllers include an authorization field known as the Privilege
175 * Attribute Certificate (PAC), which contains the user's Windows permissions
176 * (group memberships etc.). The PAC is copied into all tickets obtained on
177 * the basis of this TGT (even those issued by Unix realms which the Windows
178 * realm trusts), and can be several kB in size. The maximum token size
179 * accepted by Windows systems is determined by the MaxAuthToken Windows
180 * registry setting. Microsoft recommends that it is not set higher than
181 * 65535 bytes, so that seems like a reasonable limit for us as well.
183 #define PG_MAX_AUTH_TOKEN_LENGTH 65535
186 /*----------------------------------------------------------------
187 * Global authentication functions
188 *----------------------------------------------------------------
192 * This hook allows plugins to get control following client authentication,
193 * but before the user has been informed about the results. It could be used
194 * to record login events, insert a delay after failed authentication, etc.
196 ClientAuthentication_hook_type ClientAuthentication_hook = NULL;
199 * Tell the user the authentication failed, but not (much about) why.
201 * There is a tradeoff here between security concerns and making life
202 * unnecessarily difficult for legitimate users. We would not, for example,
203 * want to report the password we were expecting to receive...
204 * But it seems useful to report the username and authorization method
205 * in use, and these are items that must be presumed known to an attacker
207 * Note that many sorts of failure report additional information in the
208 * postmaster log, which we hope is only readable by good guys. In
209 * particular, if logdetail isn't NULL, we send that string to the log.
212 auth_failed(Port *port, int status, char *logdetail)
216 int errcode_return = ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION;
219 * If we failed due to EOF from client, just quit; there's no point in
220 * trying to send a message to the client, and not much point in logging
221 * the failure in the postmaster log. (Logging the failure might be
222 * desirable, were it not for the fact that libpq closes the connection
223 * unceremoniously if challenged for a password when it hasn't got one to
224 * send. We'll get a useless log entry for every psql connection under
225 * password auth, even if it's perfectly successful, if we log STATUS_EOF
228 if (status == STATUS_EOF)
231 switch (port->hba->auth_method)
234 case uaImplicitReject:
235 errstr = gettext_noop("authentication failed for user \"%s\": host rejected");
238 errstr = gettext_noop("\"trust\" authentication failed for user \"%s\"");
241 errstr = gettext_noop("Ident authentication failed for user \"%s\"");
244 errstr = gettext_noop("Peer authentication failed for user \"%s\"");
248 errstr = gettext_noop("password authentication failed for user \"%s\"");
249 /* We use it to indicate if a .pgpass password failed. */
250 errcode_return = ERRCODE_INVALID_PASSWORD;
253 errstr = gettext_noop("GSSAPI authentication failed for user \"%s\"");
256 errstr = gettext_noop("SSPI authentication failed for user \"%s\"");
259 errstr = gettext_noop("PAM authentication failed for user \"%s\"");
262 errstr = gettext_noop("LDAP authentication failed for user \"%s\"");
265 errstr = gettext_noop("certificate authentication failed for user \"%s\"");
268 errstr = gettext_noop("RADIUS authentication failed for user \"%s\"");
271 errstr = gettext_noop("authentication failed for user \"%s\": invalid authentication method");
275 cdetail = psprintf(_("Connection matched pg_hba.conf line %d: \"%s\""),
276 port->hba->linenumber, port->hba->rawline);
278 logdetail = psprintf("%s\n%s", logdetail, cdetail);
283 (errcode(errcode_return),
284 errmsg(errstr, port->user_name),
285 logdetail ? errdetail_log("%s", logdetail) : 0));
292 * Client authentication starts here. If there is an error, this
293 * function does not return and the backend process is terminated.
296 ClientAuthentication(Port *port)
298 int status = STATUS_ERROR;
299 char *logdetail = NULL;
302 * Get the authentication method to use for this frontend/database
303 * combination. Note: we do not parse the file at this point; this has
304 * already been done elsewhere. hba.c dropped an error message into the
305 * server logfile if parsing the hba config file failed.
307 hba_getauthmethod(port);
310 * Enable immediate response to SIGTERM/SIGINT/timeout interrupts. (We
311 * don't want this during hba_getauthmethod() because it might have to do
312 * database access, eg for role membership checks.)
314 ImmediateInterruptOK = true;
315 /* And don't forget to detect one that already arrived */
316 CHECK_FOR_INTERRUPTS();
319 * This is the first point where we have access to the hba record for the
320 * current connection, so perform any verifications based on the hba
321 * options field that should be done *before* the authentication here.
323 if (port->hba->clientcert)
326 * When we parse pg_hba.conf, we have already made sure that we have
327 * been able to load a certificate store. Thus, if a certificate is
328 * present on the client, it has been verified against our root
329 * certificate store, and the connection would have been aborted
330 * already if it didn't verify ok.
333 if (!port->peer_cert_valid)
336 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
337 errmsg("connection requires a valid client certificate")));
342 * hba.c makes sure hba->clientcert can't be set unless OpenSSL is
350 * Now proceed to do the actual authentication check
352 switch (port->hba->auth_method)
357 * An explicit "reject" entry in pg_hba.conf. This report exposes
358 * the fact that there's an explicit reject entry, which is
359 * perhaps not so desirable from a security standpoint; but the
360 * message for an implicit reject could confuse the DBA a lot when
361 * the true situation is a match to an explicit reject. And we
362 * don't want to change the message for an implicit reject. As
363 * noted below, the additional information shown here doesn't
364 * expose anything not known to an attacker.
367 char hostinfo[NI_MAXHOST];
369 pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
370 hostinfo, sizeof(hostinfo),
378 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
379 errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
380 hostinfo, port->user_name,
381 port->ssl_in_use ? _("SSL on") : _("SSL off"))));
384 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
385 errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"",
386 hostinfo, port->user_name)));
393 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
394 errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
395 hostinfo, port->user_name,
397 port->ssl_in_use ? _("SSL on") : _("SSL off"))));
400 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
401 errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"",
402 hostinfo, port->user_name,
403 port->database_name)));
409 case uaImplicitReject:
412 * No matching entry, so tell the user we fell through.
414 * NOTE: the extra info reported here is not a security breach,
415 * because all that info is known at the frontend and must be
416 * assumed known to bad guys. We're merely helping out the less
420 char hostinfo[NI_MAXHOST];
422 pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
423 hostinfo, sizeof(hostinfo),
427 #define HOSTNAME_LOOKUP_DETAIL(port) \
428 (port->remote_hostname ? \
429 (port->remote_hostname_resolv == +1 ? \
430 errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \
431 port->remote_hostname) : \
432 port->remote_hostname_resolv == 0 ? \
433 errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", \
434 port->remote_hostname) : \
435 port->remote_hostname_resolv == -1 ? \
436 errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", \
437 port->remote_hostname) : \
438 port->remote_hostname_resolv == -2 ? \
439 errdetail_log("Could not translate client host name \"%s\" to IP address: %s.", \
440 port->remote_hostname, \
441 gai_strerror(port->remote_hostname_errcode)) : \
443 : (port->remote_hostname_resolv == -2 ? \
444 errdetail_log("Could not resolve client IP address to a host name: %s.", \
445 gai_strerror(port->remote_hostname_errcode)) : \
452 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
453 errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
454 hostinfo, port->user_name,
455 port->ssl_in_use ? _("SSL on") : _("SSL off")),
456 HOSTNAME_LOOKUP_DETAIL(port)));
459 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
460 errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"",
461 hostinfo, port->user_name),
462 HOSTNAME_LOOKUP_DETAIL(port)));
469 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
470 errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
471 hostinfo, port->user_name,
473 port->ssl_in_use ? _("SSL on") : _("SSL off")),
474 HOSTNAME_LOOKUP_DETAIL(port)));
477 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
478 errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"",
479 hostinfo, port->user_name,
480 port->database_name),
481 HOSTNAME_LOOKUP_DETAIL(port)));
489 sendAuthRequest(port, AUTH_REQ_GSS);
490 status = pg_GSS_recvauth(port);
498 sendAuthRequest(port, AUTH_REQ_SSPI);
499 status = pg_SSPI_recvauth(port);
506 #ifdef HAVE_UNIX_SOCKETS
507 status = auth_peer(port);
514 status = ident_inet(port);
518 if (Db_user_namespace)
520 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
521 errmsg("MD5 authentication is not supported when \"db_user_namespace\" is enabled")));
522 sendAuthRequest(port, AUTH_REQ_MD5);
523 status = recv_and_check_password_packet(port, &logdetail);
527 sendAuthRequest(port, AUTH_REQ_PASSWORD);
528 status = recv_and_check_password_packet(port, &logdetail);
533 status = CheckPAMAuth(port, port->user_name, "");
541 status = CheckLDAPAuth(port);
549 status = CheckCertAuth(port);
555 status = CheckRADIUSAuth(port);
562 if (ClientAuthentication_hook)
563 (*ClientAuthentication_hook) (port, status);
565 if (status == STATUS_OK)
566 sendAuthRequest(port, AUTH_REQ_OK);
568 auth_failed(port, status, logdetail);
570 /* Done with authentication, so we should turn off immediate interrupts */
571 ImmediateInterruptOK = false;
576 * Send an authentication request packet to the frontend.
579 sendAuthRequest(Port *port, AuthRequest areq)
583 pq_beginmessage(&buf, 'R');
584 pq_sendint(&buf, (int32) areq, sizeof(int32));
586 /* Add the salt for encrypted passwords. */
587 if (areq == AUTH_REQ_MD5)
588 pq_sendbytes(&buf, port->md5Salt, 4);
590 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
593 * Add the authentication data for the next step of the GSSAPI or SSPI
596 else if (areq == AUTH_REQ_GSS_CONT)
598 if (port->gss->outbuf.length > 0)
600 elog(DEBUG4, "sending GSS token of length %u",
601 (unsigned int) port->gss->outbuf.length);
603 pq_sendbytes(&buf, port->gss->outbuf.value, port->gss->outbuf.length);
611 * Flush message so client will see it, except for AUTH_REQ_OK, which need
612 * not be sent until we are ready for queries.
614 if (areq != AUTH_REQ_OK)
619 * Collect password response packet from frontend.
621 * Returns NULL if couldn't get password, else palloc'd string.
624 recv_password_packet(Port *port)
628 if (PG_PROTOCOL_MAJOR(port->proto) >= 3)
630 /* Expect 'p' message type */
633 mtype = pq_getbyte();
637 * If the client just disconnects without offering a password,
638 * don't make a log entry. This is legal per protocol spec and in
639 * fact commonly done by psql, so complaining just clutters the
644 (errcode(ERRCODE_PROTOCOL_VIOLATION),
645 errmsg("expected password response, got message type %d",
647 return NULL; /* EOF or bad message type */
652 /* For pre-3.0 clients, avoid log entry if they just disconnect */
653 if (pq_peekbyte() == EOF)
654 return NULL; /* EOF */
657 initStringInfo(&buf);
658 if (pq_getmessage(&buf, 1000)) /* receive password */
660 /* EOF - pq_getmessage already logged a suitable message */
666 * Apply sanity check: password packet length should agree with length of
667 * contained string. Note it is safe to use strlen here because
668 * StringInfo is guaranteed to have an appended '\0'.
670 if (strlen(buf.data) + 1 != buf.len)
672 (errcode(ERRCODE_PROTOCOL_VIOLATION),
673 errmsg("invalid password packet size")));
675 /* Do not echo password to logs, for security. */
677 (errmsg("received password packet")));
680 * Return the received string. Note we do not attempt to do any
681 * character-set conversion on it; since we don't yet know the client's
682 * encoding, there wouldn't be much point.
688 /*----------------------------------------------------------------
690 *----------------------------------------------------------------
694 * Called when we have sent an authorization request for a password.
695 * Get the response and check it.
696 * On error, optionally store a detail string at *logdetail.
699 recv_and_check_password_packet(Port *port, char **logdetail)
704 passwd = recv_password_packet(port);
707 return STATUS_EOF; /* client wouldn't send password */
709 result = md5_crypt_verify(port, port->user_name, passwd, logdetail);
718 /*----------------------------------------------------------------
719 * GSSAPI authentication system
720 *----------------------------------------------------------------
724 #if defined(WIN32) && !defined(WIN32_ONLY_COMPILER)
726 * MIT Kerberos GSSAPI DLL doesn't properly export the symbols for MingW
727 * that contain the OIDs required. Redefine here, values copied
728 * from src/athena/auth/krb5/src/lib/gssapi/generic/gssapi_generic.c
730 static const gss_OID_desc GSS_C_NT_USER_NAME_desc =
731 {10, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"};
732 static GSS_DLLIMP gss_OID GSS_C_NT_USER_NAME = &GSS_C_NT_USER_NAME_desc;
737 pg_GSS_error(int severity, char *errmsg, OM_uint32 maj_stat, OM_uint32 min_stat)
739 gss_buffer_desc gmsg;
745 /* Fetch major status message */
747 gss_display_status(&lmin_s, maj_stat, GSS_C_GSS_CODE,
748 GSS_C_NO_OID, &msg_ctx, &gmsg);
749 strlcpy(msg_major, gmsg.value, sizeof(msg_major));
750 gss_release_buffer(&lmin_s, &gmsg);
755 * More than one message available. XXX: Should we loop and read all
756 * messages? (same below)
759 (errmsg_internal("incomplete GSS error report")));
761 /* Fetch mechanism minor status message */
763 gss_display_status(&lmin_s, min_stat, GSS_C_MECH_CODE,
764 GSS_C_NO_OID, &msg_ctx, &gmsg);
765 strlcpy(msg_minor, gmsg.value, sizeof(msg_minor));
766 gss_release_buffer(&lmin_s, &gmsg);
770 (errmsg_internal("incomplete GSS minor error report")));
773 * errmsg_internal, since translation of the first part must be done
774 * before calling this function anyway.
777 (errmsg_internal("%s", errmsg),
778 errdetail_internal("%s: %s", msg_major, msg_minor)));
782 pg_GSS_recvauth(Port *port)
791 gss_buffer_desc gbuf;
794 * GSS auth is not supported for protocol versions before 3, because it
795 * relies on the overall message length word to determine the GSS payload
796 * size in AuthenticationGSSContinue and PasswordMessage messages. (This
797 * is, in fact, a design error in our GSS support, because protocol
798 * messages are supposed to be parsable without relying on the length
799 * word; but it's not worth changing it now.)
801 if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
803 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
804 errmsg("GSSAPI is not supported in protocol version 2")));
806 if (pg_krb_server_keyfile && strlen(pg_krb_server_keyfile) > 0)
809 * Set default Kerberos keytab file for the Krb5 mechanism.
811 * setenv("KRB5_KTNAME", pg_krb_server_keyfile, 0); except setenv()
812 * not always available.
814 if (getenv("KRB5_KTNAME") == NULL)
816 size_t kt_len = strlen(pg_krb_server_keyfile) + 14;
817 char *kt_path = malloc(kt_len);
822 (errcode(ERRCODE_OUT_OF_MEMORY),
823 errmsg("out of memory")));
826 snprintf(kt_path, kt_len, "KRB5_KTNAME=%s", pg_krb_server_keyfile);
832 * We accept any service principal that's present in our keytab. This
833 * increases interoperability between kerberos implementations that see
834 * for example case sensitivity differently, while not really opening up
835 * any vector of attack.
837 port->gss->cred = GSS_C_NO_CREDENTIAL;
840 * Initialize sequence with an empty context
842 port->gss->ctx = GSS_C_NO_CONTEXT;
845 * Loop through GSSAPI message exchange. This exchange can consist of
846 * multiple messags sent in both directions. First message is always from
847 * the client. All messages from client to server are password packets
852 mtype = pq_getbyte();
855 /* Only log error if client didn't disconnect. */
858 (errcode(ERRCODE_PROTOCOL_VIOLATION),
859 errmsg("expected GSS response, got message type %d",
864 /* Get the actual GSS token */
865 initStringInfo(&buf);
866 if (pq_getmessage(&buf, PG_MAX_AUTH_TOKEN_LENGTH))
868 /* EOF - pq_getmessage already logged error */
873 /* Map to GSSAPI style buffer */
874 gbuf.length = buf.len;
875 gbuf.value = buf.data;
877 elog(DEBUG4, "Processing received GSS token of length %u",
878 (unsigned int) gbuf.length);
880 maj_stat = gss_accept_sec_context(
885 GSS_C_NO_CHANNEL_BINDINGS,
893 /* gbuf no longer used */
896 elog(DEBUG5, "gss_accept_sec_context major: %d, "
897 "minor: %d, outlen: %u, outflags: %x",
899 (unsigned int) port->gss->outbuf.length, gflags);
901 if (port->gss->outbuf.length != 0)
904 * Negotiation generated data to be sent to the client.
906 elog(DEBUG4, "sending GSS response token of length %u",
907 (unsigned int) port->gss->outbuf.length);
909 sendAuthRequest(port, AUTH_REQ_GSS_CONT);
911 gss_release_buffer(&lmin_s, &port->gss->outbuf);
914 if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
916 gss_delete_sec_context(&lmin_s, &port->gss->ctx, GSS_C_NO_BUFFER);
918 gettext_noop("accepting GSS security context failed"),
922 if (maj_stat == GSS_S_CONTINUE_NEEDED)
923 elog(DEBUG4, "GSS continue needed");
925 } while (maj_stat == GSS_S_CONTINUE_NEEDED);
927 if (port->gss->cred != GSS_C_NO_CREDENTIAL)
930 * Release service principal credentials
932 gss_release_cred(&min_stat, &port->gss->cred);
936 * GSS_S_COMPLETE indicates that authentication is now complete.
938 * Get the name of the user that authenticated, and compare it to the pg
939 * username that was specified for the connection.
941 maj_stat = gss_display_name(&min_stat, port->gss->name, &gbuf, NULL);
942 if (maj_stat != GSS_S_COMPLETE)
944 gettext_noop("retrieving GSS user name failed"),
948 * Split the username at the realm separator
950 if (strchr(gbuf.value, '@'))
952 char *cp = strchr(gbuf.value, '@');
955 * If we are not going to include the realm in the username that is
956 * passed to the ident map, destructively modify it here to remove the
957 * realm. Then advance past the separator to check the realm.
959 if (!port->hba->include_realm)
963 if (port->hba->krb_realm != NULL && strlen(port->hba->krb_realm))
966 * Match the realm part of the name first
968 if (pg_krb_caseins_users)
969 ret = pg_strcasecmp(port->hba->krb_realm, cp);
971 ret = strcmp(port->hba->krb_realm, cp);
975 /* GSS realm does not match */
977 "GSSAPI realm (%s) and configured realm (%s) don't match",
978 cp, port->hba->krb_realm);
979 gss_release_buffer(&lmin_s, &gbuf);
984 else if (port->hba->krb_realm && strlen(port->hba->krb_realm))
987 "GSSAPI did not return realm but realm matching was requested");
989 gss_release_buffer(&lmin_s, &gbuf);
993 ret = check_usermap(port->hba->usermap, port->user_name, gbuf.value,
994 pg_krb_caseins_users);
996 gss_release_buffer(&lmin_s, &gbuf);
1000 #endif /* ENABLE_GSS */
1003 /*----------------------------------------------------------------
1004 * SSPI authentication system
1005 *----------------------------------------------------------------
1009 pg_SSPI_error(int severity, const char *errmsg, SECURITY_STATUS r)
1013 if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, r, 0,
1014 sysmsg, sizeof(sysmsg), NULL) == 0)
1016 (errmsg_internal("%s", errmsg),
1017 errdetail_internal("SSPI error %x", (unsigned int) r)));
1020 (errmsg_internal("%s", errmsg),
1021 errdetail_internal("%s (%x)", sysmsg, (unsigned int) r)));
1025 pg_SSPI_recvauth(Port *port)
1030 CredHandle sspicred;
1031 CtxtHandle *sspictx = NULL,
1035 SecBufferDesc inbuf;
1036 SecBufferDesc outbuf;
1037 SecBuffer OutBuffers[1];
1038 SecBuffer InBuffers[1];
1040 TOKEN_USER *tokenuser;
1042 char accountname[MAXPGPATH];
1043 char domainname[MAXPGPATH];
1044 DWORD accountnamesize = sizeof(accountname);
1045 DWORD domainnamesize = sizeof(domainname);
1046 SID_NAME_USE accountnameuse;
1048 QUERY_SECURITY_CONTEXT_TOKEN_FN _QuerySecurityContextToken;
1051 * SSPI auth is not supported for protocol versions before 3, because it
1052 * relies on the overall message length word to determine the SSPI payload
1053 * size in AuthenticationGSSContinue and PasswordMessage messages. (This
1054 * is, in fact, a design error in our SSPI support, because protocol
1055 * messages are supposed to be parsable without relying on the length
1056 * word; but it's not worth changing it now.)
1058 if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
1060 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1061 errmsg("SSPI is not supported in protocol version 2")));
1064 * Acquire a handle to the server credentials.
1066 r = AcquireCredentialsHandle(NULL,
1068 SECPKG_CRED_INBOUND,
1076 pg_SSPI_error(ERROR, _("could not acquire SSPI credentials"), r);
1079 * Loop through SSPI message exchange. This exchange can consist of
1080 * multiple messags sent in both directions. First message is always from
1081 * the client. All messages from client to server are password packets
1086 mtype = pq_getbyte();
1089 /* Only log error if client didn't disconnect. */
1092 (errcode(ERRCODE_PROTOCOL_VIOLATION),
1093 errmsg("expected SSPI response, got message type %d",
1095 return STATUS_ERROR;
1098 /* Get the actual SSPI token */
1099 initStringInfo(&buf);
1100 if (pq_getmessage(&buf, PG_MAX_AUTH_TOKEN_LENGTH))
1102 /* EOF - pq_getmessage already logged error */
1104 return STATUS_ERROR;
1107 /* Map to SSPI style buffer */
1108 inbuf.ulVersion = SECBUFFER_VERSION;
1110 inbuf.pBuffers = InBuffers;
1111 InBuffers[0].pvBuffer = buf.data;
1112 InBuffers[0].cbBuffer = buf.len;
1113 InBuffers[0].BufferType = SECBUFFER_TOKEN;
1115 /* Prepare output buffer */
1116 OutBuffers[0].pvBuffer = NULL;
1117 OutBuffers[0].BufferType = SECBUFFER_TOKEN;
1118 OutBuffers[0].cbBuffer = 0;
1119 outbuf.cBuffers = 1;
1120 outbuf.pBuffers = OutBuffers;
1121 outbuf.ulVersion = SECBUFFER_VERSION;
1124 elog(DEBUG4, "Processing received SSPI token of length %u",
1125 (unsigned int) buf.len);
1127 r = AcceptSecurityContext(&sspicred,
1130 ASC_REQ_ALLOCATE_MEMORY,
1131 SECURITY_NETWORK_DREP,
1137 /* input buffer no longer used */
1140 if (outbuf.cBuffers > 0 && outbuf.pBuffers[0].cbBuffer > 0)
1143 * Negotiation generated data to be sent to the client.
1145 elog(DEBUG4, "sending SSPI response token of length %u",
1146 (unsigned int) outbuf.pBuffers[0].cbBuffer);
1148 port->gss->outbuf.length = outbuf.pBuffers[0].cbBuffer;
1149 port->gss->outbuf.value = outbuf.pBuffers[0].pvBuffer;
1151 sendAuthRequest(port, AUTH_REQ_GSS_CONT);
1153 FreeContextBuffer(outbuf.pBuffers[0].pvBuffer);
1156 if (r != SEC_E_OK && r != SEC_I_CONTINUE_NEEDED)
1158 if (sspictx != NULL)
1160 DeleteSecurityContext(sspictx);
1163 FreeCredentialsHandle(&sspicred);
1164 pg_SSPI_error(ERROR,
1165 _("could not accept SSPI security context"), r);
1169 * Overwrite the current context with the one we just received. If
1170 * sspictx is NULL it was the first loop and we need to allocate a
1171 * buffer for it. On subsequent runs, we can just overwrite the buffer
1172 * contents since the size does not change.
1174 if (sspictx == NULL)
1176 sspictx = malloc(sizeof(CtxtHandle));
1177 if (sspictx == NULL)
1179 (errmsg("out of memory")));
1182 memcpy(sspictx, &newctx, sizeof(CtxtHandle));
1184 if (r == SEC_I_CONTINUE_NEEDED)
1185 elog(DEBUG4, "SSPI continue needed");
1187 } while (r == SEC_I_CONTINUE_NEEDED);
1191 * Release service principal credentials
1193 FreeCredentialsHandle(&sspicred);
1197 * SEC_E_OK indicates that authentication is now complete.
1199 * Get the name of the user that authenticated, and compare it to the pg
1200 * username that was specified for the connection.
1202 * MingW is missing the export for QuerySecurityContextToken in the
1203 * secur32 library, so we have to load it dynamically.
1206 secur32 = LoadLibrary("SECUR32.DLL");
1207 if (secur32 == NULL)
1209 (errmsg_internal("could not load secur32.dll: error code %lu",
1212 _QuerySecurityContextToken = (QUERY_SECURITY_CONTEXT_TOKEN_FN)
1213 GetProcAddress(secur32, "QuerySecurityContextToken");
1214 if (_QuerySecurityContextToken == NULL)
1216 FreeLibrary(secur32);
1218 (errmsg_internal("could not locate QuerySecurityContextToken in secur32.dll: error code %lu",
1222 r = (_QuerySecurityContextToken) (sspictx, &token);
1225 FreeLibrary(secur32);
1226 pg_SSPI_error(ERROR,
1227 _("could not get token from SSPI security context"), r);
1230 FreeLibrary(secur32);
1233 * No longer need the security context, everything from here on uses the
1236 DeleteSecurityContext(sspictx);
1239 if (!GetTokenInformation(token, TokenUser, NULL, 0, &retlen) && GetLastError() != 122)
1241 (errmsg_internal("could not get token user size: error code %lu",
1244 tokenuser = malloc(retlen);
1245 if (tokenuser == NULL)
1247 (errmsg("out of memory")));
1249 if (!GetTokenInformation(token, TokenUser, tokenuser, retlen, &retlen))
1251 (errmsg_internal("could not get user token: error code %lu",
1254 if (!LookupAccountSid(NULL, tokenuser->User.Sid, accountname, &accountnamesize,
1255 domainname, &domainnamesize, &accountnameuse))
1257 (errmsg_internal("could not look up account SID: error code %lu",
1263 * Compare realm/domain if requested. In SSPI, always compare case
1266 if (port->hba->krb_realm && strlen(port->hba->krb_realm))
1268 if (pg_strcasecmp(port->hba->krb_realm, domainname) != 0)
1271 "SSPI domain (%s) and configured domain (%s) don't match",
1272 domainname, port->hba->krb_realm);
1274 return STATUS_ERROR;
1279 * We have the username (without domain/realm) in accountname, compare to
1280 * the supplied value. In SSPI, always compare case insensitive.
1282 * If set to include realm, append it in <username>@<realm> format.
1284 if (port->hba->include_realm)
1289 namebuf = psprintf("%s@%s", accountname, domainname);
1290 retval = check_usermap(port->hba->usermap, port->user_name, namebuf, true);
1295 return check_usermap(port->hba->usermap, port->user_name, accountname, true);
1297 #endif /* ENABLE_SSPI */
1301 /*----------------------------------------------------------------
1302 * Ident authentication system
1303 *----------------------------------------------------------------
1307 * Parse the string "*ident_response" as a response from a query to an Ident
1308 * server. If it's a normal response indicating a user name, return true
1309 * and store the user name at *ident_user. If it's anything else,
1313 interpret_ident_response(const char *ident_response,
1316 const char *cursor = ident_response; /* Cursor into *ident_response */
1319 * Ident's response, in the telnet tradition, should end in crlf (\r\n).
1321 if (strlen(ident_response) < 2)
1323 else if (ident_response[strlen(ident_response) - 2] != '\r')
1327 while (*cursor != ':' && *cursor != '\r')
1328 cursor++; /* skip port field */
1334 /* We're positioned to colon before response type field */
1335 char response_type[80];
1336 int i; /* Index into *response_type */
1338 cursor++; /* Go over colon */
1339 while (pg_isblank(*cursor))
1340 cursor++; /* skip blanks */
1342 while (*cursor != ':' && *cursor != '\r' && !pg_isblank(*cursor) &&
1343 i < (int) (sizeof(response_type) - 1))
1344 response_type[i++] = *cursor++;
1345 response_type[i] = '\0';
1346 while (pg_isblank(*cursor))
1347 cursor++; /* skip blanks */
1348 if (strcmp(response_type, "USERID") != 0)
1353 * It's a USERID response. Good. "cursor" should be pointing
1354 * to the colon that precedes the operating system type.
1360 cursor++; /* Go over colon */
1361 /* Skip over operating system field. */
1362 while (*cursor != ':' && *cursor != '\r')
1368 int i; /* Index into *ident_user */
1370 cursor++; /* Go over colon */
1371 while (pg_isblank(*cursor))
1372 cursor++; /* skip blanks */
1373 /* Rest of line is user name. Copy it over. */
1375 while (*cursor != '\r' && i < IDENT_USERNAME_MAX)
1376 ident_user[i++] = *cursor++;
1377 ident_user[i] = '\0';
1388 * Talk to the ident server on host "remote_ip_addr" and find out who
1389 * owns the tcp connection from his port "remote_port" to port
1390 * "local_port_addr" on host "local_ip_addr". Return the user name the
1391 * ident server gives as "*ident_user".
1393 * IP addresses and port numbers are in network byte order.
1395 * But iff we're unable to get the information from ident, return false.
1398 ident_inet(hbaPort *port)
1400 const SockAddr remote_addr = port->raddr;
1401 const SockAddr local_addr = port->laddr;
1402 char ident_user[IDENT_USERNAME_MAX + 1];
1403 pgsocket sock_fd; /* File descriptor for socket on which we talk
1405 int rc; /* Return code from a locally called function */
1407 char remote_addr_s[NI_MAXHOST];
1408 char remote_port[NI_MAXSERV];
1409 char local_addr_s[NI_MAXHOST];
1410 char local_port[NI_MAXSERV];
1411 char ident_port[NI_MAXSERV];
1412 char ident_query[80];
1413 char ident_response[80 + IDENT_USERNAME_MAX];
1414 struct addrinfo *ident_serv = NULL,
1419 * Might look a little weird to first convert it to text and then back to
1420 * sockaddr, but it's protocol independent.
1422 pg_getnameinfo_all(&remote_addr.addr, remote_addr.salen,
1423 remote_addr_s, sizeof(remote_addr_s),
1424 remote_port, sizeof(remote_port),
1425 NI_NUMERICHOST | NI_NUMERICSERV);
1426 pg_getnameinfo_all(&local_addr.addr, local_addr.salen,
1427 local_addr_s, sizeof(local_addr_s),
1428 local_port, sizeof(local_port),
1429 NI_NUMERICHOST | NI_NUMERICSERV);
1431 snprintf(ident_port, sizeof(ident_port), "%d", IDENT_PORT);
1432 hints.ai_flags = AI_NUMERICHOST;
1433 hints.ai_family = remote_addr.addr.ss_family;
1434 hints.ai_socktype = SOCK_STREAM;
1435 hints.ai_protocol = 0;
1436 hints.ai_addrlen = 0;
1437 hints.ai_canonname = NULL;
1438 hints.ai_addr = NULL;
1439 hints.ai_next = NULL;
1440 rc = pg_getaddrinfo_all(remote_addr_s, ident_port, &hints, &ident_serv);
1441 if (rc || !ident_serv)
1444 pg_freeaddrinfo_all(hints.ai_family, ident_serv);
1445 return STATUS_ERROR; /* we don't expect this to happen */
1448 hints.ai_flags = AI_NUMERICHOST;
1449 hints.ai_family = local_addr.addr.ss_family;
1450 hints.ai_socktype = SOCK_STREAM;
1451 hints.ai_protocol = 0;
1452 hints.ai_addrlen = 0;
1453 hints.ai_canonname = NULL;
1454 hints.ai_addr = NULL;
1455 hints.ai_next = NULL;
1456 rc = pg_getaddrinfo_all(local_addr_s, NULL, &hints, &la);
1460 pg_freeaddrinfo_all(hints.ai_family, la);
1461 return STATUS_ERROR; /* we don't expect this to happen */
1464 sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
1465 ident_serv->ai_protocol);
1466 if (sock_fd == PGINVALID_SOCKET)
1469 (errcode_for_socket_access(),
1470 errmsg("could not create socket for Ident connection: %m")));
1471 ident_return = false;
1472 goto ident_inet_done;
1476 * Bind to the address which the client originally contacted, otherwise
1477 * the ident server won't be able to match up the right connection. This
1478 * is necessary if the PostgreSQL server is running on an IP alias.
1480 rc = bind(sock_fd, la->ai_addr, la->ai_addrlen);
1484 (errcode_for_socket_access(),
1485 errmsg("could not bind to local address \"%s\": %m",
1487 ident_return = false;
1488 goto ident_inet_done;
1491 rc = connect(sock_fd, ident_serv->ai_addr,
1492 ident_serv->ai_addrlen);
1496 (errcode_for_socket_access(),
1497 errmsg("could not connect to Ident server at address \"%s\", port %s: %m",
1498 remote_addr_s, ident_port)));
1499 ident_return = false;
1500 goto ident_inet_done;
1503 /* The query we send to the Ident server */
1504 snprintf(ident_query, sizeof(ident_query), "%s,%s\r\n",
1505 remote_port, local_port);
1507 /* loop in case send is interrupted */
1510 rc = send(sock_fd, ident_query, strlen(ident_query), 0);
1511 } while (rc < 0 && errno == EINTR);
1516 (errcode_for_socket_access(),
1517 errmsg("could not send query to Ident server at address \"%s\", port %s: %m",
1518 remote_addr_s, ident_port)));
1519 ident_return = false;
1520 goto ident_inet_done;
1525 rc = recv(sock_fd, ident_response, sizeof(ident_response) - 1, 0);
1526 } while (rc < 0 && errno == EINTR);
1531 (errcode_for_socket_access(),
1532 errmsg("could not receive response from Ident server at address \"%s\", port %s: %m",
1533 remote_addr_s, ident_port)));
1534 ident_return = false;
1535 goto ident_inet_done;
1538 ident_response[rc] = '\0';
1539 ident_return = interpret_ident_response(ident_response, ident_user);
1542 (errmsg("invalidly formatted response from Ident server: \"%s\"",
1546 if (sock_fd != PGINVALID_SOCKET)
1547 closesocket(sock_fd);
1548 pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
1549 pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
1552 /* Success! Check the usermap */
1553 return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
1554 return STATUS_ERROR;
1558 * Ask kernel about the credentials of the connecting process,
1559 * determine the symbolic name of the corresponding user, and check
1560 * if valid per the usermap.
1562 * Iff authorized, return STATUS_OK, otherwise return STATUS_ERROR.
1564 #ifdef HAVE_UNIX_SOCKETS
1567 auth_peer(hbaPort *port)
1569 char ident_user[IDENT_USERNAME_MAX + 1];
1574 if (getpeereid(port->sock, &uid, &gid) != 0)
1576 /* Provide special error message if getpeereid is a stub */
1577 if (errno == ENOSYS)
1579 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1580 errmsg("peer authentication is not supported on this platform")));
1583 (errcode_for_socket_access(),
1584 errmsg("could not get peer credentials: %m")));
1585 return STATUS_ERROR;
1588 errno = 0; /* clear errno before call */
1593 (errmsg("failed to look up local user id %ld: %s",
1594 (long) uid, errno ? strerror(errno) : _("user does not exist"))));
1595 return STATUS_ERROR;
1598 strlcpy(ident_user, pw->pw_name, IDENT_USERNAME_MAX + 1);
1600 return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
1602 #endif /* HAVE_UNIX_SOCKETS */
1605 /*----------------------------------------------------------------
1606 * PAM authentication system
1607 *----------------------------------------------------------------
1612 * PAM conversation function
1616 pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg,
1617 struct pam_response ** resp, void *appdata_ptr)
1620 struct pam_response *reply;
1624 passwd = (char *) appdata_ptr;
1628 * Workaround for Solaris 2.6 where the PAM library is broken and does
1629 * not pass appdata_ptr to the conversation routine
1631 passwd = pam_passwd;
1634 *resp = NULL; /* in case of error exit */
1636 if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG)
1637 return PAM_CONV_ERR;
1640 * Explicitly not using palloc here - PAM will free this memory in
1643 if ((reply = calloc(num_msg, sizeof(struct pam_response))) == NULL)
1646 (errcode(ERRCODE_OUT_OF_MEMORY),
1647 errmsg("out of memory")));
1648 return PAM_CONV_ERR;
1651 for (i = 0; i < num_msg; i++)
1653 switch (msg[i]->msg_style)
1655 case PAM_PROMPT_ECHO_OFF:
1656 if (strlen(passwd) == 0)
1659 * Password wasn't passed to PAM the first time around -
1660 * let's go ask the client to send a password, which we
1661 * then stuff into PAM.
1663 sendAuthRequest(pam_port_cludge, AUTH_REQ_PASSWORD);
1664 passwd = recv_password_packet(pam_port_cludge);
1668 * Client didn't want to send password. We
1669 * intentionally do not log anything about this.
1673 if (strlen(passwd) == 0)
1676 (errmsg("empty password returned by client")));
1680 if ((reply[i].resp = strdup(passwd)) == NULL)
1682 reply[i].resp_retcode = PAM_SUCCESS;
1686 (errmsg("error from underlying PAM layer: %s",
1690 /* we don't bother to log TEXT_INFO messages */
1691 if ((reply[i].resp = strdup("")) == NULL)
1693 reply[i].resp_retcode = PAM_SUCCESS;
1696 elog(LOG, "unsupported PAM conversation %d/\"%s\"",
1698 msg[i]->msg ? msg[i]->msg : "(none)");
1707 /* free up whatever we allocated */
1708 for (i = 0; i < num_msg; i++)
1710 if (reply[i].resp != NULL)
1711 free(reply[i].resp);
1715 return PAM_CONV_ERR;
1720 * Check authentication against PAM.
1723 CheckPAMAuth(Port *port, char *user, char *password)
1726 pam_handle_t *pamh = NULL;
1729 * We can't entirely rely on PAM to pass through appdata --- it appears
1730 * not to work on at least Solaris 2.6. So use these ugly static
1731 * variables instead.
1733 pam_passwd = password;
1734 pam_port_cludge = port;
1737 * Set the application data portion of the conversation struct. This is
1738 * later used inside the PAM conversation to pass the password to the
1739 * authentication module.
1741 pam_passw_conv.appdata_ptr = (char *) password; /* from password above,
1744 /* Optionally, one can set the service name in pg_hba.conf */
1745 if (port->hba->pamservice && port->hba->pamservice[0] != '\0')
1746 retval = pam_start(port->hba->pamservice, "pgsql@",
1747 &pam_passw_conv, &pamh);
1749 retval = pam_start(PGSQL_PAM_SERVICE, "pgsql@",
1750 &pam_passw_conv, &pamh);
1752 if (retval != PAM_SUCCESS)
1755 (errmsg("could not create PAM authenticator: %s",
1756 pam_strerror(pamh, retval))));
1757 pam_passwd = NULL; /* Unset pam_passwd */
1758 return STATUS_ERROR;
1761 retval = pam_set_item(pamh, PAM_USER, user);
1763 if (retval != PAM_SUCCESS)
1766 (errmsg("pam_set_item(PAM_USER) failed: %s",
1767 pam_strerror(pamh, retval))));
1768 pam_passwd = NULL; /* Unset pam_passwd */
1769 return STATUS_ERROR;
1772 retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv);
1774 if (retval != PAM_SUCCESS)
1777 (errmsg("pam_set_item(PAM_CONV) failed: %s",
1778 pam_strerror(pamh, retval))));
1779 pam_passwd = NULL; /* Unset pam_passwd */
1780 return STATUS_ERROR;
1783 retval = pam_authenticate(pamh, 0);
1785 if (retval != PAM_SUCCESS)
1788 (errmsg("pam_authenticate failed: %s",
1789 pam_strerror(pamh, retval))));
1790 pam_passwd = NULL; /* Unset pam_passwd */
1791 return STATUS_ERROR;
1794 retval = pam_acct_mgmt(pamh, 0);
1796 if (retval != PAM_SUCCESS)
1799 (errmsg("pam_acct_mgmt failed: %s",
1800 pam_strerror(pamh, retval))));
1801 pam_passwd = NULL; /* Unset pam_passwd */
1802 return STATUS_ERROR;
1805 retval = pam_end(pamh, retval);
1807 if (retval != PAM_SUCCESS)
1810 (errmsg("could not release PAM authenticator: %s",
1811 pam_strerror(pamh, retval))));
1814 pam_passwd = NULL; /* Unset pam_passwd */
1816 return (retval == PAM_SUCCESS ? STATUS_OK : STATUS_ERROR);
1818 #endif /* USE_PAM */
1822 /*----------------------------------------------------------------
1823 * LDAP authentication system
1824 *----------------------------------------------------------------
1829 * Initialize a connection to the LDAP server, including setting up
1833 InitializeLDAPConnection(Port *port, LDAP **ldap)
1835 int ldapversion = LDAP_VERSION3;
1838 *ldap = ldap_init(port->hba->ldapserver, port->hba->ldapport);
1843 (errmsg("could not initialize LDAP: %m")));
1846 (errmsg("could not initialize LDAP: error code %d",
1847 (int) LdapGetLastError())));
1849 return STATUS_ERROR;
1852 if ((r = ldap_set_option(*ldap, LDAP_OPT_PROTOCOL_VERSION, &ldapversion)) != LDAP_SUCCESS)
1856 (errmsg("could not set LDAP protocol version: %s", ldap_err2string(r))));
1857 return STATUS_ERROR;
1860 if (port->hba->ldaptls)
1863 if ((r = ldap_start_tls_s(*ldap, NULL, NULL)) != LDAP_SUCCESS)
1865 static __ldap_start_tls_sA _ldap_start_tls_sA = NULL;
1867 if (_ldap_start_tls_sA == NULL)
1870 * Need to load this function dynamically because it does not
1871 * exist on Windows 2000, and causes a load error for the whole
1872 * exe if referenced.
1876 ldaphandle = LoadLibrary("WLDAP32.DLL");
1877 if (ldaphandle == NULL)
1880 * should never happen since we import other files from
1881 * wldap32, but check anyway
1885 (errmsg("could not load wldap32.dll")));
1886 return STATUS_ERROR;
1888 _ldap_start_tls_sA = (__ldap_start_tls_sA) GetProcAddress(ldaphandle, "ldap_start_tls_sA");
1889 if (_ldap_start_tls_sA == NULL)
1893 (errmsg("could not load function _ldap_start_tls_sA in wldap32.dll"),
1894 errdetail("LDAP over SSL is not supported on this platform.")));
1895 return STATUS_ERROR;
1899 * Leak LDAP handle on purpose, because we need the library to
1900 * stay open. This is ok because it will only ever be leaked once
1901 * per process and is automatically cleaned up on process exit.
1904 if ((r = _ldap_start_tls_sA(*ldap, NULL, NULL, NULL, NULL)) != LDAP_SUCCESS)
1909 (errmsg("could not start LDAP TLS session: %s", ldap_err2string(r))));
1910 return STATUS_ERROR;
1918 * Perform LDAP authentication
1921 CheckLDAPAuth(Port *port)
1928 if (!port->hba->ldapserver || port->hba->ldapserver[0] == '\0')
1931 (errmsg("LDAP server not specified")));
1932 return STATUS_ERROR;
1935 if (port->hba->ldapport == 0)
1936 port->hba->ldapport = LDAP_PORT;
1938 sendAuthRequest(port, AUTH_REQ_PASSWORD);
1940 passwd = recv_password_packet(port);
1942 return STATUS_EOF; /* client wouldn't send password */
1944 if (strlen(passwd) == 0)
1947 (errmsg("empty password returned by client")));
1948 return STATUS_ERROR;
1951 if (InitializeLDAPConnection(port, &ldap) == STATUS_ERROR)
1952 /* Error message already sent */
1953 return STATUS_ERROR;
1955 if (port->hba->ldapbasedn)
1958 * First perform an LDAP search to find the DN for the user we are
1959 * trying to log in as.
1962 LDAPMessage *search_message;
1964 char *attributes[2];
1970 * Disallow any characters that we would otherwise need to escape,
1971 * since they aren't really reasonable in a username anyway. Allowing
1972 * them would make it possible to inject any kind of custom filters in
1975 for (c = port->user_name; *c; c++)
1984 (errmsg("invalid character in user name for LDAP authentication")));
1985 return STATUS_ERROR;
1990 * Bind with a pre-defined username/password (if available) for
1991 * searching. If none is specified, this turns into an anonymous bind.
1993 r = ldap_simple_bind_s(ldap,
1994 port->hba->ldapbinddn ? port->hba->ldapbinddn : "",
1995 port->hba->ldapbindpasswd ? port->hba->ldapbindpasswd : "");
1996 if (r != LDAP_SUCCESS)
1999 (errmsg("could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s",
2000 port->hba->ldapbinddn, port->hba->ldapserver, ldap_err2string(r))));
2001 return STATUS_ERROR;
2004 /* Fetch just one attribute, else *all* attributes are returned */
2005 attributes[0] = port->hba->ldapsearchattribute ? port->hba->ldapsearchattribute : "uid";
2006 attributes[1] = NULL;
2008 filter = psprintf("(%s=%s)",
2012 r = ldap_search_s(ldap,
2013 port->hba->ldapbasedn,
2014 port->hba->ldapscope,
2020 if (r != LDAP_SUCCESS)
2023 (errmsg("could not search LDAP for filter \"%s\" on server \"%s\": %s",
2024 filter, port->hba->ldapserver, ldap_err2string(r))));
2026 return STATUS_ERROR;
2029 count = ldap_count_entries(ldap, search_message);
2034 (errmsg("LDAP user \"%s\" does not exist", port->user_name),
2035 errdetail("LDAP search for filter \"%s\" on server \"%s\" returned no entries.",
2036 filter, port->hba->ldapserver)));
2039 (errmsg("LDAP user \"%s\" is not unique", port->user_name),
2040 errdetail_plural("LDAP search for filter \"%s\" on server \"%s\" returned %d entry.",
2041 "LDAP search for filter \"%s\" on server \"%s\" returned %d entries.",
2043 filter, port->hba->ldapserver, count)));
2046 ldap_msgfree(search_message);
2047 return STATUS_ERROR;
2050 entry = ldap_first_entry(ldap, search_message);
2051 dn = ldap_get_dn(ldap, entry);
2056 (void) ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &error);
2058 (errmsg("could not get dn for the first entry matching \"%s\" on server \"%s\": %s",
2059 filter, port->hba->ldapserver, ldap_err2string(error))));
2061 ldap_msgfree(search_message);
2062 return STATUS_ERROR;
2064 fulluser = pstrdup(dn);
2068 ldap_msgfree(search_message);
2070 /* Unbind and disconnect from the LDAP server */
2071 r = ldap_unbind_s(ldap);
2072 if (r != LDAP_SUCCESS)
2076 (void) ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &error);
2078 (errmsg("could not unbind after searching for user \"%s\" on server \"%s\": %s",
2079 fulluser, port->hba->ldapserver, ldap_err2string(error))));
2081 return STATUS_ERROR;
2085 * Need to re-initialize the LDAP connection, so that we can bind to
2086 * it with a different username.
2088 if (InitializeLDAPConnection(port, &ldap) == STATUS_ERROR)
2092 /* Error message already sent */
2093 return STATUS_ERROR;
2097 fulluser = psprintf("%s%s%s",
2098 port->hba->ldapprefix ? port->hba->ldapprefix : "",
2100 port->hba->ldapsuffix ? port->hba->ldapsuffix : "");
2102 r = ldap_simple_bind_s(ldap, fulluser, passwd);
2105 if (r != LDAP_SUCCESS)
2108 (errmsg("LDAP login failed for user \"%s\" on server \"%s\": %s",
2109 fulluser, port->hba->ldapserver, ldap_err2string(r))));
2111 return STATUS_ERROR;
2118 #endif /* USE_LDAP */
2121 /*----------------------------------------------------------------
2122 * SSL client certificate authentication
2123 *----------------------------------------------------------------
2127 CheckCertAuth(Port *port)
2131 /* Make sure we have received a username in the certificate */
2132 if (port->peer_cn == NULL ||
2133 strlen(port->peer_cn) <= 0)
2136 (errmsg("certificate authentication failed for user \"%s\": client certificate contains no user name",
2138 return STATUS_ERROR;
2141 /* Just pass the certificate CN to the usermap check */
2142 return check_usermap(port->hba->usermap, port->user_name, port->peer_cn, false);
2147 /*----------------------------------------------------------------
2148 * RADIUS authentication
2149 *----------------------------------------------------------------
2153 * RADIUS authentication is described in RFC2865 (and several
2157 #define RADIUS_VECTOR_LENGTH 16
2158 #define RADIUS_HEADER_LENGTH 20
2172 uint8 vector[RADIUS_VECTOR_LENGTH];
2175 /* RADIUS packet types */
2176 #define RADIUS_ACCESS_REQUEST 1
2177 #define RADIUS_ACCESS_ACCEPT 2
2178 #define RADIUS_ACCESS_REJECT 3
2180 /* RAIDUS attributes */
2181 #define RADIUS_USER_NAME 1
2182 #define RADIUS_PASSWORD 2
2183 #define RADIUS_SERVICE_TYPE 6
2184 #define RADIUS_NAS_IDENTIFIER 32
2186 /* RADIUS service types */
2187 #define RADIUS_AUTHENTICATE_ONLY 8
2189 /* Maximum size of a RADIUS packet we will create or accept */
2190 #define RADIUS_BUFFER_SIZE 1024
2192 /* Seconds to wait - XXX: should be in a config variable! */
2193 #define RADIUS_TIMEOUT 3
2196 radius_add_attribute(radius_packet *packet, uint8 type, const unsigned char *data, int len)
2198 radius_attribute *attr;
2200 if (packet->length + len > RADIUS_BUFFER_SIZE)
2203 * With remotely realistic data, this can never happen. But catch it
2204 * just to make sure we don't overrun a buffer. We'll just skip adding
2205 * the broken attribute, which will in the end cause authentication to
2209 "Adding attribute code %d with length %d to radius packet would create oversize packet, ignoring",
2215 attr = (radius_attribute *) ((unsigned char *) packet + packet->length);
2216 attr->attribute = type;
2217 attr->length = len + 2; /* total size includes type and length */
2218 memcpy(attr->data, data, len);
2219 packet->length += attr->length;
2223 CheckRADIUSAuth(Port *port)
2226 char *identifier = "postgresql";
2227 char radius_buffer[RADIUS_BUFFER_SIZE];
2228 char receive_buffer[RADIUS_BUFFER_SIZE];
2229 radius_packet *packet = (radius_packet *) radius_buffer;
2230 radius_packet *receivepacket = (radius_packet *) receive_buffer;
2231 int32 service = htonl(RADIUS_AUTHENTICATE_ONLY);
2233 uint8 encryptedpassword[RADIUS_VECTOR_LENGTH];
2238 struct sockaddr_in6 localaddr;
2239 struct sockaddr_in6 remoteaddr;
2241 struct sockaddr_in localaddr;
2242 struct sockaddr_in remoteaddr;
2244 struct addrinfo hint;
2245 struct addrinfo *serveraddrs;
2247 ACCEPT_TYPE_ARG3 addrsize;
2249 struct timeval endtime;
2253 /* Make sure struct alignment is correct */
2254 Assert(offsetof(radius_packet, vector) == 4);
2256 /* Verify parameters */
2257 if (!port->hba->radiusserver || port->hba->radiusserver[0] == '\0')
2260 (errmsg("RADIUS server not specified")));
2261 return STATUS_ERROR;
2264 if (!port->hba->radiussecret || port->hba->radiussecret[0] == '\0')
2267 (errmsg("RADIUS secret not specified")));
2268 return STATUS_ERROR;
2271 if (port->hba->radiusport == 0)
2272 port->hba->radiusport = 1812;
2274 MemSet(&hint, 0, sizeof(hint));
2275 hint.ai_socktype = SOCK_DGRAM;
2276 hint.ai_family = AF_UNSPEC;
2277 snprintf(portstr, sizeof(portstr), "%d", port->hba->radiusport);
2279 r = pg_getaddrinfo_all(port->hba->radiusserver, portstr, &hint, &serveraddrs);
2280 if (r || !serveraddrs)
2283 (errmsg("could not translate RADIUS server name \"%s\" to address: %s",
2284 port->hba->radiusserver, gai_strerror(r))));
2286 pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
2287 return STATUS_ERROR;
2289 /* XXX: add support for multiple returned addresses? */
2291 if (port->hba->radiusidentifier && port->hba->radiusidentifier[0])
2292 identifier = port->hba->radiusidentifier;
2294 /* Send regular password request to client, and get the response */
2295 sendAuthRequest(port, AUTH_REQ_PASSWORD);
2297 passwd = recv_password_packet(port);
2299 return STATUS_EOF; /* client wouldn't send password */
2301 if (strlen(passwd) == 0)
2304 (errmsg("empty password returned by client")));
2305 return STATUS_ERROR;
2308 if (strlen(passwd) > RADIUS_VECTOR_LENGTH)
2311 (errmsg("RADIUS authentication does not support passwords longer than 16 characters")));
2312 return STATUS_ERROR;
2315 /* Construct RADIUS packet */
2316 packet->code = RADIUS_ACCESS_REQUEST;
2317 packet->length = RADIUS_HEADER_LENGTH;
2319 if (RAND_bytes(packet->vector, RADIUS_VECTOR_LENGTH) != 1)
2322 (errmsg("could not generate random encryption vector")));
2323 return STATUS_ERROR;
2326 for (i = 0; i < RADIUS_VECTOR_LENGTH; i++)
2327 /* Use a lower strengh random number of OpenSSL is not available */
2328 packet->vector[i] = random() % 255;
2330 packet->id = packet->vector[0];
2331 radius_add_attribute(packet, RADIUS_SERVICE_TYPE, (unsigned char *) &service, sizeof(service));
2332 radius_add_attribute(packet, RADIUS_USER_NAME, (unsigned char *) port->user_name, strlen(port->user_name));
2333 radius_add_attribute(packet, RADIUS_NAS_IDENTIFIER, (unsigned char *) identifier, strlen(identifier));
2336 * RADIUS password attributes are calculated as: e[0] = p[0] XOR
2337 * MD5(secret + vector)
2339 cryptvector = palloc(RADIUS_VECTOR_LENGTH + strlen(port->hba->radiussecret));
2340 memcpy(cryptvector, port->hba->radiussecret, strlen(port->hba->radiussecret));
2341 memcpy(cryptvector + strlen(port->hba->radiussecret), packet->vector, RADIUS_VECTOR_LENGTH);
2342 if (!pg_md5_binary(cryptvector, RADIUS_VECTOR_LENGTH + strlen(port->hba->radiussecret), encryptedpassword))
2345 (errmsg("could not perform MD5 encryption of password")));
2347 return STATUS_ERROR;
2350 for (i = 0; i < RADIUS_VECTOR_LENGTH; i++)
2352 if (i < strlen(passwd))
2353 encryptedpassword[i] = passwd[i] ^ encryptedpassword[i];
2355 encryptedpassword[i] = '\0' ^ encryptedpassword[i];
2357 radius_add_attribute(packet, RADIUS_PASSWORD, encryptedpassword, RADIUS_VECTOR_LENGTH);
2359 /* Length need to be in network order on the wire */
2360 packetlength = packet->length;
2361 packet->length = htons(packet->length);
2363 sock = socket(serveraddrs[0].ai_family, SOCK_DGRAM, 0);
2364 if (sock == PGINVALID_SOCKET)
2367 (errmsg("could not create RADIUS socket: %m")));
2368 pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
2369 return STATUS_ERROR;
2372 memset(&localaddr, 0, sizeof(localaddr));
2374 localaddr.sin6_family = serveraddrs[0].ai_family;
2375 localaddr.sin6_addr = in6addr_any;
2376 if (localaddr.sin6_family == AF_INET6)
2377 addrsize = sizeof(struct sockaddr_in6);
2379 addrsize = sizeof(struct sockaddr_in);
2381 localaddr.sin_family = serveraddrs[0].ai_family;
2382 localaddr.sin_addr.s_addr = INADDR_ANY;
2383 addrsize = sizeof(struct sockaddr_in);
2385 if (bind(sock, (struct sockaddr *) & localaddr, addrsize))
2388 (errmsg("could not bind local RADIUS socket: %m")));
2390 pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
2391 return STATUS_ERROR;
2394 if (sendto(sock, radius_buffer, packetlength, 0,
2395 serveraddrs[0].ai_addr, serveraddrs[0].ai_addrlen) < 0)
2398 (errmsg("could not send RADIUS packet: %m")));
2400 pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
2401 return STATUS_ERROR;
2404 /* Don't need the server address anymore */
2405 pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
2408 * Figure out at what time we should time out. We can't just use a single
2409 * call to select() with a timeout, since somebody can be sending invalid
2410 * packets to our port thus causing us to retry in a loop and never time
2413 gettimeofday(&endtime, NULL);
2414 endtime.tv_sec += RADIUS_TIMEOUT;
2418 struct timeval timeout;
2422 gettimeofday(&now, NULL);
2423 timeoutval = (endtime.tv_sec * 1000000 + endtime.tv_usec) - (now.tv_sec * 1000000 + now.tv_usec);
2424 if (timeoutval <= 0)
2427 (errmsg("timeout waiting for RADIUS response")));
2429 return STATUS_ERROR;
2431 timeout.tv_sec = timeoutval / 1000000;
2432 timeout.tv_usec = timeoutval % 1000000;
2435 FD_SET(sock, &fdset);
2437 r = select(sock + 1, &fdset, NULL, NULL, &timeout);
2443 /* Anything else is an actual error */
2445 (errmsg("could not check status on RADIUS socket: %m")));
2447 return STATUS_ERROR;
2452 (errmsg("timeout waiting for RADIUS response")));
2454 return STATUS_ERROR;
2458 * Attempt to read the response packet, and verify the contents.
2460 * Any packet that's not actually a RADIUS packet, or otherwise does
2461 * not validate as an explicit reject, is just ignored and we retry
2462 * for another packet (until we reach the timeout). This is to avoid
2463 * the possibility to denial-of-service the login by flooding the
2464 * server with invalid packets on the port that we're expecting the
2465 * RADIUS response on.
2468 addrsize = sizeof(remoteaddr);
2469 packetlength = recvfrom(sock, receive_buffer, RADIUS_BUFFER_SIZE, 0,
2470 (struct sockaddr *) & remoteaddr, &addrsize);
2471 if (packetlength < 0)
2474 (errmsg("could not read RADIUS response: %m")));
2475 return STATUS_ERROR;
2479 if (remoteaddr.sin6_port != htons(port->hba->radiusport))
2481 if (remoteaddr.sin_port != htons(port->hba->radiusport))
2486 (errmsg("RADIUS response was sent from incorrect port: %d",
2487 ntohs(remoteaddr.sin6_port))));
2490 (errmsg("RADIUS response was sent from incorrect port: %d",
2491 ntohs(remoteaddr.sin_port))));
2496 if (packetlength < RADIUS_HEADER_LENGTH)
2499 (errmsg("RADIUS response too short: %d", packetlength)));
2503 if (packetlength != ntohs(receivepacket->length))
2506 (errmsg("RADIUS response has corrupt length: %d (actual length %d)",
2507 ntohs(receivepacket->length), packetlength)));
2511 if (packet->id != receivepacket->id)
2514 (errmsg("RADIUS response is to a different request: %d (should be %d)",
2515 receivepacket->id, packet->id)));
2520 * Verify the response authenticator, which is calculated as
2521 * MD5(Code+ID+Length+RequestAuthenticator+Attributes+Secret)
2523 cryptvector = palloc(packetlength + strlen(port->hba->radiussecret));
2525 memcpy(cryptvector, receivepacket, 4); /* code+id+length */
2526 memcpy(cryptvector + 4, packet->vector, RADIUS_VECTOR_LENGTH); /* request
2527 * authenticator, from
2528 * original packet */
2529 if (packetlength > RADIUS_HEADER_LENGTH) /* there may be no
2530 * attributes at all */
2531 memcpy(cryptvector + RADIUS_HEADER_LENGTH, receive_buffer + RADIUS_HEADER_LENGTH, packetlength - RADIUS_HEADER_LENGTH);
2532 memcpy(cryptvector + packetlength, port->hba->radiussecret, strlen(port->hba->radiussecret));
2534 if (!pg_md5_binary(cryptvector,
2535 packetlength + strlen(port->hba->radiussecret),
2539 (errmsg("could not perform MD5 encryption of received packet")));
2545 if (memcmp(receivepacket->vector, encryptedpassword, RADIUS_VECTOR_LENGTH) != 0)
2548 (errmsg("RADIUS response has incorrect MD5 signature")));
2552 if (receivepacket->code == RADIUS_ACCESS_ACCEPT)
2557 else if (receivepacket->code == RADIUS_ACCESS_REJECT)
2560 return STATUS_ERROR;
2565 (errmsg("RADIUS response has invalid code (%d) for user \"%s\"",
2566 receivepacket->code, port->user_name)));
2569 } /* while (true) */