1 /*-------------------------------------------------------------------------
4 * Routines to handle network authentication
6 * Portions Copyright (c) 1996-2012, 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);
41 static char *recv_password_packet(Port *port);
42 static int recv_and_check_password_packet(Port *port);
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;
132 bool pg_krb_caseins_users;
135 /*----------------------------------------------------------------
136 * MIT Kerberos authentication system - protocol version 5
137 *----------------------------------------------------------------
140 static int pg_krb5_recvauth(Port *port);
143 /* Some old versions of Kerberos do not include <com_err.h> in <krb5.h> */
144 #if !defined(__COM_ERR_H) && !defined(__COM_ERR_H__)
148 * Various krb5 state which is not connection specfic, and a flag to
149 * indicate whether we have initialised it yet.
151 static int pg_krb5_initialised;
152 static krb5_context pg_krb5_context;
153 static krb5_keytab pg_krb5_keytab;
154 static krb5_principal pg_krb5_server;
158 /*----------------------------------------------------------------
159 * GSSAPI Authentication
160 *----------------------------------------------------------------
163 #if defined(HAVE_GSSAPI_H)
166 #include <gssapi/gssapi.h>
169 static int pg_GSS_recvauth(Port *port);
170 #endif /* ENABLE_GSS */
173 /*----------------------------------------------------------------
174 * SSPI Authentication
175 *----------------------------------------------------------------
178 typedef SECURITY_STATUS
179 (WINAPI * QUERY_SECURITY_CONTEXT_TOKEN_FN) (
180 PCtxtHandle, void **);
181 static int pg_SSPI_recvauth(Port *port);
184 /*----------------------------------------------------------------
185 * RADIUS Authentication
186 *----------------------------------------------------------------
189 #include <openssl/rand.h>
191 static int CheckRADIUSAuth(Port *port);
195 * Maximum accepted size of GSS and SSPI authentication tokens.
197 * Kerberos tickets are usually quite small, but the TGTs issued by Windows
198 * domain controllers include an authorization field known as the Privilege
199 * Attribute Certificate (PAC), which contains the user's Windows permissions
200 * (group memberships etc.). The PAC is copied into all tickets obtained on
201 * the basis of this TGT (even those issued by Unix realms which the Windows
202 * realm trusts), and can be several kB in size. The maximum token size
203 * accepted by Windows systems is determined by the MaxAuthToken Windows
204 * registry setting. Microsoft recommends that it is not set higher than
205 * 65535 bytes, so that seems like a reasonable limit for us as well.
207 #define PG_MAX_AUTH_TOKEN_LENGTH 65535
210 /*----------------------------------------------------------------
211 * Global authentication functions
212 *----------------------------------------------------------------
216 * This hook allows plugins to get control following client authentication,
217 * but before the user has been informed about the results. It could be used
218 * to record login events, insert a delay after failed authentication, etc.
220 ClientAuthentication_hook_type ClientAuthentication_hook = NULL;
223 * Tell the user the authentication failed, but not (much about) why.
225 * There is a tradeoff here between security concerns and making life
226 * unnecessarily difficult for legitimate users. We would not, for example,
227 * want to report the password we were expecting to receive...
228 * But it seems useful to report the username and authorization method
229 * in use, and these are items that must be presumed known to an attacker
231 * Note that many sorts of failure report additional information in the
232 * postmaster log, which we hope is only readable by good guys.
235 auth_failed(Port *port, int status)
238 int errcode_return = ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION;
241 * If we failed due to EOF from client, just quit; there's no point in
242 * trying to send a message to the client, and not much point in logging
243 * the failure in the postmaster log. (Logging the failure might be
244 * desirable, were it not for the fact that libpq closes the connection
245 * unceremoniously if challenged for a password when it hasn't got one to
246 * send. We'll get a useless log entry for every psql connection under
247 * password auth, even if it's perfectly successful, if we log STATUS_EOF
250 if (status == STATUS_EOF)
253 switch (port->hba->auth_method)
256 case uaImplicitReject:
257 errstr = gettext_noop("authentication failed for user \"%s\": host rejected");
260 errstr = gettext_noop("Kerberos 5 authentication failed for user \"%s\"");
263 errstr = gettext_noop("\"trust\" authentication failed for user \"%s\"");
266 errstr = gettext_noop("Ident authentication failed for user \"%s\"");
269 errstr = gettext_noop("Peer authentication failed for user \"%s\"");
273 errstr = gettext_noop("password authentication failed for user \"%s\"");
274 /* We use it to indicate if a .pgpass password failed. */
275 errcode_return = ERRCODE_INVALID_PASSWORD;
278 errstr = gettext_noop("GSSAPI authentication failed for user \"%s\"");
281 errstr = gettext_noop("SSPI authentication failed for user \"%s\"");
284 errstr = gettext_noop("PAM authentication failed for user \"%s\"");
287 errstr = gettext_noop("LDAP authentication failed for user \"%s\"");
290 errstr = gettext_noop("certificate authentication failed for user \"%s\"");
293 errstr = gettext_noop("RADIUS authentication failed for user \"%s\"");
296 errstr = gettext_noop("authentication failed for user \"%s\": invalid authentication method");
301 (errcode(errcode_return),
302 errmsg(errstr, port->user_name)));
308 * Client authentication starts here. If there is an error, this
309 * function does not return and the backend process is terminated.
312 ClientAuthentication(Port *port)
314 int status = STATUS_ERROR;
317 * Get the authentication method to use for this frontend/database
318 * combination. Note: we do not parse the file at this point; this has
319 * already been done elsewhere. hba.c dropped an error message
320 * into the server logfile if parsing the hba config file failed.
322 hba_getauthmethod(port);
325 * Enable immediate response to SIGTERM/SIGINT/timeout interrupts. (We
326 * don't want this during hba_getauthmethod() because it might have to do
327 * database access, eg for role membership checks.)
329 ImmediateInterruptOK = true;
330 /* And don't forget to detect one that already arrived */
331 CHECK_FOR_INTERRUPTS();
334 * This is the first point where we have access to the hba record for the
335 * current connection, so perform any verifications based on the hba
336 * options field that should be done *before* the authentication here.
338 if (port->hba->clientcert)
341 * When we parse pg_hba.conf, we have already made sure that we have
342 * been able to load a certificate store. Thus, if a certificate is
343 * present on the client, it has been verified against our root
344 * certificate store, and the connection would have been aborted
345 * already if it didn't verify ok.
351 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
352 errmsg("connection requires a valid client certificate")));
357 * hba.c makes sure hba->clientcert can't be set unless OpenSSL is
365 * Now proceed to do the actual authentication check
367 switch (port->hba->auth_method)
372 * An explicit "reject" entry in pg_hba.conf. This report exposes
373 * the fact that there's an explicit reject entry, which is
374 * perhaps not so desirable from a security standpoint; but the
375 * message for an implicit reject could confuse the DBA a lot when
376 * the true situation is a match to an explicit reject. And we
377 * don't want to change the message for an implicit reject. As
378 * noted below, the additional information shown here doesn't
379 * expose anything not known to an attacker.
382 char hostinfo[NI_MAXHOST];
384 pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
385 hostinfo, sizeof(hostinfo),
393 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
394 errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
395 hostinfo, port->user_name,
396 port->ssl ? _("SSL on") : _("SSL off"))));
399 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
400 errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"",
401 hostinfo, port->user_name)));
408 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
409 errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
410 hostinfo, port->user_name,
412 port->ssl ? _("SSL on") : _("SSL off"))));
415 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
416 errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"",
417 hostinfo, port->user_name,
418 port->database_name)));
424 case uaImplicitReject:
427 * No matching entry, so tell the user we fell through.
429 * NOTE: the extra info reported here is not a security breach,
430 * because all that info is known at the frontend and must be
431 * assumed known to bad guys. We're merely helping out the less
435 char hostinfo[NI_MAXHOST];
437 pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
438 hostinfo, sizeof(hostinfo),
442 #define HOSTNAME_LOOKUP_DETAIL(port) \
443 (port->remote_hostname \
444 ? (port->remote_hostname_resolv == +1 \
445 ? errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", port->remote_hostname) \
446 : (port->remote_hostname_resolv == 0 \
447 ? errdetail_log("Client IP address resolved to \"%s\", forward lookup not checked.", port->remote_hostname) \
448 : (port->remote_hostname_resolv == -1 \
449 ? errdetail_log("Client IP address resolved to \"%s\", forward lookup does not match.", port->remote_hostname) \
457 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
458 errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
459 hostinfo, port->user_name,
460 port->ssl ? _("SSL on") : _("SSL off")),
461 HOSTNAME_LOOKUP_DETAIL(port)));
464 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
465 errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"",
466 hostinfo, port->user_name),
467 HOSTNAME_LOOKUP_DETAIL(port)));
474 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
475 errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
476 hostinfo, port->user_name,
478 port->ssl ? _("SSL on") : _("SSL off")),
479 HOSTNAME_LOOKUP_DETAIL(port)));
482 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
483 errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"",
484 hostinfo, port->user_name,
485 port->database_name),
486 HOSTNAME_LOOKUP_DETAIL(port)));
494 sendAuthRequest(port, AUTH_REQ_KRB5);
495 status = pg_krb5_recvauth(port);
503 sendAuthRequest(port, AUTH_REQ_GSS);
504 status = pg_GSS_recvauth(port);
512 sendAuthRequest(port, AUTH_REQ_SSPI);
513 status = pg_SSPI_recvauth(port);
520 #ifdef HAVE_UNIX_SOCKETS
521 status = auth_peer(port);
528 status = ident_inet(port);
532 if (Db_user_namespace)
534 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
535 errmsg("MD5 authentication is not supported when \"db_user_namespace\" is enabled")));
536 sendAuthRequest(port, AUTH_REQ_MD5);
537 status = recv_and_check_password_packet(port);
541 sendAuthRequest(port, AUTH_REQ_PASSWORD);
542 status = recv_and_check_password_packet(port);
547 status = CheckPAMAuth(port, port->user_name, "");
555 status = CheckLDAPAuth(port);
563 status = CheckCertAuth(port);
569 status = CheckRADIUSAuth(port);
576 if (ClientAuthentication_hook)
577 (*ClientAuthentication_hook) (port, status);
579 if (status == STATUS_OK)
580 sendAuthRequest(port, AUTH_REQ_OK);
582 auth_failed(port, status);
584 /* Done with authentication, so we should turn off immediate interrupts */
585 ImmediateInterruptOK = false;
590 * Send an authentication request packet to the frontend.
593 sendAuthRequest(Port *port, AuthRequest areq)
597 pq_beginmessage(&buf, 'R');
598 pq_sendint(&buf, (int32) areq, sizeof(int32));
600 /* Add the salt for encrypted passwords. */
601 if (areq == AUTH_REQ_MD5)
602 pq_sendbytes(&buf, port->md5Salt, 4);
604 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
607 * Add the authentication data for the next step of the GSSAPI or SSPI
610 else if (areq == AUTH_REQ_GSS_CONT)
612 if (port->gss->outbuf.length > 0)
614 elog(DEBUG4, "sending GSS token of length %u",
615 (unsigned int) port->gss->outbuf.length);
617 pq_sendbytes(&buf, port->gss->outbuf.value, port->gss->outbuf.length);
625 * Flush message so client will see it, except for AUTH_REQ_OK, which need
626 * not be sent until we are ready for queries.
628 if (areq != AUTH_REQ_OK)
633 * Collect password response packet from frontend.
635 * Returns NULL if couldn't get password, else palloc'd string.
638 recv_password_packet(Port *port)
642 if (PG_PROTOCOL_MAJOR(port->proto) >= 3)
644 /* Expect 'p' message type */
647 mtype = pq_getbyte();
651 * If the client just disconnects without offering a password,
652 * don't make a log entry. This is legal per protocol spec and in
653 * fact commonly done by psql, so complaining just clutters the
658 (errcode(ERRCODE_PROTOCOL_VIOLATION),
659 errmsg("expected password response, got message type %d",
661 return NULL; /* EOF or bad message type */
666 /* For pre-3.0 clients, avoid log entry if they just disconnect */
667 if (pq_peekbyte() == EOF)
668 return NULL; /* EOF */
671 initStringInfo(&buf);
672 if (pq_getmessage(&buf, 1000)) /* receive password */
674 /* EOF - pq_getmessage already logged a suitable message */
680 * Apply sanity check: password packet length should agree with length of
681 * contained string. Note it is safe to use strlen here because
682 * StringInfo is guaranteed to have an appended '\0'.
684 if (strlen(buf.data) + 1 != buf.len)
686 (errcode(ERRCODE_PROTOCOL_VIOLATION),
687 errmsg("invalid password packet size")));
689 /* Do not echo password to logs, for security. */
691 (errmsg("received password packet")));
694 * Return the received string. Note we do not attempt to do any
695 * character-set conversion on it; since we don't yet know the client's
696 * encoding, there wouldn't be much point.
702 /*----------------------------------------------------------------
704 *----------------------------------------------------------------
708 * Called when we have sent an authorization request for a password.
709 * Get the response and check it.
712 recv_and_check_password_packet(Port *port)
717 passwd = recv_password_packet(port);
720 return STATUS_EOF; /* client wouldn't send password */
722 result = md5_crypt_verify(port, port->user_name, passwd);
730 /*----------------------------------------------------------------
731 * MIT Kerberos authentication system - protocol version 5
732 *----------------------------------------------------------------
737 pg_krb5_init(Port *port)
739 krb5_error_code retval;
742 if (pg_krb5_initialised)
745 retval = krb5_init_context(&pg_krb5_context);
749 (errmsg("Kerberos initialization returned error %d",
751 com_err("postgres", retval, "while initializing krb5");
755 retval = krb5_kt_resolve(pg_krb5_context, pg_krb_server_keyfile, &pg_krb5_keytab);
759 (errmsg("Kerberos keytab resolving returned error %d",
761 com_err("postgres", retval, "while resolving keytab file \"%s\"",
762 pg_krb_server_keyfile);
763 krb5_free_context(pg_krb5_context);
768 * If no hostname was specified, pg_krb_server_hostname is already NULL.
769 * If it's set to blank, force it to NULL.
771 khostname = port->hba->krb_server_hostname;
772 if (khostname && khostname[0] == '\0')
775 retval = krb5_sname_to_principal(pg_krb5_context,
783 (errmsg("Kerberos sname_to_principal(\"%s\", \"%s\") returned error %d",
784 khostname ? khostname : "server hostname", pg_krb_srvnam, retval)));
785 com_err("postgres", retval,
786 "while getting server principal for server \"%s\" for service \"%s\"",
787 khostname ? khostname : "server hostname", pg_krb_srvnam);
788 krb5_kt_close(pg_krb5_context, pg_krb5_keytab);
789 krb5_free_context(pg_krb5_context);
793 pg_krb5_initialised = 1;
799 * pg_krb5_recvauth -- server routine to receive authentication information
802 * We still need to compare the username obtained from the client's setup
803 * packet to the authenticated name.
805 * We have our own keytab file because postgres is unlikely to run as root,
806 * and so cannot read the default keytab.
809 pg_krb5_recvauth(Port *port)
811 krb5_error_code retval;
813 krb5_auth_context auth_context = NULL;
818 ret = pg_krb5_init(port);
819 if (ret != STATUS_OK)
822 retval = krb5_recvauth(pg_krb5_context, &auth_context,
823 (krb5_pointer) &port->sock, pg_krb_srvnam,
824 pg_krb5_server, 0, pg_krb5_keytab, &ticket);
828 (errmsg("Kerberos recvauth returned error %d",
830 com_err("postgres", retval, "from krb5_recvauth");
835 * The "client" structure comes out of the ticket and is therefore
836 * authenticated. Use it to check the username obtained from the
837 * postmaster startup packet.
839 #if defined(HAVE_KRB5_TICKET_ENC_PART2)
840 retval = krb5_unparse_name(pg_krb5_context,
841 ticket->enc_part2->client, &kusername);
842 #elif defined(HAVE_KRB5_TICKET_CLIENT)
843 retval = krb5_unparse_name(pg_krb5_context,
844 ticket->client, &kusername);
846 #error "bogus configuration"
851 (errmsg("Kerberos unparse_name returned error %d",
853 com_err("postgres", retval, "while unparsing client name");
854 krb5_free_ticket(pg_krb5_context, ticket);
855 krb5_auth_con_free(pg_krb5_context, auth_context);
859 cp = strchr(kusername, '@');
863 * If we are not going to include the realm in the username that is
864 * passed to the ident map, destructively modify it here to remove the
865 * realm. Then advance past the separator to check the realm.
867 if (!port->hba->include_realm)
871 if (port->hba->krb_realm != NULL && strlen(port->hba->krb_realm))
873 /* Match realm against configured */
874 if (pg_krb_caseins_users)
875 ret = pg_strcasecmp(port->hba->krb_realm, cp);
877 ret = strcmp(port->hba->krb_realm, cp);
882 "krb5 realm (%s) and configured realm (%s) don't match",
883 cp, port->hba->krb_realm);
885 krb5_free_ticket(pg_krb5_context, ticket);
886 krb5_auth_con_free(pg_krb5_context, auth_context);
891 else if (port->hba->krb_realm && strlen(port->hba->krb_realm))
894 "krb5 did not return realm but realm matching was requested");
896 krb5_free_ticket(pg_krb5_context, ticket);
897 krb5_auth_con_free(pg_krb5_context, auth_context);
901 ret = check_usermap(port->hba->usermap, port->user_name, kusername,
902 pg_krb_caseins_users);
904 krb5_free_ticket(pg_krb5_context, ticket);
905 krb5_auth_con_free(pg_krb5_context, auth_context);
913 /*----------------------------------------------------------------
914 * GSSAPI authentication system
915 *----------------------------------------------------------------
919 #if defined(WIN32) && !defined(WIN32_ONLY_COMPILER)
921 * MIT Kerberos GSSAPI DLL doesn't properly export the symbols for MingW
922 * that contain the OIDs required. Redefine here, values copied
923 * from src/athena/auth/krb5/src/lib/gssapi/generic/gssapi_generic.c
925 static const gss_OID_desc GSS_C_NT_USER_NAME_desc =
926 {10, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"};
927 static GSS_DLLIMP gss_OID GSS_C_NT_USER_NAME = &GSS_C_NT_USER_NAME_desc;
932 pg_GSS_error(int severity, char *errmsg, OM_uint32 maj_stat, OM_uint32 min_stat)
934 gss_buffer_desc gmsg;
940 /* Fetch major status message */
942 gss_display_status(&lmin_s, maj_stat, GSS_C_GSS_CODE,
943 GSS_C_NO_OID, &msg_ctx, &gmsg);
944 strlcpy(msg_major, gmsg.value, sizeof(msg_major));
945 gss_release_buffer(&lmin_s, &gmsg);
950 * More than one message available. XXX: Should we loop and read all
951 * messages? (same below)
954 (errmsg_internal("incomplete GSS error report")));
956 /* Fetch mechanism minor status message */
958 gss_display_status(&lmin_s, min_stat, GSS_C_MECH_CODE,
959 GSS_C_NO_OID, &msg_ctx, &gmsg);
960 strlcpy(msg_minor, gmsg.value, sizeof(msg_minor));
961 gss_release_buffer(&lmin_s, &gmsg);
965 (errmsg_internal("incomplete GSS minor error report")));
968 * errmsg_internal, since translation of the first part must be done
969 * before calling this function anyway.
972 (errmsg_internal("%s", errmsg),
973 errdetail_internal("%s: %s", msg_major, msg_minor)));
977 pg_GSS_recvauth(Port *port)
986 gss_buffer_desc gbuf;
989 * GSS auth is not supported for protocol versions before 3, because it
990 * relies on the overall message length word to determine the GSS payload
991 * size in AuthenticationGSSContinue and PasswordMessage messages. (This
992 * is, in fact, a design error in our GSS support, because protocol
993 * messages are supposed to be parsable without relying on the length
994 * word; but it's not worth changing it now.)
996 if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
998 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
999 errmsg("GSSAPI is not supported in protocol version 2")));
1001 if (pg_krb_server_keyfile && strlen(pg_krb_server_keyfile) > 0)
1004 * Set default Kerberos keytab file for the Krb5 mechanism.
1006 * setenv("KRB5_KTNAME", pg_krb_server_keyfile, 0); except setenv()
1007 * not always available.
1009 if (getenv("KRB5_KTNAME") == NULL)
1011 size_t kt_len = strlen(pg_krb_server_keyfile) + 14;
1012 char *kt_path = malloc(kt_len);
1017 (errcode(ERRCODE_OUT_OF_MEMORY),
1018 errmsg("out of memory")));
1019 return STATUS_ERROR;
1021 snprintf(kt_path, kt_len, "KRB5_KTNAME=%s", pg_krb_server_keyfile);
1027 * We accept any service principal that's present in our keytab. This
1028 * increases interoperability between kerberos implementations that see
1029 * for example case sensitivity differently, while not really opening up
1030 * any vector of attack.
1032 port->gss->cred = GSS_C_NO_CREDENTIAL;
1035 * Initialize sequence with an empty context
1037 port->gss->ctx = GSS_C_NO_CONTEXT;
1040 * Loop through GSSAPI message exchange. This exchange can consist of
1041 * multiple messags sent in both directions. First message is always from
1042 * the client. All messages from client to server are password packets
1047 mtype = pq_getbyte();
1050 /* Only log error if client didn't disconnect. */
1053 (errcode(ERRCODE_PROTOCOL_VIOLATION),
1054 errmsg("expected GSS response, got message type %d",
1056 return STATUS_ERROR;
1059 /* Get the actual GSS token */
1060 initStringInfo(&buf);
1061 if (pq_getmessage(&buf, PG_MAX_AUTH_TOKEN_LENGTH))
1063 /* EOF - pq_getmessage already logged error */
1065 return STATUS_ERROR;
1068 /* Map to GSSAPI style buffer */
1069 gbuf.length = buf.len;
1070 gbuf.value = buf.data;
1072 elog(DEBUG4, "Processing received GSS token of length %u",
1073 (unsigned int) gbuf.length);
1075 maj_stat = gss_accept_sec_context(
1080 GSS_C_NO_CHANNEL_BINDINGS,
1088 /* gbuf no longer used */
1091 elog(DEBUG5, "gss_accept_sec_context major: %d, "
1092 "minor: %d, outlen: %u, outflags: %x",
1094 (unsigned int) port->gss->outbuf.length, gflags);
1096 if (port->gss->outbuf.length != 0)
1099 * Negotiation generated data to be sent to the client.
1103 elog(DEBUG4, "sending GSS response token of length %u",
1104 (unsigned int) port->gss->outbuf.length);
1106 sendAuthRequest(port, AUTH_REQ_GSS_CONT);
1108 gss_release_buffer(&lmin_s, &port->gss->outbuf);
1111 if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
1115 gss_delete_sec_context(&lmin_s, &port->gss->ctx, GSS_C_NO_BUFFER);
1117 gettext_noop("accepting GSS security context failed"),
1118 maj_stat, min_stat);
1121 if (maj_stat == GSS_S_CONTINUE_NEEDED)
1122 elog(DEBUG4, "GSS continue needed");
1124 } while (maj_stat == GSS_S_CONTINUE_NEEDED);
1126 if (port->gss->cred != GSS_C_NO_CREDENTIAL)
1129 * Release service principal credentials
1131 gss_release_cred(&min_stat, &port->gss->cred);
1135 * GSS_S_COMPLETE indicates that authentication is now complete.
1137 * Get the name of the user that authenticated, and compare it to the pg
1138 * username that was specified for the connection.
1140 maj_stat = gss_display_name(&min_stat, port->gss->name, &gbuf, NULL);
1141 if (maj_stat != GSS_S_COMPLETE)
1143 gettext_noop("retrieving GSS user name failed"),
1144 maj_stat, min_stat);
1147 * Split the username at the realm separator
1149 if (strchr(gbuf.value, '@'))
1151 char *cp = strchr(gbuf.value, '@');
1154 * If we are not going to include the realm in the username that is
1155 * passed to the ident map, destructively modify it here to remove the
1156 * realm. Then advance past the separator to check the realm.
1158 if (!port->hba->include_realm)
1162 if (port->hba->krb_realm != NULL && strlen(port->hba->krb_realm))
1165 * Match the realm part of the name first
1167 if (pg_krb_caseins_users)
1168 ret = pg_strcasecmp(port->hba->krb_realm, cp);
1170 ret = strcmp(port->hba->krb_realm, cp);
1174 /* GSS realm does not match */
1176 "GSSAPI realm (%s) and configured realm (%s) don't match",
1177 cp, port->hba->krb_realm);
1178 gss_release_buffer(&lmin_s, &gbuf);
1179 return STATUS_ERROR;
1183 else if (port->hba->krb_realm && strlen(port->hba->krb_realm))
1186 "GSSAPI did not return realm but realm matching was requested");
1188 gss_release_buffer(&lmin_s, &gbuf);
1189 return STATUS_ERROR;
1192 ret = check_usermap(port->hba->usermap, port->user_name, gbuf.value,
1193 pg_krb_caseins_users);
1195 gss_release_buffer(&lmin_s, &gbuf);
1199 #endif /* ENABLE_GSS */
1202 /*----------------------------------------------------------------
1203 * SSPI authentication system
1204 *----------------------------------------------------------------
1208 pg_SSPI_error(int severity, const char *errmsg, SECURITY_STATUS r)
1212 if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, r, 0,
1213 sysmsg, sizeof(sysmsg), NULL) == 0)
1215 (errmsg_internal("%s", errmsg),
1216 errdetail_internal("SSPI error %x", (unsigned int) r)));
1219 (errmsg_internal("%s", errmsg),
1220 errdetail_internal("%s (%x)", sysmsg, (unsigned int) r)));
1224 pg_SSPI_recvauth(Port *port)
1229 CredHandle sspicred;
1230 CtxtHandle *sspictx = NULL,
1234 SecBufferDesc inbuf;
1235 SecBufferDesc outbuf;
1236 SecBuffer OutBuffers[1];
1237 SecBuffer InBuffers[1];
1239 TOKEN_USER *tokenuser;
1241 char accountname[MAXPGPATH];
1242 char domainname[MAXPGPATH];
1243 DWORD accountnamesize = sizeof(accountname);
1244 DWORD domainnamesize = sizeof(domainname);
1245 SID_NAME_USE accountnameuse;
1247 QUERY_SECURITY_CONTEXT_TOKEN_FN _QuerySecurityContextToken;
1250 * SSPI auth is not supported for protocol versions before 3, because it
1251 * relies on the overall message length word to determine the SSPI payload
1252 * size in AuthenticationGSSContinue and PasswordMessage messages. (This
1253 * is, in fact, a design error in our SSPI support, because protocol
1254 * messages are supposed to be parsable without relying on the length
1255 * word; but it's not worth changing it now.)
1257 if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
1259 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1260 errmsg("SSPI is not supported in protocol version 2")));
1263 * Acquire a handle to the server credentials.
1265 r = AcquireCredentialsHandle(NULL,
1267 SECPKG_CRED_INBOUND,
1275 pg_SSPI_error(ERROR, _("could not acquire SSPI credentials"), r);
1278 * Loop through SSPI message exchange. This exchange can consist of
1279 * multiple messags sent in both directions. First message is always from
1280 * the client. All messages from client to server are password packets
1285 mtype = pq_getbyte();
1288 /* Only log error if client didn't disconnect. */
1291 (errcode(ERRCODE_PROTOCOL_VIOLATION),
1292 errmsg("expected SSPI response, got message type %d",
1294 return STATUS_ERROR;
1297 /* Get the actual SSPI token */
1298 initStringInfo(&buf);
1299 if (pq_getmessage(&buf, PG_MAX_AUTH_TOKEN_LENGTH))
1301 /* EOF - pq_getmessage already logged error */
1303 return STATUS_ERROR;
1306 /* Map to SSPI style buffer */
1307 inbuf.ulVersion = SECBUFFER_VERSION;
1309 inbuf.pBuffers = InBuffers;
1310 InBuffers[0].pvBuffer = buf.data;
1311 InBuffers[0].cbBuffer = buf.len;
1312 InBuffers[0].BufferType = SECBUFFER_TOKEN;
1314 /* Prepare output buffer */
1315 OutBuffers[0].pvBuffer = NULL;
1316 OutBuffers[0].BufferType = SECBUFFER_TOKEN;
1317 OutBuffers[0].cbBuffer = 0;
1318 outbuf.cBuffers = 1;
1319 outbuf.pBuffers = OutBuffers;
1320 outbuf.ulVersion = SECBUFFER_VERSION;
1323 elog(DEBUG4, "Processing received SSPI token of length %u",
1324 (unsigned int) buf.len);
1326 r = AcceptSecurityContext(&sspicred,
1329 ASC_REQ_ALLOCATE_MEMORY,
1330 SECURITY_NETWORK_DREP,
1336 /* input buffer no longer used */
1339 if (outbuf.cBuffers > 0 && outbuf.pBuffers[0].cbBuffer > 0)
1342 * Negotiation generated data to be sent to the client.
1344 elog(DEBUG4, "sending SSPI response token of length %u",
1345 (unsigned int) outbuf.pBuffers[0].cbBuffer);
1347 port->gss->outbuf.length = outbuf.pBuffers[0].cbBuffer;
1348 port->gss->outbuf.value = outbuf.pBuffers[0].pvBuffer;
1350 sendAuthRequest(port, AUTH_REQ_GSS_CONT);
1352 FreeContextBuffer(outbuf.pBuffers[0].pvBuffer);
1355 if (r != SEC_E_OK && r != SEC_I_CONTINUE_NEEDED)
1357 if (sspictx != NULL)
1359 DeleteSecurityContext(sspictx);
1362 FreeCredentialsHandle(&sspicred);
1363 pg_SSPI_error(ERROR,
1364 _("could not accept SSPI security context"), r);
1368 * Overwrite the current context with the one we just received.
1369 * If sspictx is NULL it was the first loop and we need to allocate
1370 * a buffer for it. On subsequent runs, we can just overwrite the
1371 * buffer contents since the size does not change.
1373 if (sspictx == NULL)
1375 sspictx = malloc(sizeof(CtxtHandle));
1376 if (sspictx == NULL)
1378 (errmsg("out of memory")));
1381 memcpy(sspictx, &newctx, sizeof(CtxtHandle));
1383 if (r == SEC_I_CONTINUE_NEEDED)
1384 elog(DEBUG4, "SSPI continue needed");
1386 } while (r == SEC_I_CONTINUE_NEEDED);
1390 * Release service principal credentials
1392 FreeCredentialsHandle(&sspicred);
1396 * SEC_E_OK indicates that authentication is now complete.
1398 * Get the name of the user that authenticated, and compare it to the pg
1399 * username that was specified for the connection.
1401 * MingW is missing the export for QuerySecurityContextToken in the
1402 * secur32 library, so we have to load it dynamically.
1405 secur32 = LoadLibrary("SECUR32.DLL");
1406 if (secur32 == NULL)
1408 (errmsg_internal("could not load secur32.dll: error code %lu",
1411 _QuerySecurityContextToken = (QUERY_SECURITY_CONTEXT_TOKEN_FN)
1412 GetProcAddress(secur32, "QuerySecurityContextToken");
1413 if (_QuerySecurityContextToken == NULL)
1415 FreeLibrary(secur32);
1417 (errmsg_internal("could not locate QuerySecurityContextToken in secur32.dll: error code %lu",
1421 r = (_QuerySecurityContextToken) (sspictx, &token);
1424 FreeLibrary(secur32);
1425 pg_SSPI_error(ERROR,
1426 _("could not get token from SSPI security context"), r);
1429 FreeLibrary(secur32);
1432 * No longer need the security context, everything from here on uses the
1435 DeleteSecurityContext(sspictx);
1438 if (!GetTokenInformation(token, TokenUser, NULL, 0, &retlen) && GetLastError() != 122)
1440 (errmsg_internal("could not get token user size: error code %lu",
1443 tokenuser = malloc(retlen);
1444 if (tokenuser == NULL)
1446 (errmsg("out of memory")));
1448 if (!GetTokenInformation(token, TokenUser, tokenuser, retlen, &retlen))
1450 (errmsg_internal("could not get user token: error code %lu",
1453 if (!LookupAccountSid(NULL, tokenuser->User.Sid, accountname, &accountnamesize,
1454 domainname, &domainnamesize, &accountnameuse))
1456 (errmsg_internal("could not look up account SID: error code %lu",
1462 * Compare realm/domain if requested. In SSPI, always compare case
1465 if (port->hba->krb_realm && strlen(port->hba->krb_realm))
1467 if (pg_strcasecmp(port->hba->krb_realm, domainname) != 0)
1470 "SSPI domain (%s) and configured domain (%s) don't match",
1471 domainname, port->hba->krb_realm);
1473 return STATUS_ERROR;
1478 * We have the username (without domain/realm) in accountname, compare to
1479 * the supplied value. In SSPI, always compare case insensitive.
1481 * If set to include realm, append it in <username>@<realm> format.
1483 if (port->hba->include_realm)
1488 namebuf = palloc(strlen(accountname) + strlen(domainname) + 2);
1489 sprintf(namebuf, "%s@%s", accountname, domainname);
1490 retval = check_usermap(port->hba->usermap, port->user_name, namebuf, true);
1495 return check_usermap(port->hba->usermap, port->user_name, accountname, true);
1497 #endif /* ENABLE_SSPI */
1501 /*----------------------------------------------------------------
1502 * Ident authentication system
1503 *----------------------------------------------------------------
1507 * Parse the string "*ident_response" as a response from a query to an Ident
1508 * server. If it's a normal response indicating a user name, return true
1509 * and store the user name at *ident_user. If it's anything else,
1513 interpret_ident_response(const char *ident_response,
1516 const char *cursor = ident_response; /* Cursor into *ident_response */
1519 * Ident's response, in the telnet tradition, should end in crlf (\r\n).
1521 if (strlen(ident_response) < 2)
1523 else if (ident_response[strlen(ident_response) - 2] != '\r')
1527 while (*cursor != ':' && *cursor != '\r')
1528 cursor++; /* skip port field */
1534 /* We're positioned to colon before response type field */
1535 char response_type[80];
1536 int i; /* Index into *response_type */
1538 cursor++; /* Go over colon */
1539 while (pg_isblank(*cursor))
1540 cursor++; /* skip blanks */
1542 while (*cursor != ':' && *cursor != '\r' && !pg_isblank(*cursor) &&
1543 i < (int) (sizeof(response_type) - 1))
1544 response_type[i++] = *cursor++;
1545 response_type[i] = '\0';
1546 while (pg_isblank(*cursor))
1547 cursor++; /* skip blanks */
1548 if (strcmp(response_type, "USERID") != 0)
1553 * It's a USERID response. Good. "cursor" should be pointing
1554 * to the colon that precedes the operating system type.
1560 cursor++; /* Go over colon */
1561 /* Skip over operating system field. */
1562 while (*cursor != ':' && *cursor != '\r')
1568 int i; /* Index into *ident_user */
1570 cursor++; /* Go over colon */
1571 while (pg_isblank(*cursor))
1572 cursor++; /* skip blanks */
1573 /* Rest of line is user name. Copy it over. */
1575 while (*cursor != '\r' && i < IDENT_USERNAME_MAX)
1576 ident_user[i++] = *cursor++;
1577 ident_user[i] = '\0';
1588 * Talk to the ident server on host "remote_ip_addr" and find out who
1589 * owns the tcp connection from his port "remote_port" to port
1590 * "local_port_addr" on host "local_ip_addr". Return the user name the
1591 * ident server gives as "*ident_user".
1593 * IP addresses and port numbers are in network byte order.
1595 * But iff we're unable to get the information from ident, return false.
1598 ident_inet(hbaPort *port)
1600 const SockAddr remote_addr = port->raddr;
1601 const SockAddr local_addr = port->laddr;
1602 char ident_user[IDENT_USERNAME_MAX + 1];
1603 pgsocket sock_fd, /* File descriptor for socket on which we talk
1605 rc; /* Return code from a locally called function */
1607 char remote_addr_s[NI_MAXHOST];
1608 char remote_port[NI_MAXSERV];
1609 char local_addr_s[NI_MAXHOST];
1610 char local_port[NI_MAXSERV];
1611 char ident_port[NI_MAXSERV];
1612 char ident_query[80];
1613 char ident_response[80 + IDENT_USERNAME_MAX];
1614 struct addrinfo *ident_serv = NULL,
1619 * Might look a little weird to first convert it to text and then back to
1620 * sockaddr, but it's protocol independent.
1622 pg_getnameinfo_all(&remote_addr.addr, remote_addr.salen,
1623 remote_addr_s, sizeof(remote_addr_s),
1624 remote_port, sizeof(remote_port),
1625 NI_NUMERICHOST | NI_NUMERICSERV);
1626 pg_getnameinfo_all(&local_addr.addr, local_addr.salen,
1627 local_addr_s, sizeof(local_addr_s),
1628 local_port, sizeof(local_port),
1629 NI_NUMERICHOST | NI_NUMERICSERV);
1631 snprintf(ident_port, sizeof(ident_port), "%d", IDENT_PORT);
1632 hints.ai_flags = AI_NUMERICHOST;
1633 hints.ai_family = remote_addr.addr.ss_family;
1634 hints.ai_socktype = SOCK_STREAM;
1635 hints.ai_protocol = 0;
1636 hints.ai_addrlen = 0;
1637 hints.ai_canonname = NULL;
1638 hints.ai_addr = NULL;
1639 hints.ai_next = NULL;
1640 rc = pg_getaddrinfo_all(remote_addr_s, ident_port, &hints, &ident_serv);
1641 if (rc || !ident_serv)
1644 pg_freeaddrinfo_all(hints.ai_family, ident_serv);
1645 return STATUS_ERROR; /* we don't expect this to happen */
1648 hints.ai_flags = AI_NUMERICHOST;
1649 hints.ai_family = local_addr.addr.ss_family;
1650 hints.ai_socktype = SOCK_STREAM;
1651 hints.ai_protocol = 0;
1652 hints.ai_addrlen = 0;
1653 hints.ai_canonname = NULL;
1654 hints.ai_addr = NULL;
1655 hints.ai_next = NULL;
1656 rc = pg_getaddrinfo_all(local_addr_s, NULL, &hints, &la);
1660 pg_freeaddrinfo_all(hints.ai_family, la);
1661 return STATUS_ERROR; /* we don't expect this to happen */
1664 sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
1665 ident_serv->ai_protocol);
1669 (errcode_for_socket_access(),
1670 errmsg("could not create socket for Ident connection: %m")));
1671 ident_return = false;
1672 goto ident_inet_done;
1676 * Bind to the address which the client originally contacted, otherwise
1677 * the ident server won't be able to match up the right connection. This
1678 * is necessary if the PostgreSQL server is running on an IP alias.
1680 rc = bind(sock_fd, la->ai_addr, la->ai_addrlen);
1684 (errcode_for_socket_access(),
1685 errmsg("could not bind to local address \"%s\": %m",
1687 ident_return = false;
1688 goto ident_inet_done;
1691 rc = connect(sock_fd, ident_serv->ai_addr,
1692 ident_serv->ai_addrlen);
1696 (errcode_for_socket_access(),
1697 errmsg("could not connect to Ident server at address \"%s\", port %s: %m",
1698 remote_addr_s, ident_port)));
1699 ident_return = false;
1700 goto ident_inet_done;
1703 /* The query we send to the Ident server */
1704 snprintf(ident_query, sizeof(ident_query), "%s,%s\r\n",
1705 remote_port, local_port);
1707 /* loop in case send is interrupted */
1710 rc = send(sock_fd, ident_query, strlen(ident_query), 0);
1711 } while (rc < 0 && errno == EINTR);
1716 (errcode_for_socket_access(),
1717 errmsg("could not send query to Ident server at address \"%s\", port %s: %m",
1718 remote_addr_s, ident_port)));
1719 ident_return = false;
1720 goto ident_inet_done;
1725 rc = recv(sock_fd, ident_response, sizeof(ident_response) - 1, 0);
1726 } while (rc < 0 && errno == EINTR);
1731 (errcode_for_socket_access(),
1732 errmsg("could not receive response from Ident server at address \"%s\", port %s: %m",
1733 remote_addr_s, ident_port)));
1734 ident_return = false;
1735 goto ident_inet_done;
1738 ident_response[rc] = '\0';
1739 ident_return = interpret_ident_response(ident_response, ident_user);
1742 (errmsg("invalidly formatted response from Ident server: \"%s\"",
1747 closesocket(sock_fd);
1748 pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
1749 pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
1752 /* Success! Check the usermap */
1753 return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
1754 return STATUS_ERROR;
1758 * Ask kernel about the credentials of the connecting process,
1759 * determine the symbolic name of the corresponding user, and check
1760 * if valid per the usermap.
1762 * Iff authorized, return STATUS_OK, otherwise return STATUS_ERROR.
1764 #ifdef HAVE_UNIX_SOCKETS
1767 auth_peer(hbaPort *port)
1769 char ident_user[IDENT_USERNAME_MAX + 1];
1772 struct passwd *pass;
1775 if (getpeereid(port->sock, &uid, &gid) != 0)
1777 /* Provide special error message if getpeereid is a stub */
1778 if (errno == ENOSYS)
1780 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1781 errmsg("peer authentication is not supported on this platform")));
1784 (errcode_for_socket_access(),
1785 errmsg("could not get peer credentials: %m")));
1786 return STATUS_ERROR;
1789 pass = getpwuid(uid);
1794 (errmsg("local user with ID %d does not exist",
1796 return STATUS_ERROR;
1799 strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
1801 return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
1803 #endif /* HAVE_UNIX_SOCKETS */
1806 /*----------------------------------------------------------------
1807 * PAM authentication system
1808 *----------------------------------------------------------------
1813 * PAM conversation function
1817 pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg,
1818 struct pam_response ** resp, void *appdata_ptr)
1821 struct pam_response *reply;
1825 passwd = (char *) appdata_ptr;
1829 * Workaround for Solaris 2.6 where the PAM library is broken and does
1830 * not pass appdata_ptr to the conversation routine
1832 passwd = pam_passwd;
1835 *resp = NULL; /* in case of error exit */
1837 if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG)
1838 return PAM_CONV_ERR;
1841 * Explicitly not using palloc here - PAM will free this memory in
1844 if ((reply = calloc(num_msg, sizeof(struct pam_response))) == NULL)
1847 (errcode(ERRCODE_OUT_OF_MEMORY),
1848 errmsg("out of memory")));
1849 return PAM_CONV_ERR;
1852 for (i = 0; i < num_msg; i++)
1854 switch (msg[i]->msg_style)
1856 case PAM_PROMPT_ECHO_OFF:
1857 if (strlen(passwd) == 0)
1860 * Password wasn't passed to PAM the first time around -
1861 * let's go ask the client to send a password, which we
1862 * then stuff into PAM.
1864 sendAuthRequest(pam_port_cludge, AUTH_REQ_PASSWORD);
1865 passwd = recv_password_packet(pam_port_cludge);
1869 * Client didn't want to send password. We
1870 * intentionally do not log anything about this.
1874 if (strlen(passwd) == 0)
1877 (errmsg("empty password returned by client")));
1881 if ((reply[i].resp = strdup(passwd)) == NULL)
1883 reply[i].resp_retcode = PAM_SUCCESS;
1887 (errmsg("error from underlying PAM layer: %s",
1891 /* we don't bother to log TEXT_INFO messages */
1892 if ((reply[i].resp = strdup("")) == NULL)
1894 reply[i].resp_retcode = PAM_SUCCESS;
1897 elog(LOG, "unsupported PAM conversation %d/\"%s\"",
1899 msg[i]->msg ? msg[i]->msg : "(none)");
1908 /* free up whatever we allocated */
1909 for (i = 0; i < num_msg; i++)
1911 if (reply[i].resp != NULL)
1912 free(reply[i].resp);
1916 return PAM_CONV_ERR;
1921 * Check authentication against PAM.
1924 CheckPAMAuth(Port *port, char *user, char *password)
1927 pam_handle_t *pamh = NULL;
1930 * We can't entirely rely on PAM to pass through appdata --- it appears
1931 * not to work on at least Solaris 2.6. So use these ugly static
1932 * variables instead.
1934 pam_passwd = password;
1935 pam_port_cludge = port;
1938 * Set the application data portion of the conversation struct This is
1939 * later used inside the PAM conversation to pass the password to the
1940 * authentication module.
1942 pam_passw_conv.appdata_ptr = (char *) password; /* from password above,
1945 /* Optionally, one can set the service name in pg_hba.conf */
1946 if (port->hba->pamservice && port->hba->pamservice[0] != '\0')
1947 retval = pam_start(port->hba->pamservice, "pgsql@",
1948 &pam_passw_conv, &pamh);
1950 retval = pam_start(PGSQL_PAM_SERVICE, "pgsql@",
1951 &pam_passw_conv, &pamh);
1953 if (retval != PAM_SUCCESS)
1956 (errmsg("could not create PAM authenticator: %s",
1957 pam_strerror(pamh, retval))));
1958 pam_passwd = NULL; /* Unset pam_passwd */
1959 return STATUS_ERROR;
1962 retval = pam_set_item(pamh, PAM_USER, user);
1964 if (retval != PAM_SUCCESS)
1967 (errmsg("pam_set_item(PAM_USER) failed: %s",
1968 pam_strerror(pamh, retval))));
1969 pam_passwd = NULL; /* Unset pam_passwd */
1970 return STATUS_ERROR;
1973 retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv);
1975 if (retval != PAM_SUCCESS)
1978 (errmsg("pam_set_item(PAM_CONV) failed: %s",
1979 pam_strerror(pamh, retval))));
1980 pam_passwd = NULL; /* Unset pam_passwd */
1981 return STATUS_ERROR;
1984 retval = pam_authenticate(pamh, 0);
1986 if (retval != PAM_SUCCESS)
1989 (errmsg("pam_authenticate failed: %s",
1990 pam_strerror(pamh, retval))));
1991 pam_passwd = NULL; /* Unset pam_passwd */
1992 return STATUS_ERROR;
1995 retval = pam_acct_mgmt(pamh, 0);
1997 if (retval != PAM_SUCCESS)
2000 (errmsg("pam_acct_mgmt failed: %s",
2001 pam_strerror(pamh, retval))));
2002 pam_passwd = NULL; /* Unset pam_passwd */
2003 return STATUS_ERROR;
2006 retval = pam_end(pamh, retval);
2008 if (retval != PAM_SUCCESS)
2011 (errmsg("could not release PAM authenticator: %s",
2012 pam_strerror(pamh, retval))));
2015 pam_passwd = NULL; /* Unset pam_passwd */
2017 return (retval == PAM_SUCCESS ? STATUS_OK : STATUS_ERROR);
2019 #endif /* USE_PAM */
2023 /*----------------------------------------------------------------
2024 * LDAP authentication system
2025 *----------------------------------------------------------------
2030 * Initialize a connection to the LDAP server, including setting up
2034 InitializeLDAPConnection(Port *port, LDAP **ldap)
2036 int ldapversion = LDAP_VERSION3;
2039 *ldap = ldap_init(port->hba->ldapserver, port->hba->ldapport);
2044 (errmsg("could not initialize LDAP: error code %d",
2048 (errmsg("could not initialize LDAP: error code %d",
2049 (int) LdapGetLastError())));
2051 return STATUS_ERROR;
2054 if ((r = ldap_set_option(*ldap, LDAP_OPT_PROTOCOL_VERSION, &ldapversion)) != LDAP_SUCCESS)
2058 (errmsg("could not set LDAP protocol version: error code %d", r)));
2059 return STATUS_ERROR;
2062 if (port->hba->ldaptls)
2065 if ((r = ldap_start_tls_s(*ldap, NULL, NULL)) != LDAP_SUCCESS)
2067 static __ldap_start_tls_sA _ldap_start_tls_sA = NULL;
2069 if (_ldap_start_tls_sA == NULL)
2072 * Need to load this function dynamically because it does not
2073 * exist on Windows 2000, and causes a load error for the whole
2074 * exe if referenced.
2078 ldaphandle = LoadLibrary("WLDAP32.DLL");
2079 if (ldaphandle == NULL)
2082 * should never happen since we import other files from
2083 * wldap32, but check anyway
2087 (errmsg("could not load wldap32.dll")));
2088 return STATUS_ERROR;
2090 _ldap_start_tls_sA = (__ldap_start_tls_sA) GetProcAddress(ldaphandle, "ldap_start_tls_sA");
2091 if (_ldap_start_tls_sA == NULL)
2095 (errmsg("could not load function _ldap_start_tls_sA in wldap32.dll"),
2096 errdetail("LDAP over SSL is not supported on this platform.")));
2097 return STATUS_ERROR;
2101 * Leak LDAP handle on purpose, because we need the library to
2102 * stay open. This is ok because it will only ever be leaked once
2103 * per process and is automatically cleaned up on process exit.
2106 if ((r = _ldap_start_tls_sA(*ldap, NULL, NULL, NULL, NULL)) != LDAP_SUCCESS)
2111 (errmsg("could not start LDAP TLS session: error code %d", r)));
2112 return STATUS_ERROR;
2120 * Perform LDAP authentication
2123 CheckLDAPAuth(Port *port)
2130 if (!port->hba->ldapserver || port->hba->ldapserver[0] == '\0')
2133 (errmsg("LDAP server not specified")));
2134 return STATUS_ERROR;
2137 if (port->hba->ldapport == 0)
2138 port->hba->ldapport = LDAP_PORT;
2140 sendAuthRequest(port, AUTH_REQ_PASSWORD);
2142 passwd = recv_password_packet(port);
2144 return STATUS_EOF; /* client wouldn't send password */
2146 if (strlen(passwd) == 0)
2149 (errmsg("empty password returned by client")));
2150 return STATUS_ERROR;
2153 if (InitializeLDAPConnection(port, &ldap) == STATUS_ERROR)
2154 /* Error message already sent */
2155 return STATUS_ERROR;
2157 if (port->hba->ldapbasedn)
2160 * First perform an LDAP search to find the DN for the user we are
2161 * trying to log in as.
2164 LDAPMessage *search_message;
2166 char *attributes[2];
2171 * Disallow any characters that we would otherwise need to escape,
2172 * since they aren't really reasonable in a username anyway. Allowing
2173 * them would make it possible to inject any kind of custom filters in
2176 for (c = port->user_name; *c; c++)
2185 (errmsg("invalid character in user name for LDAP authentication")));
2186 return STATUS_ERROR;
2191 * Bind with a pre-defined username/password (if available) for
2192 * searching. If none is specified, this turns into an anonymous bind.
2194 r = ldap_simple_bind_s(ldap,
2195 port->hba->ldapbinddn ? port->hba->ldapbinddn : "",
2196 port->hba->ldapbindpasswd ? port->hba->ldapbindpasswd : "");
2197 if (r != LDAP_SUCCESS)
2200 (errmsg("could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": error code %d",
2201 port->hba->ldapbinddn, port->hba->ldapserver, r)));
2202 return STATUS_ERROR;
2205 /* Fetch just one attribute, else *all* attributes are returned */
2206 attributes[0] = port->hba->ldapsearchattribute ? port->hba->ldapsearchattribute : "uid";
2207 attributes[1] = NULL;
2209 filter = palloc(strlen(attributes[0]) + strlen(port->user_name) + 4);
2210 sprintf(filter, "(%s=%s)",
2214 r = ldap_search_s(ldap,
2215 port->hba->ldapbasedn,
2222 if (r != LDAP_SUCCESS)
2225 (errmsg("could not search LDAP for filter \"%s\" on server \"%s\": error code %d",
2226 filter, port->hba->ldapserver, r)));
2228 return STATUS_ERROR;
2231 if (ldap_count_entries(ldap, search_message) != 1)
2233 if (ldap_count_entries(ldap, search_message) == 0)
2235 (errmsg("LDAP search failed for filter \"%s\" on server \"%s\": no such user",
2236 filter, port->hba->ldapserver)));
2239 (errmsg("LDAP search failed for filter \"%s\" on server \"%s\": user is not unique (%ld matches)",
2240 filter, port->hba->ldapserver,
2241 (long) ldap_count_entries(ldap, search_message))));
2244 ldap_msgfree(search_message);
2245 return STATUS_ERROR;
2248 entry = ldap_first_entry(ldap, search_message);
2249 dn = ldap_get_dn(ldap, entry);
2254 (void) ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &error);
2256 (errmsg("could not get dn for the first entry matching \"%s\" on server \"%s\": %s",
2257 filter, port->hba->ldapserver, ldap_err2string(error))));
2259 ldap_msgfree(search_message);
2260 return STATUS_ERROR;
2262 fulluser = pstrdup(dn);
2266 ldap_msgfree(search_message);
2268 /* Unbind and disconnect from the LDAP server */
2269 r = ldap_unbind_s(ldap);
2270 if (r != LDAP_SUCCESS)
2274 (void) ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &error);
2276 (errmsg("could not unbind after searching for user \"%s\" on server \"%s\": %s",
2277 fulluser, port->hba->ldapserver, ldap_err2string(error))));
2279 return STATUS_ERROR;
2283 * Need to re-initialize the LDAP connection, so that we can bind to
2284 * it with a different username.
2286 if (InitializeLDAPConnection(port, &ldap) == STATUS_ERROR)
2290 /* Error message already sent */
2291 return STATUS_ERROR;
2296 fulluser = palloc((port->hba->ldapprefix ? strlen(port->hba->ldapprefix) : 0) +
2297 strlen(port->user_name) +
2298 (port->hba->ldapsuffix ? strlen(port->hba->ldapsuffix) : 0) +
2301 sprintf(fulluser, "%s%s%s",
2302 port->hba->ldapprefix ? port->hba->ldapprefix : "",
2304 port->hba->ldapsuffix ? port->hba->ldapsuffix : "");
2307 r = ldap_simple_bind_s(ldap, fulluser, passwd);
2310 if (r != LDAP_SUCCESS)
2313 (errmsg("LDAP login failed for user \"%s\" on server \"%s\": error code %d",
2314 fulluser, port->hba->ldapserver, r)));
2316 return STATUS_ERROR;
2323 #endif /* USE_LDAP */
2326 /*----------------------------------------------------------------
2327 * SSL client certificate authentication
2328 *----------------------------------------------------------------
2332 CheckCertAuth(Port *port)
2336 /* Make sure we have received a username in the certificate */
2337 if (port->peer_cn == NULL ||
2338 strlen(port->peer_cn) <= 0)
2341 (errmsg("certificate authentication failed for user \"%s\": client certificate contains no user name",
2343 return STATUS_ERROR;
2346 /* Just pass the certificate CN to the usermap check */
2347 return check_usermap(port->hba->usermap, port->user_name, port->peer_cn, false);
2352 /*----------------------------------------------------------------
2353 * RADIUS authentication
2354 *----------------------------------------------------------------
2358 * RADIUS authentication is described in RFC2865 (and several
2362 #define RADIUS_VECTOR_LENGTH 16
2363 #define RADIUS_HEADER_LENGTH 20
2377 uint8 vector[RADIUS_VECTOR_LENGTH];
2380 /* RADIUS packet types */
2381 #define RADIUS_ACCESS_REQUEST 1
2382 #define RADIUS_ACCESS_ACCEPT 2
2383 #define RADIUS_ACCESS_REJECT 3
2385 /* RAIDUS attributes */
2386 #define RADIUS_USER_NAME 1
2387 #define RADIUS_PASSWORD 2
2388 #define RADIUS_SERVICE_TYPE 6
2389 #define RADIUS_NAS_IDENTIFIER 32
2391 /* RADIUS service types */
2392 #define RADIUS_AUTHENTICATE_ONLY 8
2394 /* Maximum size of a RADIUS packet we will create or accept */
2395 #define RADIUS_BUFFER_SIZE 1024
2397 /* Seconds to wait - XXX: should be in a config variable! */
2398 #define RADIUS_TIMEOUT 3
2401 radius_add_attribute(radius_packet *packet, uint8 type, const unsigned char *data, int len)
2403 radius_attribute *attr;
2405 if (packet->length + len > RADIUS_BUFFER_SIZE)
2408 * With remotely realistic data, this can never happen. But catch it
2409 * just to make sure we don't overrun a buffer. We'll just skip adding
2410 * the broken attribute, which will in the end cause authentication to
2414 "Adding attribute code %d with length %d to radius packet would create oversize packet, ignoring",
2420 attr = (radius_attribute *) ((unsigned char *) packet + packet->length);
2421 attr->attribute = type;
2422 attr->length = len + 2; /* total size includes type and length */
2423 memcpy(attr->data, data, len);
2424 packet->length += attr->length;
2428 CheckRADIUSAuth(Port *port)
2431 char *identifier = "postgresql";
2432 char radius_buffer[RADIUS_BUFFER_SIZE];
2433 char receive_buffer[RADIUS_BUFFER_SIZE];
2434 radius_packet *packet = (radius_packet *) radius_buffer;
2435 radius_packet *receivepacket = (radius_packet *) receive_buffer;
2436 int32 service = htonl(RADIUS_AUTHENTICATE_ONLY);
2438 uint8 encryptedpassword[RADIUS_VECTOR_LENGTH];
2443 struct sockaddr_in6 localaddr;
2444 struct sockaddr_in6 remoteaddr;
2446 struct sockaddr_in localaddr;
2447 struct sockaddr_in remoteaddr;
2449 struct addrinfo hint;
2450 struct addrinfo *serveraddrs;
2452 ACCEPT_TYPE_ARG3 addrsize;
2454 struct timeval endtime;
2458 /* Make sure struct alignment is correct */
2459 Assert(offsetof(radius_packet, vector) == 4);
2461 /* Verify parameters */
2462 if (!port->hba->radiusserver || port->hba->radiusserver[0] == '\0')
2465 (errmsg("RADIUS server not specified")));
2466 return STATUS_ERROR;
2469 if (!port->hba->radiussecret || port->hba->radiussecret[0] == '\0')
2472 (errmsg("RADIUS secret not specified")));
2473 return STATUS_ERROR;
2476 if (port->hba->radiusport == 0)
2477 port->hba->radiusport = 1812;
2479 MemSet(&hint, 0, sizeof(hint));
2480 hint.ai_socktype = SOCK_DGRAM;
2481 hint.ai_family = AF_UNSPEC;
2482 snprintf(portstr, sizeof(portstr), "%d", port->hba->radiusport);
2484 r = pg_getaddrinfo_all(port->hba->radiusserver, portstr, &hint, &serveraddrs);
2485 if (r || !serveraddrs)
2488 (errmsg("could not translate RADIUS server name \"%s\" to address: %s",
2489 port->hba->radiusserver, gai_strerror(r))));
2491 pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
2492 return STATUS_ERROR;
2494 /* XXX: add support for multiple returned addresses? */
2496 if (port->hba->radiusidentifier && port->hba->radiusidentifier[0])
2497 identifier = port->hba->radiusidentifier;
2499 /* Send regular password request to client, and get the response */
2500 sendAuthRequest(port, AUTH_REQ_PASSWORD);
2502 passwd = recv_password_packet(port);
2504 return STATUS_EOF; /* client wouldn't send password */
2506 if (strlen(passwd) == 0)
2509 (errmsg("empty password returned by client")));
2510 return STATUS_ERROR;
2513 if (strlen(passwd) > RADIUS_VECTOR_LENGTH)
2516 (errmsg("RADIUS authentication does not support passwords longer than 16 characters")));
2517 return STATUS_ERROR;
2520 /* Construct RADIUS packet */
2521 packet->code = RADIUS_ACCESS_REQUEST;
2522 packet->length = RADIUS_HEADER_LENGTH;
2524 if (RAND_bytes(packet->vector, RADIUS_VECTOR_LENGTH) != 1)
2527 (errmsg("could not generate random encryption vector")));
2528 return STATUS_ERROR;
2531 for (i = 0; i < RADIUS_VECTOR_LENGTH; i++)
2532 /* Use a lower strengh random number of OpenSSL is not available */
2533 packet->vector[i] = random() % 255;
2535 packet->id = packet->vector[0];
2536 radius_add_attribute(packet, RADIUS_SERVICE_TYPE, (unsigned char *) &service, sizeof(service));
2537 radius_add_attribute(packet, RADIUS_USER_NAME, (unsigned char *) port->user_name, strlen(port->user_name));
2538 radius_add_attribute(packet, RADIUS_NAS_IDENTIFIER, (unsigned char *) identifier, strlen(identifier));
2541 * RADIUS password attributes are calculated as: e[0] = p[0] XOR
2542 * MD5(secret + vector)
2544 cryptvector = palloc(RADIUS_VECTOR_LENGTH + strlen(port->hba->radiussecret));
2545 memcpy(cryptvector, port->hba->radiussecret, strlen(port->hba->radiussecret));
2546 memcpy(cryptvector + strlen(port->hba->radiussecret), packet->vector, RADIUS_VECTOR_LENGTH);
2547 if (!pg_md5_binary(cryptvector, RADIUS_VECTOR_LENGTH + strlen(port->hba->radiussecret), encryptedpassword))
2550 (errmsg("could not perform MD5 encryption of password")));
2552 return STATUS_ERROR;
2555 for (i = 0; i < RADIUS_VECTOR_LENGTH; i++)
2557 if (i < strlen(passwd))
2558 encryptedpassword[i] = passwd[i] ^ encryptedpassword[i];
2560 encryptedpassword[i] = '\0' ^ encryptedpassword[i];
2562 radius_add_attribute(packet, RADIUS_PASSWORD, encryptedpassword, RADIUS_VECTOR_LENGTH);
2564 /* Length need to be in network order on the wire */
2565 packetlength = packet->length;
2566 packet->length = htons(packet->length);
2568 sock = socket(serveraddrs[0].ai_family, SOCK_DGRAM, 0);
2572 (errmsg("could not create RADIUS socket: %m")));
2573 pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
2574 return STATUS_ERROR;
2577 memset(&localaddr, 0, sizeof(localaddr));
2579 localaddr.sin6_family = serveraddrs[0].ai_family;
2580 localaddr.sin6_addr = in6addr_any;
2581 if (localaddr.sin6_family == AF_INET6)
2582 addrsize = sizeof(struct sockaddr_in6);
2584 addrsize = sizeof(struct sockaddr_in);
2586 localaddr.sin_family = serveraddrs[0].ai_family;
2587 localaddr.sin_addr.s_addr = INADDR_ANY;
2588 addrsize = sizeof(struct sockaddr_in);
2590 if (bind(sock, (struct sockaddr *) & localaddr, addrsize))
2593 (errmsg("could not bind local RADIUS socket: %m")));
2595 pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
2596 return STATUS_ERROR;
2599 if (sendto(sock, radius_buffer, packetlength, 0,
2600 serveraddrs[0].ai_addr, serveraddrs[0].ai_addrlen) < 0)
2603 (errmsg("could not send RADIUS packet: %m")));
2605 pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
2606 return STATUS_ERROR;
2609 /* Don't need the server address anymore */
2610 pg_freeaddrinfo_all(hint.ai_family, serveraddrs);
2613 * Figure out at what time we should time out. We can't just use a single
2614 * call to select() with a timeout, since somebody can be sending invalid
2615 * packets to our port thus causing us to retry in a loop and never time
2618 gettimeofday(&endtime, NULL);
2619 endtime.tv_sec += RADIUS_TIMEOUT;
2623 struct timeval timeout;
2627 gettimeofday(&now, NULL);
2628 timeoutval = (endtime.tv_sec * 1000000 + endtime.tv_usec) - (now.tv_sec * 1000000 + now.tv_usec);
2629 if (timeoutval <= 0)
2632 (errmsg("timeout waiting for RADIUS response")));
2634 return STATUS_ERROR;
2636 timeout.tv_sec = timeoutval / 1000000;
2637 timeout.tv_usec = timeoutval % 1000000;
2640 FD_SET(sock, &fdset);
2642 r = select(sock + 1, &fdset, NULL, NULL, &timeout);
2648 /* Anything else is an actual error */
2650 (errmsg("could not check status on RADIUS socket: %m")));
2652 return STATUS_ERROR;
2657 (errmsg("timeout waiting for RADIUS response")));
2659 return STATUS_ERROR;
2663 * Attempt to read the response packet, and verify the contents.
2665 * Any packet that's not actually a RADIUS packet, or otherwise does
2666 * not validate as an explicit reject, is just ignored and we retry
2667 * for another packet (until we reach the timeout). This is to avoid
2668 * the possibility to denial-of-service the login by flooding the
2669 * server with invalid packets on the port that we're expecting the
2670 * RADIUS response on.
2673 addrsize = sizeof(remoteaddr);
2674 packetlength = recvfrom(sock, receive_buffer, RADIUS_BUFFER_SIZE, 0,
2675 (struct sockaddr *) & remoteaddr, &addrsize);
2676 if (packetlength < 0)
2679 (errmsg("could not read RADIUS response: %m")));
2680 return STATUS_ERROR;
2684 if (remoteaddr.sin6_port != htons(port->hba->radiusport))
2686 if (remoteaddr.sin_port != htons(port->hba->radiusport))
2691 (errmsg("RADIUS response was sent from incorrect port: %d",
2692 ntohs(remoteaddr.sin6_port))));
2695 (errmsg("RADIUS response was sent from incorrect port: %d",
2696 ntohs(remoteaddr.sin_port))));
2701 if (packetlength < RADIUS_HEADER_LENGTH)
2704 (errmsg("RADIUS response too short: %d", packetlength)));
2708 if (packetlength != ntohs(receivepacket->length))
2711 (errmsg("RADIUS response has corrupt length: %d (actual length %d)",
2712 ntohs(receivepacket->length), packetlength)));
2716 if (packet->id != receivepacket->id)
2719 (errmsg("RADIUS response is to a different request: %d (should be %d)",
2720 receivepacket->id, packet->id)));
2725 * Verify the response authenticator, which is calculated as
2726 * MD5(Code+ID+Length+RequestAuthenticator+Attributes+Secret)
2728 cryptvector = palloc(packetlength + strlen(port->hba->radiussecret));
2730 memcpy(cryptvector, receivepacket, 4); /* code+id+length */
2731 memcpy(cryptvector + 4, packet->vector, RADIUS_VECTOR_LENGTH); /* request
2732 * authenticator, from
2733 * original packet */
2734 if (packetlength > RADIUS_HEADER_LENGTH) /* there may be no
2735 * attributes at all */
2736 memcpy(cryptvector + RADIUS_HEADER_LENGTH, receive_buffer + RADIUS_HEADER_LENGTH, packetlength - RADIUS_HEADER_LENGTH);
2737 memcpy(cryptvector + packetlength, port->hba->radiussecret, strlen(port->hba->radiussecret));
2739 if (!pg_md5_binary(cryptvector,
2740 packetlength + strlen(port->hba->radiussecret),
2744 (errmsg("could not perform MD5 encryption of received packet")));
2750 if (memcmp(receivepacket->vector, encryptedpassword, RADIUS_VECTOR_LENGTH) != 0)
2753 (errmsg("RADIUS response has incorrect MD5 signature")));
2757 if (receivepacket->code == RADIUS_ACCESS_ACCEPT)
2762 else if (receivepacket->code == RADIUS_ACCESS_REJECT)
2765 return STATUS_ERROR;
2770 (errmsg("RADIUS response has invalid code (%d) for user \"%s\"",
2771 receivepacket->code, port->user_name)));
2774 } /* while (true) */