Attaching also mod_auth_gssapi patch. If the approach is good, then I'd send it as a push request to upstream git repo.

Copr build of mod_auth_gssapi with the patch: https://copr.fedorainfracloud.org/coprs/pvoborni/freeipa-4-3/build/167157/


IPA patch attached uses the functionality.

https://fedorahosted.org/freeipa/ticket/5653
--
Petr Vobornik
From 069842cc93aa17a8e3be66b785678ee862b5ab24 Mon Sep 17 00:00:00 2001
From: Petr Vobornik <pvobo...@redhat.com>
Date: Thu, 10 Mar 2016 14:53:43 +0100
Subject: [PATCH] sessions: use unique mod_auth_gssapi ccaches

Same ccache name causes issue in concurrent http requests because it is
deleted at the end of request so other requests might not have it available
and then fail.

https://fedorahosted.org/freeipa/ticket/5653
---
 freeipa.spec.in       | 2 +-
 install/conf/ipa.conf | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/freeipa.spec.in b/freeipa.spec.in
index bc47df4c916bd8f091fc2f70330d95bd116ad187..e04df39a8d73f99cf4e189b042d5beb4720fab04 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -140,7 +140,7 @@ Requires: cyrus-sasl-gssapi%{?_isa}
 Requires: ntp
 Requires: httpd >= 2.4.6-6
 Requires: mod_wsgi
-Requires: mod_auth_gssapi >= 1.3.0-2
+Requires: mod_auth_gssapi >= 1.3.2-2
 Requires: mod_nss >= 1.0.8-26
 Requires: python-ldap >= 2.4.15
 Requires: python-gssapi >= 1.1.2
diff --git a/install/conf/ipa.conf b/install/conf/ipa.conf
index 8d4fea35e9c5aa15a611d90fe005090abb1d8e50..3ce3d0e05bffae86687dea1a26231ec968417bda 100644
--- a/install/conf/ipa.conf
+++ b/install/conf/ipa.conf
@@ -1,5 +1,5 @@
 #
-# VERSION 19 - DO NOT REMOVE THIS LINE
+# VERSION 20 - DO NOT REMOVE THIS LINE
 #
 # This file may be overwritten on upgrades.
 #
@@ -65,6 +65,7 @@ WSGIScriptReloading Off
   GssapiCredStore keytab:/etc/httpd/conf/ipa.keytab
   GssapiCredStore client_keytab:/etc/httpd/conf/ipa.keytab
   GssapiDelegCcacheDir /var/run/httpd/ipa/clientcaches
+  GssapiUseUniqueCcacheName On
   GssapiUseS4U2Proxy on
   GssapiAllowedMech krb5
   Require valid-user
-- 
2.5.0

From bb7d486b41891860b5ec39c1b7f7ade5a8d641b1 Mon Sep 17 00:00:00 2001
From: Petr Vobornik <pvobo...@redhat.com>
Date: Tue, 8 Mar 2016 19:38:59 +0100
Subject: [PATCH] Support unique credential cache names

Add new configuration option:
  GssapiUseUniqueCcacheName On

To enable unique names of credential caches. It allows consuming application
to work on top of the cache, without affecting other concurent http requests
of the same principal.
---
 README                | 11 +++++++++++
 src/environ.c         | 12 +++---------
 src/mod_auth_gssapi.c | 35 +++++++++++++++++++++++++++--------
 src/mod_auth_gssapi.h |  6 ++++--
 4 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/README b/README
index b4eca28..708532f 100644
--- a/README
+++ b/README
@@ -171,6 +171,17 @@ A user f...@example.com delegating its credentials would cause the server to
 create a ccache file named /var/run/httpd/clientcaches/f...@example.com
 
 
+### GssapiUseUniqueCcacheName
+
+If credentials are exported to private directory set by GssapiDelegCcacheDir,
+the delegate credentials will use unique credentials cache name.
+
+**Note:** Consuming application must delete the ccache otherwise it will
+litter the filesystem.
+
+#### Example
+    GssapiUseUniqueCcacheName On
+
 ### GssapiUseS4U2Proxy
 
 Enables the use of the s4u2Proxy Kerberos extension also known as
diff --git a/src/environ.c b/src/environ.c
index f9bbf30..edf31cc 100644
--- a/src/environ.c
+++ b/src/environ.c
@@ -243,7 +243,7 @@ static void mag_set_name_attributes(request_rec *req, struct mag_conn *mc)
     }
 }
 
-static void mag_set_KRB5CCANME(request_rec *req, char *ccname)
+static void mag_set_KRB5CCANME(request_rec *req, const char *ccname)
 {
     apr_status_t status;
     apr_finfo_t finfo;
@@ -277,14 +277,8 @@ void mag_set_req_data(request_rec *req,
     }
 
 #ifdef HAVE_CRED_STORE
-    if (cfg->deleg_ccache_dir && mc->delegated) {
-        char *ccname;
-        ccname = mag_gss_name_to_ccache_name(req,
-                                             cfg->deleg_ccache_dir,
-                                             mc->gss_name);
-        if (ccname) {
-            mag_set_KRB5CCANME(req, ccname);
-        }
+    if (cfg->deleg_ccache_dir && mc->delegated && mc->ccname) {
+        mag_set_KRB5CCANME(req, mc->ccname);
     }
 #endif
 }
diff --git a/src/mod_auth_gssapi.c b/src/mod_auth_gssapi.c
index 97e365c..41b7a56 100644
--- a/src/mod_auth_gssapi.c
+++ b/src/mod_auth_gssapi.c
@@ -225,9 +225,10 @@ static char *escape(apr_pool_t *pool, const char *name,
 }
 
 char *mag_gss_name_to_ccache_name(request_rec *req,
-                                  char *dir, const char *gss_name)
+                                  char *dir, const char *gss_name, bool unique)
 {
     char *escaped;
+    struct timespec now;
 
     /* We need to escape away '/', we can't have path separators in
      * a ccache file name */
@@ -236,22 +237,25 @@ char *mag_gss_name_to_ccache_name(request_rec *req,
     /* then escape away the separator (/) if any */
     escaped = escape(req->pool, escaped, '/', "~");
 
-    return apr_psprintf(req->pool, "%s/%s", dir, escaped);
+    if (unique) {
+        clock_gettime(CLOCK_REALTIME, &now);
+        return apr_psprintf(req->pool, "%s/%s_%ld_%ld", dir, escaped,
+                            now.tv_sec, now.tv_nsec);
+    } else {
+        return apr_psprintf(req->pool, "%s/%s", dir, escaped);
+    }
 }
 
-static void mag_store_deleg_creds(request_rec *req,
-                                  char *dir, const char *gss_name,
+static void mag_store_deleg_creds(request_rec *req, const char *ccname,
                                   gss_cred_id_t delegated_cred)
 {
     gss_key_value_element_desc element;
     gss_key_value_set_desc store;
-    char *ccname;
     uint32_t maj, min;
     element.key = "ccache";
     store.elements = &element;
     store.count = 1;
 
-    ccname = mag_gss_name_to_ccache_name(req, dir, gss_name);
     element.value = apr_psprintf(req->pool, "FILE:%s", ccname);
 
     maj = gss_store_cred_into(&min, delegated_cred, GSS_C_INITIATE,
@@ -899,8 +903,11 @@ complete:
 
 #ifdef HAVE_CRED_STORE
     if (cfg->deleg_ccache_dir && delegated_cred != GSS_C_NO_CREDENTIAL) {
-        mag_store_deleg_creds(req, cfg->deleg_ccache_dir, mc->gss_name,
-                              delegated_cred);
+        mc->ccname = mag_gss_name_to_ccache_name(req,
+                                                 cfg->deleg_ccache_dir,
+                                                 mc->gss_name,
+                                                 cfg->use_unique_ccname);
+        mag_store_deleg_creds(req, mc->ccname, delegated_cred);
         mc->delegated = true;
     }
 #endif
@@ -1028,6 +1035,16 @@ static const char *mag_use_s4u2p(cmd_parms *parms, void *mconfig, int on)
 
     return NULL;
 }
+
+static const char *mag_use_unique_ccache_name(cmd_parms *parms, void *mconfig,
+                                              int on)
+{
+    struct mag_config *cfg = (struct mag_config *)mconfig;
+    cfg->use_unique_ccname = on ? true : false;
+
+    return NULL;
+}
+
 #endif
 
 static const char *mag_sess_key(cmd_parms *parms, void *mconfig, const char *w)
@@ -1352,6 +1369,8 @@ static const command_rec mag_commands[] = {
                     "Credential Store"),
     AP_INIT_RAW_ARGS("GssapiDelegCcacheDir", mag_deleg_ccache_dir, NULL,
                      OR_AUTHCFG, "Directory to store delegated credentials"),
+    AP_INIT_FLAG("GssapiUseUniqueCcacheName", mag_use_unique_ccache_name, NULL,
+                 OR_AUTHCFG, "Enables uniqueness of credential cache name"),
 #endif
 #ifdef HAVE_GSS_ACQUIRE_CRED_WITH_PASSWORD
     AP_INIT_FLAG("GssapiBasicAuth", mag_use_basic_auth, NULL, OR_AUTHCFG,
diff --git a/src/mod_auth_gssapi.h b/src/mod_auth_gssapi.h
index ea563ec..deadfbd 100644
--- a/src/mod_auth_gssapi.h
+++ b/src/mod_auth_gssapi.h
@@ -68,6 +68,7 @@ struct mag_config {
     bool use_s4u2proxy;
     char *deleg_ccache_dir;
     gss_key_value_set_desc *cred_store;
+    bool use_unique_ccname;
 #endif
     struct seal_key *mag_skey;
 
@@ -112,12 +113,13 @@ struct mag_conn {
     bool is_preserved;
     int na_count;
     struct mag_attr *name_attributes;
+    const char *ccname;
 };
 
 #define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
 
 struct mag_conn *mag_new_conn_ctx(apr_pool_t *pool);
 const char *mag_str_auth_type(int auth_type);
-char *mag_gss_name_to_ccache_name(request_rec *req,
-                                  char *dir, const char *gss_name);
+char *mag_gss_name_to_ccache_name(request_rec *req, char *dir,
+                                  const char *gss_name, bool unique);
 char *mag_error(request_rec *req, const char *msg, uint32_t maj, uint32_t min);
-- 
2.5.0

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to