Skip Menu |
 

Subject: Credential collection doesn't include DIR subsidiary default cache
The ccache name DIR::filepath represents a single cache within the
directory. If the context's default cache is of this form, DIR's per-
type cursor should yield that cache as a singleton (if the file exists).
Currently it yields nothing.
Date: Thu, 18 Apr 2013 14:44:21 -0400
From: Nalin Dahyabhai <nalin@redhat.com>
To: rt@krbdev.mit.edu
Subject: Re: [krbdev.mit.edu #7172] Credential collection doesn't include DIR subsidiary default cache
RT-Send-Cc:
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'
From: ghudson@mit.edu
Subject: git commit

Include default DIR::file ccache in collection

If the context's default ccache name is a subsidiary file of a
directory collection, include that single cache in the cursor walk
over the DIR type.

https://github.com/krb5/krb5/commit/b874882dc93e5ece4f7218617ed7942656985471
Author: Greg Hudson <ghudson@mit.edu>
Commit: b874882dc93e5ece4f7218617ed7942656985471
Branch: master
src/lib/krb5/ccache/cc_dir.c | 41 +++++++++++++++++++++++++++++++++++++--
src/lib/krb5/ccache/t_cccol.py | 3 ++
2 files changed, 41 insertions(+), 3 deletions(-)
I rewrote the patch because:

* It did unnecessary work. We don't need a directory name in the cursor
if we're not going to iterate over a directory, so we don't have to
decompose the residual value and then recompose it.

* get_context_specified_file didn't conform to
http://k5wiki.kerberos.org/wiki/Coding_style/Practices#Exception_Handlin
g or
http://k5wiki.kerberos.org/wiki/Coding_style/Practices#Output_parameter_
handling or
http://k5wiki.kerberos.org/wiki/Coding_style/Practices#Memory_management

* There were three test cases which all tested the same thing, but no
test case for a nonexistent subsidiary default ccache name.