[krbdev.mit.edu #7172] Credential collection doesn't include DIR subsidiary default cache

nalin@redhat.com via RT rt-comment at krbdev.mit.edu
Thu Apr 18 14:44:33 EDT 2013


Proposed patch:

--- src/lib/krb5/ccache/cc_dir.c
+++ src/lib/krb5/ccache/cc_dir.c
@@ -266,6 +266,46 @@ get_context_default_dir(krb5_context context, char **dirname_out)
     return 0;
 }
 
+/*
+ * If the default ccache name for context is a subsidiary in a directory
+ * collection, set *dirname_out to the directory name for that collection and
+ * *residual_out to the residual value that we'd use if the named file was the
+ * primary.  Otherwise set both to NULL.
+ */
+static krb5_error_code
+get_context_specified_file(krb5_context context, char **dirname_out,
+                           char **residual_out)
+{
+    krb5_error_code ret;
+    const char *defname;
+    char *filename;
+
+    *dirname_out = NULL;
+    *residual_out = NULL;
+    defname = krb5_cc_default_name(context);
+    if (defname == NULL)
+        return 0;
+    if (strncmp(defname, "DIR:", 4) != 0 || defname[4] != ':')
+        return 0;
+    ret = split_path(context, defname + 5, dirname_out, &filename);
+    if (ret != 0) {
+        free(*dirname_out);
+        *dirname_out = NULL;
+        free(filename);
+        return ret;
+    }
+    ret = subsidiary_residual(*dirname_out, filename, residual_out);
+    free(filename);
+    if (ret != 0) {
+        free(*dirname_out);
+        *dirname_out = NULL;
+        free(*residual_out);
+        *residual_out = NULL;
+        return ret;
+    }
+    return 0;
+}
+
 static const char * KRB5_CALLCONV
 dcc_get_name(krb5_context context, krb5_ccache cache)
 {
@@ -559,22 +599,31 @@ dcc_ptcursor_new(krb5_context context, krb5_cc_ptcursor *cursor_out)
     krb5_error_code ret;
     char *dirname = NULL, *primary_path = NULL, *primary = NULL;
     DIR *dir = NULL;
+    krb5_boolean override_primary;
 
     *cursor_out = NULL;
 
     /* Open the directory for the context's default cache. */
     ret = get_context_default_dir(context, &dirname);
-    if (ret || dirname == NULL)
-        goto cleanup;
-    dir = opendir(dirname);
-    if (dir == NULL)
-        goto cleanup;
+    override_primary = FALSE;
+    if (ret || dirname == NULL) {
+        ret = get_context_specified_file(context, &dirname, &primary);
+        if (ret || dirname == NULL || primary == NULL)
+            goto cleanup;
+        override_primary = TRUE;
+    } else {
+        dir = opendir(dirname);
+        if (dir == NULL)
+            goto cleanup;
+    }
 
     /* Fetch the primary cache name if possible. */
-    ret = primary_pathname(dirname, &primary_path);
-    if (ret)
-        goto cleanup;
-    ret = read_primary_file(context, primary_path, dirname, &primary);
+    if (!override_primary) {
+        ret = primary_pathname(dirname, &primary_path);
+        if (ret)
+            goto cleanup;
+        ret = read_primary_file(context, primary_path, dirname, &primary);
+    }
     if (ret)
         krb5_clear_error_message(context);
 
@@ -607,8 +656,6 @@ dcc_ptcursor_next(krb5_context context, krb5_cc_ptcursor cursor,
     struct stat sb;
 
     *cache_out = NULL;
-    if (data->dir == NULL)      /* Empty cursor */
-        return 0;
 
     /* Return the primary cache if we haven't yet. */
     if (data->first) {
@@ -616,6 +663,8 @@ dcc_ptcursor_next(krb5_context context, krb5_cc_ptcursor cursor,
         if (data->primary != NULL && stat(data->primary + 1, &sb) == 0)
             return dcc_resolve(context, cache_out, data->primary);
     }
+    if (data->dir == NULL)      /* Empty cursor or one already-seen cache. */
+        return 0;
 
     /* Look for the next filename of the correct form, without repeating the
      * primary cache. */
diff --git a/src/lib/krb5/ccache/t_cccol.py b/src/lib/krb5/ccache/t_cccol.py
index acd2b6e..8a37f9b 100644
--- a/src/lib/krb5/ccache/t_cccol.py
+++ b/src/lib/krb5/ccache/t_cccol.py
@@ -30,6 +30,9 @@ cursor_test('file-default2', [realm.ccache], [fccname])
 cursor_test('file-default3', [fccname], [fccname])
 
 cursor_test('dir', [dccname], [duser, dalice, dbob])
+cursor_test('dir-user', [duser], [duser])
+cursor_test('dir-alice', [dalice], [dalice])
+cursor_test('dir-bob', [dbob], [dbob])
 
 mfoo = 'MEMORY:foo'
 mbar = 'MEMORY:bar'



More information about the krb5-bugs mailing list