Index: globus_gram_job_manager.h
===================================================================
RCS file: /home/globdev/CVS/globus-packages/gram/jobmanager/source/globus_gram_job_manager.h,v
retrieving revision 1.48
diff -u -r1.48 globus_gram_job_manager.h
--- globus_gram_job_manager.h	16 Dec 2009 23:25:48 -0000	1.48
+++ globus_gram_job_manager.h	26 Mar 2010 14:41:46 -0000
@@ -326,6 +326,14 @@
      * on GRAM operations or not. Default to no.
      */
     globus_bool_t                       enable_callout;
+
+    /**
+     * Boolean flag indicating whether to include the DN hash
+     * as part of the job manager tag string. Make this true if you
+     * have multiple DNs mapped to the same local user so each gets
+     * a separate job space with the appropriate credential.
+     */
+    globus_bool_t                       tag_with_dn_hash;
 }
 globus_gram_job_manager_config_t;
 
@@ -1046,6 +1054,11 @@
     const char *                        uri,
     const char *                        auth_type);
 
+int
+globus_gram_gsi_get_dn_hash(
+    gss_cred_id_t                       cred,
+    unsigned long *                     hash);
+
 /* globus_gram_job_manager_query.c */
 void
 globus_gram_job_manager_query_callback(
Index: globus_gram_job_manager_config.c
===================================================================
RCS file: /home/globdev/CVS/globus-packages/gram/jobmanager/source/globus_gram_job_manager_config.c,v
retrieving revision 1.7
diff -u -r1.7 globus_gram_job_manager_config.c
--- globus_gram_job_manager_config.c	16 Dec 2009 23:25:48 -0000	1.7
+++ globus_gram_job_manager_config.c	26 Mar 2010 14:41:46 -0000
@@ -270,6 +270,11 @@
         {
             config->service_tag = strdup(argv[++i]);
         }
+        else if (strcmp(argv[i], "-tag-with-dn-hash") == 0
+                && (i+1 < argc))
+        {
+            config->tag_with_dn_hash = GLOBUS_TRUE;
+        }
         else if (strcmp(argv[i], "-enable-syslog") == 0)
         {
             config->syslog_enabled = GLOBUS_TRUE;
Index: globus_gram_job_manager_gsi.c
===================================================================
RCS file: /home/globdev/CVS/globus-packages/gram/jobmanager/source/globus_gram_job_manager_gsi.c,v
retrieving revision 1.20
diff -u -r1.20 globus_gram_job_manager_gsi.c
--- globus_gram_job_manager_gsi.c	18 Jan 2010 13:33:04 -0000	1.20
+++ globus_gram_job_manager_gsi.c	26 Mar 2010 14:41:46 -0000
@@ -22,6 +22,7 @@
 #include "globus_gram_jobmanager_callout_error.h"
 
 #include <string.h>
+#include <openssl/evp.h>
 
 static
 void
@@ -927,3 +928,134 @@
     return rc;
 }
 /* globus_gram_job_manager_authz_query() */
+
+/**
+ * @brief Look up the identity of a GSSAPI credential and generate a hash
+ * @ingroup globus_gram_gsi
+ *
+ * @details
+ * The @a globus_gram_gsi_get_dn_hash() function inspects the credential 
+ * named by @a cred parameter to determine the identity of the credential.
+ * It then computes the default hash on that name and assigns a copy of
+ * that value to the @a hash parameter. The caller is responsible for freeing
+ * that value.
+ * 
+ * @param cred
+ *     GSSAPI credential to inspect
+ * @param hash
+ *     Pointer to be set to the hash of the identity of @a cred.
+ *
+ * @return 
+ *     On success, @a globus_gram_gsi_get_dn_hash() returns GLOBUS_SUCCESS
+ *     and modifies the @a hash parameter to point to a copy of the string
+ *     representation of the hash. If an error occurs, @a
+ *     globus_gram_gsi_get_dn_hash() returns a non-zero error code and the
+ *     the value of @a hash is undefined.
+ */
+int
+globus_gram_gsi_get_dn_hash(
+    gss_cred_id_t                       cred,
+    unsigned long *                     hash)
+{
+    int                                 rc = GLOBUS_SUCCESS;
+    OM_uint32                           major, minor;
+    gss_name_t                          name;
+    gss_buffer_desc                     namebuf;
+    unsigned char                       md[EVP_MAX_MD_SIZE+1];
+    const EVP_MD *                      evp_md;
+    EVP_MD_CTX                          evp_ctx;
+    unsigned int                        mdlen;
+    unsigned long                       hash_value;
+
+    if (hash == NULL)
+    {
+        rc = GLOBUS_GRAM_PROTOCOL_ERROR_NULL_PARAMETER;
+
+        goto out;
+    }
+    *hash = 0L;
+    if (cred == GSS_C_NO_CREDENTIAL)
+    {
+        rc = GLOBUS_GRAM_PROTOCOL_ERROR_USER_PROXY_NOT_FOUND;
+
+        goto out;
+    }
+
+    major = gss_inquire_cred(
+            &minor,
+            cred,
+            &name,
+            NULL,
+            NULL,
+            NULL);
+
+    if (major != GSS_S_COMPLETE)
+    {
+        rc = GLOBUS_GRAM_PROTOCOL_ERROR_USER_PROXY_NOT_FOUND;
+
+        goto out;
+    }
+
+    major = gss_display_name(
+            &minor,
+            name,
+            &namebuf,
+            NULL);
+    if (major != GSS_S_COMPLETE)
+    {
+        rc = GLOBUS_GRAM_PROTOCOL_ERROR_USER_PROXY_NOT_FOUND;
+
+        goto free_name_out;
+    }
+
+    evp_md = EVP_get_digestbyname("sha1");
+    if (evp_md == NULL)
+    {
+        evp_md = EVP_get_digestbyname("md5");
+    }
+    if (evp_md == NULL)
+    {
+        rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;
+
+        goto free_namebuf_out;
+    }
+
+    EVP_MD_CTX_init(&evp_ctx);
+
+    if (EVP_DigestInit_ex(&evp_ctx, evp_md, NULL) != 1)
+    {
+        rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;
+
+        goto free_namebuf_out;
+    }
+
+    if (EVP_DigestUpdate(&evp_ctx, namebuf.value, namebuf.length) != 1)
+    {
+        rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;
+
+        goto free_digest_out;
+    }
+
+    if (EVP_DigestFinal_ex(&evp_ctx, md, &mdlen) != 1)
+    {
+        rc = GLOBUS_GRAM_PROTOCOL_ERROR_MALLOC_FAILED;
+
+        goto free_digest_out;
+    }
+    hash_value = (((unsigned long)md[0]) |
+                  ((unsigned long)md[1] << 8L) |
+                  ((unsigned long)md[2] << 16L) |
+                  ((unsigned long)md[3] << 24L)) & 0xffffffffL;
+
+    *hash = hash_value;
+
+free_digest_out:
+    EVP_MD_CTX_cleanup(&evp_ctx);
+free_namebuf_out:
+    gss_release_buffer(&minor, &namebuf);
+free_name_out:
+    gss_release_name(&minor, &name);
+out:
+    return rc;
+}
+/* globus_gram_gsi_get_dn_hash() */
Index: main.c
===================================================================
RCS file: /home/globdev/CVS/globus-packages/gram/jobmanager/source/main.c,v
retrieving revision 1.22
diff -u -r1.22 main.c
--- main.c	29 Oct 2009 14:36:39 -0000	1.22
+++ main.c	26 Mar 2010 14:41:46 -0000
@@ -152,6 +152,27 @@
         exit(1);
     }
 
+    if (config.tag_with_dn_hash && cred != GSS_C_NO_CREDENTIAL)
+    {
+        unsigned long hash;
+        char * newtag;
+
+        rc = globus_gram_gsi_get_dn_hash(
+                cred,
+                &hash);
+        if (rc == GLOBUS_SUCCESS)
+        {
+            newtag = globus_common_create_string("%s%s%lx",
+                    strcmp(config.service_tag, "untagged") == 0
+                            ? "" : config.service_tag,
+                    strcmp(config.service_tag, "untagged") == 0
+                            ? "" : ".",
+                    hash);
+            free(config.service_tag);
+            config.service_tag = newtag;
+        }
+    }
+
     /*
      * Remove delegated proxy from disk.
      */
