Skip to content

Commit

Permalink
Preserve cred order in memory ccache type
Browse files Browse the repository at this point in the history
In the memory credential cache type, add new creds to the tail of the
list so that iteration does not reverse the order.
  • Loading branch information
greghudson committed Dec 22, 2020
1 parent 0d56740 commit 722b77b
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 2 deletions.
11 changes: 9 additions & 2 deletions src/lib/krb5/ccache/cc_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ typedef struct _krb5_mcc_data {
k5_cc_mutex lock;
krb5_principal prin;
krb5_mcc_link *link;
krb5_mcc_link **tail; /* Where to store next added cred */
/* Time offsets for clock-skewed clients. */
krb5_int32 time_offset;
krb5_int32 usec_offset;
Expand Down Expand Up @@ -159,6 +160,7 @@ empty_mcc_cache(krb5_context context, krb5_mcc_data *d)
free(curr);
}
d->link = NULL;
d->tail = &d->link;
d->generation++;
krb5_free_principal(context, d->prin);
d->prin = NULL;
Expand Down Expand Up @@ -470,6 +472,7 @@ new_mcc_data (const char *name, krb5_mcc_data **dataptr)
return KRB5_CC_NOMEM;
}
d->link = NULL;
d->tail = &d->link;
d->prin = NULL;
d->time_offset = 0;
d->usec_offset = 0;
Expand Down Expand Up @@ -665,13 +668,17 @@ krb5_mcc_store(krb5_context ctx, krb5_ccache id, krb5_creds *creds)
new_node = malloc(sizeof(krb5_mcc_link));
if (new_node == NULL)
return ENOMEM;
new_node->next = NULL;
err = krb5_copy_creds(ctx, creds, &new_node->creds);
if (err)
goto cleanup;

/* Place the new node at the tail of the list. */
k5_cc_mutex_lock(ctx, &mptr->lock);
new_node->next = mptr->link;
mptr->link = new_node;
*mptr->tail = new_node;
mptr->tail = &new_node->next;
k5_cc_mutex_unlock(ctx, &mptr->lock);

return 0;
cleanup:
free(new_node);
Expand Down
43 changes: 43 additions & 0 deletions src/lib/krb5/ccache/t_cc.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,47 @@ test_memory_concurrent(krb5_context context)
free_test_cred(context);
}

/* Check that order is preserved during iteration. Not all cache types have
* this property. */
static void
test_order(krb5_context context, const char *name)
{
krb5_error_code kret;
krb5_ccache id;
krb5_cc_cursor cursor;
krb5_creds creds;

kret = init_test_cred(context);
CHECK(kret, "init_creds");

kret = krb5_cc_resolve(context, name, &id);
CHECK(kret, "resolve");
kret = krb5_cc_initialize(context, id, test_creds.client);
CHECK(kret, "initialize");
kret = krb5_cc_store_cred(context, id, &test_creds);
CHECK(kret, "store 1");
kret = krb5_cc_store_cred(context, id, &test_creds2);
CHECK(kret, "store 2");

kret = krb5_cc_start_seq_get(context, id, &cursor);
CHECK(kret, "start_seq_get");
kret = krb5_cc_next_cred(context, id, &cursor, &creds);
CHECK(kret, "next_cred 1");
CHECK_BOOL(krb5_principal_compare(context, creds.server,
test_creds.server) != TRUE,
"first cred does not match", "principal_compare");
krb5_free_cred_contents(context, &creds);

kret = krb5_cc_next_cred(context, id, &cursor, &creds);
CHECK(kret, "next_cred 2");
CHECK_BOOL(krb5_principal_compare(context, creds.server,
test_creds2.server) != TRUE,
"second cred does not match", "principal_compare");
krb5_free_cred_contents(context, &creds);

free_test_cred(context);
}

extern const krb5_cc_ops krb5_mcc_ops;
extern const krb5_cc_ops krb5_fcc_ops;

Expand Down Expand Up @@ -610,6 +651,8 @@ main(void)

test_memory_concurrent(context);

test_order(context, "MEMORY:order");

krb5_free_context(context);
return 0;
}

0 comments on commit 722b77b

Please sign in to comment.