diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/catalog/system_views.sql | 3 | ||||
-rw-r--r-- | src/backend/foreign/foreign.c | 1 | ||||
-rw-r--r-- | src/backend/libpq/auth.c | 13 | ||||
-rw-r--r-- | src/backend/libpq/be-gssapi-common.c | 53 | ||||
-rw-r--r-- | src/backend/libpq/be-secure-gssapi.c | 26 | ||||
-rw-r--r-- | src/backend/utils/activity/backend_status.c | 1 | ||||
-rw-r--r-- | src/backend/utils/adt/pgstatfuncs.c | 21 | ||||
-rw-r--r-- | src/backend/utils/init/postinit.c | 8 | ||||
-rw-r--r-- | src/backend/utils/misc/guc_tables.c | 10 | ||||
-rw-r--r-- | src/backend/utils/misc/postgresql.conf.sample | 1 |
10 files changed, 123 insertions, 14 deletions
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 41aafe0b875..c123f109896 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -979,7 +979,8 @@ CREATE VIEW pg_stat_gssapi AS S.pid, S.gss_auth AS gss_authenticated, S.gss_princ AS principal, - S.gss_enc AS encrypted + S.gss_enc AS encrypted, + S.gss_deleg AS credentials_delegated FROM pg_stat_get_activity(NULL) AS S WHERE S.client_port IS NOT NULL; diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c index dca02271dc9..6e1977fa620 100644 --- a/src/backend/foreign/foreign.c +++ b/src/backend/foreign/foreign.c @@ -574,6 +574,7 @@ static const struct ConnectionOption libpq_conninfo_options[] = { {"requiressl", ForeignServerRelationId}, {"sslmode", ForeignServerRelationId}, {"gsslib", ForeignServerRelationId}, + {"gssdeleg", ForeignServerRelationId}, {NULL, InvalidOid} }; diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index bc0cf26b122..00ec9da284b 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -165,6 +165,7 @@ static int CheckCertAuth(Port *port); */ char *pg_krb_server_keyfile; bool pg_krb_caseins_users; +bool pg_gss_accept_deleg; /*---------------------------------------------------------------- @@ -918,6 +919,7 @@ pg_GSS_recvauth(Port *port) int mtype; StringInfoData buf; gss_buffer_desc gbuf; + gss_cred_id_t delegated_creds; /* * Use the configured keytab, if there is one. Unfortunately, Heimdal @@ -947,6 +949,9 @@ pg_GSS_recvauth(Port *port) */ port->gss->ctx = GSS_C_NO_CONTEXT; + delegated_creds = GSS_C_NO_CREDENTIAL; + port->gss->delegated_creds = false; + /* * Loop through GSSAPI message exchange. This exchange can consist of * multiple messages sent in both directions. First message is always from @@ -997,7 +1002,7 @@ pg_GSS_recvauth(Port *port) &port->gss->outbuf, &gflags, NULL, - NULL); + pg_gss_accept_deleg ? &delegated_creds : NULL); /* gbuf no longer used */ pfree(buf.data); @@ -1009,6 +1014,12 @@ pg_GSS_recvauth(Port *port) CHECK_FOR_INTERRUPTS(); + if (delegated_creds != GSS_C_NO_CREDENTIAL && gflags & GSS_C_DELEG_FLAG) + { + pg_store_delegated_credential(delegated_creds); + port->gss->delegated_creds = true; + } + if (port->gss->outbuf.length != 0) { /* diff --git a/src/backend/libpq/be-gssapi-common.c b/src/backend/libpq/be-gssapi-common.c index fb39c760d8c..64d41e52915 100644 --- a/src/backend/libpq/be-gssapi-common.c +++ b/src/backend/libpq/be-gssapi-common.c @@ -92,3 +92,56 @@ pg_GSS_error(const char *errmsg, (errmsg_internal("%s", errmsg), errdetail_internal("%s: %s", msg_major, msg_minor))); } + +/* + * Store the credentials passed in into the memory cache for later usage. + * + * This allows credentials to be delegated to us for us to use to connect + * to other systems with, using, e.g. postgres_fdw or dblink. + */ +#define GSS_MEMORY_CACHE "MEMORY:" +void +pg_store_delegated_credential(gss_cred_id_t cred) +{ + OM_uint32 major, + minor; + gss_OID_set mech; + gss_cred_usage_t usage; + gss_key_value_element_desc cc; + gss_key_value_set_desc ccset; + + cc.key = "ccache"; + cc.value = GSS_MEMORY_CACHE; + ccset.count = 1; + ccset.elements = &cc; + + /* Make the delegated credential only available to current process */ + major = gss_store_cred_into(&minor, + cred, + GSS_C_INITIATE, /* credential only used for + * starting libpq connection */ + GSS_C_NULL_OID, /* store all */ + true, /* overwrite */ + true, /* make default */ + &ccset, + &mech, + &usage); + + if (major != GSS_S_COMPLETE) + { + pg_GSS_error("gss_store_cred", major, minor); + } + + /* Credential stored, so we can release our credential handle. */ + major = gss_release_cred(&minor, &cred); + if (major != GSS_S_COMPLETE) + { + pg_GSS_error("gss_release_cred", major, minor); + } + + /* + * Set KRB5CCNAME for this backend, so that later calls to + * gss_acquire_cred will find the delegated credentials we stored. + */ + setenv("KRB5CCNAME", GSS_MEMORY_CACHE, 1); +} diff --git a/src/backend/libpq/be-secure-gssapi.c b/src/backend/libpq/be-secure-gssapi.c index 3b55f431999..73f8ce85549 100644 --- a/src/backend/libpq/be-secure-gssapi.c +++ b/src/backend/libpq/be-secure-gssapi.c @@ -497,6 +497,7 @@ secure_open_gssapi(Port *port) bool complete_next = false; OM_uint32 major, minor; + gss_cred_id_t delegated_creds; /* * Allocate subsidiary Port data for GSSAPI operations. @@ -504,6 +505,9 @@ secure_open_gssapi(Port *port) port->gss = (pg_gssinfo *) MemoryContextAllocZero(TopMemoryContext, sizeof(pg_gssinfo)); + delegated_creds = GSS_C_NO_CREDENTIAL; + port->gss->delegated_creds = false; + /* * Allocate buffers and initialize state variables. By malloc'ing the * buffers at this point, we avoid wasting static data space in processes @@ -588,7 +592,8 @@ secure_open_gssapi(Port *port) GSS_C_NO_CREDENTIAL, &input, GSS_C_NO_CHANNEL_BINDINGS, &port->gss->name, NULL, &output, NULL, - NULL, NULL); + NULL, pg_gss_accept_deleg ? &delegated_creds : NULL); + if (GSS_ERROR(major)) { pg_GSS_error(_("could not accept GSSAPI security context"), @@ -605,6 +610,12 @@ secure_open_gssapi(Port *port) complete_next = true; } + if (delegated_creds != GSS_C_NO_CREDENTIAL) + { + pg_store_delegated_credential(delegated_creds); + port->gss->delegated_creds = true; + } + /* Done handling the incoming packet, reset our buffer */ PqGSSRecvLength = 0; @@ -731,3 +742,16 @@ be_gssapi_get_princ(Port *port) return port->gss->princ; } + +/* + * Return if GSSAPI delegated credentials were included on this + * connection. + */ +bool +be_gssapi_get_deleg(Port *port) +{ + if (!port || !port->gss) + return NULL; + + return port->gss->delegated_creds; +} diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c index 608d01ea0dd..391d5de0435 100644 --- a/src/backend/utils/activity/backend_status.c +++ b/src/backend/utils/activity/backend_status.c @@ -384,6 +384,7 @@ pgstat_bestart(void) lbeentry.st_gss = true; lgssstatus.gss_auth = be_gssapi_get_auth(MyProcPort); lgssstatus.gss_enc = be_gssapi_get_enc(MyProcPort); + lgssstatus.gss_deleg = be_gssapi_get_deleg(MyProcPort); if (princ) strlcpy(lgssstatus.gss_princ, princ, NAMEDATALEN); } diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 840e9ad86c7..6b3c464db83 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -303,7 +303,7 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS) Datum pg_stat_get_activity(PG_FUNCTION_ARGS) { -#define PG_STAT_GET_ACTIVITY_COLS 30 +#define PG_STAT_GET_ACTIVITY_COLS 31 int num_backends = pgstat_fetch_stat_numbackends(); int curr_backend; int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0); @@ -395,7 +395,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) pfree(clipped_activity); /* leader_pid */ - nulls[28] = true; + nulls[29] = true; proc = BackendPidGetProc(beentry->st_procpid); @@ -432,8 +432,8 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) */ if (leader && leader->pid != beentry->st_procpid) { - values[28] = Int32GetDatum(leader->pid); - nulls[28] = false; + values[29] = Int32GetDatum(leader->pid); + nulls[29] = false; } else if (beentry->st_backendType == B_BG_WORKER) { @@ -441,8 +441,8 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) if (leader_pid != InvalidPid) { - values[28] = Int32GetDatum(leader_pid); - nulls[28] = false; + values[29] = Int32GetDatum(leader_pid); + nulls[29] = false; } } } @@ -600,6 +600,8 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) values[25] = BoolGetDatum(beentry->st_gssstatus->gss_auth); /* gss_auth */ values[26] = CStringGetTextDatum(beentry->st_gssstatus->gss_princ); values[27] = BoolGetDatum(beentry->st_gssstatus->gss_enc); /* GSS Encryption in use */ + values[28] = BoolGetDatum(beentry->st_gssstatus->gss_deleg); /* GSS credentials + * delegated */ } else { @@ -607,11 +609,13 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) nulls[26] = true; /* No GSS principal */ values[27] = BoolGetDatum(false); /* GSS Encryption not in * use */ + values[28] = BoolGetDatum(false); /* GSS credentials not + * delegated */ } if (beentry->st_query_id == 0) - nulls[29] = true; + nulls[30] = true; else - values[29] = UInt64GetDatum(beentry->st_query_id); + values[30] = UInt64GetDatum(beentry->st_query_id); } else { @@ -640,6 +644,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) nulls[27] = true; nulls[28] = true; nulls[29] = true; + nulls[30] = true; } tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 60feae0f1b1..5af87a78683 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -282,15 +282,17 @@ PerformAuthentication(Port *port) if (princ) appendStringInfo(&logmsg, - _(" GSS (authenticated=%s, encrypted=%s, principal=%s)"), + _(" GSS (authenticated=%s, encrypted=%s, deleg_credentials=%s, principal=%s)"), be_gssapi_get_auth(port) ? _("yes") : _("no"), be_gssapi_get_enc(port) ? _("yes") : _("no"), + be_gssapi_get_deleg(port) ? _("yes") : _("no"), princ); else appendStringInfo(&logmsg, - _(" GSS (authenticated=%s, encrypted=%s)"), + _(" GSS (authenticated=%s, encrypted=%s, deleg_credentials=%s)"), be_gssapi_get_auth(port) ? _("yes") : _("no"), - be_gssapi_get_enc(port) ? _("yes") : _("no")); + be_gssapi_get_enc(port) ? _("yes") : _("no"), + be_gssapi_get_deleg(port) ? _("yes") : _("no")); } #endif diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index cf7f465ddb1..97edc61a14b 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -1727,6 +1727,16 @@ struct config_bool ConfigureNamesBool[] = }, { + {"gss_accept_deleg", PGC_SIGHUP, CONN_AUTH_AUTH, + gettext_noop("Sets whether GSSAPI delegation should be accepted from the client."), + NULL + }, + &pg_gss_accept_deleg, + false, + NULL, NULL, NULL + }, + + { {"escape_string_warning", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, gettext_noop("Warn about backslash escapes in ordinary string literals."), NULL diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index e715aff3b81..dce5049bc24 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -101,6 +101,7 @@ # GSSAPI using Kerberos #krb_server_keyfile = 'FILE:${sysconfdir}/krb5.keytab' #krb_caseins_users = off +#gss_accept_deleg = off # - SSL - |