Skip to content

Commit 670240a

Browse files
Properly locate credentials in collection caches in mechglue
Previously, we would just put the credentials in the default cache for a collection type, which lead to some mysterious failures. Signed-off-by: Robbie Harwood <[email protected]> Reviewed-by: Simo Sorce <[email protected]> Merges: #221
1 parent 221b553 commit 670240a

File tree

2 files changed

+57
-22
lines changed

2 files changed

+57
-22
lines changed

src/mechglue/gpp_creds.c

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,16 @@ static krb5_error_code gpp_construct_cred(gssx_cred *creds, krb5_context ctx,
170170
return 0;
171171
}
172172

173-
uint32_t gpp_store_remote_creds(uint32_t *min, bool default_creds,
173+
/* Store creds from remote in a local ccache, updating where possible.
174+
*
175+
* If store_as_default_cred is true, the cred is made default for its
176+
* collection, if there is one. Note that if the ccache is not of a
177+
* collection type, the creds will overwrite the ccache.
178+
*
179+
* If no "ccache" entry is specified in cred_store, the default ccache for a
180+
* new context will be used.
181+
*/
182+
uint32_t gpp_store_remote_creds(uint32_t *min, bool store_as_default_cred,
174183
gss_const_key_value_set_t cred_store,
175184
gssx_cred *creds)
176185
{
@@ -179,7 +188,7 @@ uint32_t gpp_store_remote_creds(uint32_t *min, bool default_creds,
179188
krb5_creds cred;
180189
krb5_error_code ret;
181190
char cred_name[creds->desired_name.display_name.octet_string_len + 1];
182-
const char *cc_type;
191+
const char *cc_name;
183192

184193
*min = 0;
185194

@@ -191,38 +200,64 @@ uint32_t gpp_store_remote_creds(uint32_t *min, bool default_creds,
191200
goto done;
192201
}
193202

194-
if (cred_store) {
195-
for (unsigned i = 0; i < cred_store->count; i++) {
196-
if (strcmp(cred_store->elements[i].key, "ccache") == 0) {
197-
ret = krb5_cc_resolve(ctx, cred_store->elements[i].value,
198-
&ccache);
199-
if (ret) goto done;
200-
break;
201-
}
203+
for (unsigned i = 0; cred_store && i < cred_store->count; i++) {
204+
if (strcmp(cred_store->elements[i].key, "ccache") == 0) {
205+
/* krb5 creates new ccaches based off the default name. */
206+
ret = krb5_cc_set_default_name(ctx,
207+
cred_store->elements[i].value);
208+
if (ret)
209+
goto done;
210+
211+
break;
202212
}
203213
}
204-
if (!ccache) {
205-
if (!default_creds) {
206-
ret = ENOMEDIUM;
207-
goto done;
208-
}
209-
ret = krb5_cc_default(ctx, &ccache);
210-
if (ret) goto done;
211-
}
212214

213-
cc_type = krb5_cc_get_type(ctx, ccache);
214-
if (strcmp(cc_type, "FILE") == 0) {
215+
cc_name = krb5_cc_default_name(ctx);
216+
if (strncmp(cc_name, "FILE:", 5) == 0 || !strchr(cc_name, ':')) {
215217
/* FILE ccaches don't handle updates properly: if they have the same
216218
* principal name, they are blackholed. We either have to change the
217219
* name (at which point the file grows forever) or flash the cache on
218220
* every update. */
221+
ret = krb5_cc_default(ctx, &ccache);
222+
if (ret)
223+
goto done;
224+
219225
ret = krb5_cc_initialize(ctx, ccache, cred.client);
220-
if (ret != 0) {
226+
if (ret != 0)
227+
goto done;
228+
229+
ret = krb5_cc_store_cred(ctx, ccache, &cred);
230+
goto done;
231+
}
232+
233+
ret = krb5_cc_cache_match(ctx, cred.client, &ccache);
234+
if (ret == KRB5_CC_NOTFOUND) {
235+
/* A new ccache within the collection whose name is based off the
236+
* default_name for the context. krb5_cc_new_unique only accepts the
237+
* leading component of a name as a type. */
238+
char *cc_type;
239+
const char *p;
240+
241+
p = strchr(cc_name, ':'); /* can't be FILE here */
242+
cc_type = strndup(cc_name, p - cc_name);
243+
if (!cc_type) {
244+
ret = ENOMEM;
221245
goto done;
222246
}
247+
248+
ret = krb5_cc_new_unique(ctx, cc_type, NULL, &ccache);
249+
free(cc_type);
223250
}
251+
if (ret)
252+
goto done;
224253

225254
ret = krb5_cc_store_cred(ctx, ccache, &cred);
255+
if (ret)
256+
goto done;
257+
258+
if (store_as_default_cred) {
259+
ret = krb5_cc_switch(ctx, ccache);
260+
}
226261

227262
done:
228263
if (ctx) {

src/mechglue/gss_plugin.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ uint32_t gpp_cred_handle_init(uint32_t *min, bool defcred, const char *ccache,
7676
struct gpp_cred_handle **out_handle);
7777
uint32_t gpp_cred_handle_free(uint32_t *min, struct gpp_cred_handle *handle);
7878
bool gpp_creds_are_equal(gssx_cred *a, gssx_cred *b);
79-
uint32_t gpp_store_remote_creds(uint32_t *min, bool default_creds,
79+
uint32_t gpp_store_remote_creds(uint32_t *min, bool store_as_default_cred,
8080
gss_const_key_value_set_t cred_store,
8181
gssx_cred *creds);
8282

0 commit comments

Comments
 (0)