static krb5_error_code mcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) { krb5_mcache *mfrom = MCACHE(from), *mto = MCACHE(to); struct link *creds; krb5_principal principal; krb5_mcache **n; HEIMDAL_MUTEX_lock(&mcc_mutex); /* drop the from cache from the linked list to avoid lookups */ for(n = &mcc_head; n && *n; n = &(*n)->next) { if(mfrom == *n) { *n = mfrom->next; break; } } /* swap creds */ creds = mto->creds; mto->creds = mfrom->creds; mfrom->creds = creds; /* swap principal */ principal = mto->primary_principal; mto->primary_principal = mfrom->primary_principal; mfrom->primary_principal = principal; HEIMDAL_MUTEX_unlock(&mcc_mutex); mcc_destroy(context, from); return 0; }
static krb5_error_code mcc_store_cred(krb5_context context, krb5_ccache id, krb5_creds *creds) { krb5_mcache *m = MCACHE(id); krb5_error_code ret; struct link *l; if (MISDEAD(m)) return ENOENT; l = malloc (sizeof(*l)); if (l == NULL) { krb5_set_error_string (context, "malloc: out of memory"); return KRB5_CC_NOMEM; } l->next = m->creds; m->creds = l; memset (&l->cred, 0, sizeof(l->cred)); ret = krb5_copy_creds_contents (context, creds, &l->cred); if (ret) { m->creds = l->next; free (l); return ret; } return 0; }
static krb5_error_code mcc_close(krb5_context context, krb5_ccache id) { if (mcc_close_internal(MCACHE(id))) krb5_data_free(&id->data); return 0; }
static krb5_error_code mcc_initialize(krb5_context context, krb5_ccache id, krb5_principal primary_principal) { krb5_mcache *m = MCACHE(id); m->dead = 0; return krb5_copy_principal (context, primary_principal, &m->primary_principal); }
static krb5_error_code mcc_get_first (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) { krb5_mcache *m = MCACHE(id); if (MISDEAD(m)) return ENOENT; *cursor = m->creds; return 0; }
static krb5_error_code mcc_get_principal(krb5_context context, krb5_ccache id, krb5_principal *principal) { krb5_mcache *m = MCACHE(id); if (MISDEAD(m) || m->primary_principal == NULL) return ENOENT; return krb5_copy_principal (context, m->primary_principal, principal); }
static krb5_error_code mcc_remove_cred(krb5_context context, krb5_ccache id, krb5_flags which, krb5_creds *mcreds) { krb5_mcache *m = MCACHE(id); struct link **q, *p; for(q = &m->creds, p = *q; p; p = *q) { if(krb5_compare_creds(context, which, mcreds, &p->cred)) { *q = p->next; krb5_free_cred_contents(context, &p->cred); free(p); } else q = &p->next; } return 0; }
static krb5_error_code mcc_get_next (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds) { krb5_mcache *m = MCACHE(id); struct link *l; if (MISDEAD(m)) return ENOENT; l = *cursor; if (l != NULL) { *cursor = l->next; return krb5_copy_creds_contents (context, &l->cred, creds); } else return KRB5_CC_END; }
static krb5_error_code mcc_destroy(krb5_context context, krb5_ccache id) { krb5_mcache **n, *m = MCACHE(id); struct link *l; if (m->refcnt == 0) krb5_abortx(context, "mcc_destroy: refcnt already 0"); if (!MISDEAD(m)) { /* if this is an active mcache, remove it from the linked list, and free all data */ HEIMDAL_MUTEX_lock(&mcc_mutex); for(n = &mcc_head; n && *n; n = &(*n)->next) { if(m == *n) { *n = m->next; break; } } HEIMDAL_MUTEX_unlock(&mcc_mutex); if (m->primary_principal != NULL) { krb5_free_principal (context, m->primary_principal); m->primary_principal = NULL; } m->dead = 1; l = m->creds; while (l != NULL) { struct link *old; krb5_free_cred_contents (context, &l->cred); old = l; l = l->next; free (old); } m->creds = NULL; } return 0; }
static const char* mcc_get_name(krb5_context context, krb5_ccache id) { return MCACHE(id)->name; }
static krb5_error_code mcc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime) { *mtime = MCACHE(id)->mtime; return 0; }