Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by krbdev.mit.edu (Postfix) with ESMTP id A21113F159 for ; Thu, 18 Apr 2013 14:44:32 -0400 (EDT) Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r3IIiVqO013173 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 18 Apr 2013 14:44:31 -0400 Received: from blade.bos.redhat.com (blade.bos.redhat.com [10.16.184.36]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r3IIiURT002528 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 18 Apr 2013 14:44:31 -0400 Received: from blade.bos.redhat.com (localhost.localdomain [127.0.0.1]) by blade.bos.redhat.com (8.14.6/8.14.5) with ESMTP id r3IIiMZV021301 for ; Thu, 18 Apr 2013 14:44:27 -0400 Received: (from nalin@localhost) by blade.bos.redhat.com (8.14.6/8.14.6/Submit) id r3IIiL9A021300 for rt@krbdev.mit.edu; Thu, 18 Apr 2013 14:44:22 -0400 Date: Thu, 18 Apr 2013 14:44:21 -0400 From: Nalin Dahyabhai To: rt@krbdev.mit.edu Subject: Re: [krbdev.mit.edu #7172] Credential collection doesn't include DIR subsidiary default cache Message-ID: <20130418184421.GA20703@redhat.com> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Disclaimer: I am not a spokesmodel. Views expressed are my own. X-Key-ID: E54F6897 X-Key-Fingerprint: 1AD3 D57B 7B07 0952 A040 5FDA 020B 9DB9 E54F 6897 User-Agent: Mutt/1.5.21 (2010-09-15) X-Scanned-BY: MIMEDefang 2.68 on 10.5.11.23 RT-Send-Cc: X-RT-Original-Encoding: us-ascii Content-Length: 4126 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'