/* * destroy * * - free our storage and the cache */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_destroy (krb5_context context, krb5_ccache id) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; if (!err) { err = stdccv3_setup(context, ccapi_data); } if (!err) { if (ccapi_data) { if (ccapi_data->cache_name) { free(ccapi_data->cache_name); } if (ccapi_data->NamedCache) { /* destroy the named cache */ err = cc_ccache_destroy(ccapi_data->NamedCache); if (err == ccErrCCacheNotFound) { err = 0; /* ccache maybe already destroyed */ } cache_changed(); } free(ccapi_data); id->data = NULL; } free(id); } return cc_err_xlate(err); }
/* get_principal * * - return the principal associated with the named cache */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_get_principal (krb5_context context, krb5_ccache id , krb5_principal *princ) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_string_t name = NULL; if (!err) { err = stdccv3_setup(context, ccapi_data); } if (!err) { err = cc_ccache_get_principal (ccapi_data->NamedCache, cc_credentials_v5, &name); } if (!err) { err = krb5_parse_name (context, name->data, princ); } if (name) { cc_string_release (name); } return cc_err_xlate (err); }
/* * remove * * - remove the specified credentials from the NC */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_remove (krb5_context context, krb5_ccache id, krb5_flags whichfields, krb5_creds *in_creds) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_credentials_iterator_t iterator = NULL; int found = 0; if (!err) { err = stdccv3_setup(context, ccapi_data); } if (!err) { err = cc_ccache_new_credentials_iterator(ccapi_data->NamedCache, &iterator); } /* Note: CCAPI v3 ccaches can contain both v4 and v5 creds */ while (!err && !found) { cc_credentials_t credentials = NULL; err = cc_credentials_iterator_next (iterator, &credentials); if (!err && (credentials->data->version == cc_credentials_v5)) { krb5_creds creds; err = copy_cc_cred_union_to_krb5_creds(context, credentials->data, &creds); if (!err) { found = krb5int_cc_creds_match_request(context, whichfields, in_creds, &creds); krb5_free_cred_contents (context, &creds); } if (!err && found) { err = cc_ccache_remove_credentials (ccapi_data->NamedCache, credentials); } } if (credentials) { cc_credentials_release (credentials); } } if (err == ccIteratorEnd) { err = ccErrCredentialsNotFound; } if (iterator) { err = cc_credentials_iterator_release(iterator); } if (!err) { cache_changed (); } return cc_err_xlate (err); }
/* * close * * - free our pointers to the NC */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_close(krb5_context context, krb5_ccache id) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; if (!err) { err = stdccv3_setup (context, NULL); } if (!err) { if (ccapi_data) { if (ccapi_data->cache_name) { free (ccapi_data->cache_name); } if (ccapi_data->NamedCache) { err = cc_ccache_release (ccapi_data->NamedCache); } free (ccapi_data); id->data = NULL; } free (id); } return cc_err_xlate(err); }
/* * next cred * * - get the next credential in the cache as part of an iterator call * - this maps to call to cc_seq_fetch_creds */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_next_cred (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_credentials_t credentials = NULL; cc_credentials_iterator_t iterator = *cursor; if (!iterator) { err = KRB5_CC_END; } if (!err) { err = stdccv3_setup (context, ccapi_data); } /* Note: CCAPI v3 ccaches can contain both v4 and v5 creds */ while (!err) { err = cc_credentials_iterator_next (iterator, &credentials); if (!err && (credentials->data->version == cc_credentials_v5)) { copy_cc_cred_union_to_krb5_creds(context, credentials->data, creds); break; } } if (credentials) { cc_credentials_release (credentials); } if (err == ccIteratorEnd) { cc_credentials_iterator_release (iterator); *cursor = 0; } return cc_err_xlate (err); }
/* * store * * store some credentials in our cache */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_store (krb5_context context, krb5_ccache id, krb5_creds *creds ) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_credentials_union *cred_union = NULL; if (!err) { err = stdccv3_setup (context, ccapi_data); } if (!err) { /* copy the fields from the almost identical structures */ err = copy_krb5_creds_to_cc_cred_union (context, creds, &cred_union); } if (!err) { err = cc_ccache_store_credentials (ccapi_data->NamedCache, cred_union); } if (!err) { cache_changed(); } if (cred_union) { cred_union_release (cred_union); } return cc_err_xlate (err); }
/* * resolve * * create a new cache with the name stored in residual */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_resolve (krb5_context context, krb5_ccache *id , const char *residual ) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = NULL; krb5_ccache ccache = NULL; char *name = NULL; if (id == NULL) { err = KRB5_CC_NOMEM; } if (!err) { err = stdccv3_setup (context, NULL); } if (!err) { ccapi_data = (stdccCacheDataPtr) malloc (sizeof (*ccapi_data)); if (!ccapi_data) { err = KRB5_CC_NOMEM; } } if (!err) { ccache = (krb5_ccache ) malloc (sizeof (*ccache)); if (!ccache) { err = KRB5_CC_NOMEM; } } if (!err) { name = malloc (strlen(residual) + 1); if (!name) { err = KRB5_CC_NOMEM; } } if (!err) { err = cc_context_open_ccache (gCntrlBlock, residual, &ccapi_data->NamedCache); if (err == ccErrCCacheNotFound) { ccapi_data->NamedCache = NULL; err = 0; /* ccache just doesn't exist yet */ } } if (!err) { strcpy(name, residual); ccapi_data->cache_name = name; name = NULL; /* take ownership */ ccache->ops = &krb5_cc_stdcc_ops; ccache->data = ccapi_data; ccapi_data = NULL; /* take ownership */ *id = ccache; ccache = NULL; /* take ownership */ } if (ccache) { free (ccache); } if (ccapi_data) { free (ccapi_data); } if (name) { free (name); } return cc_err_xlate (err); }
/* * get_flags * * - currently a NOP since we don't store any flags in the NC */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_get_flags (krb5_context context, krb5_ccache id, krb5_flags *flags) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; err = stdccv3_setup (context, ccapi_data); return cc_err_xlate (err); }
krb5_error_code KRB5_CALLCONV krb5_stdccv3_unlock (krb5_context context, krb5_ccache id) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; if (!err) { err = stdccv3_setup(context, ccapi_data); } if (!err) { err = cc_ccache_unlock(ccapi_data->NamedCache); } return cc_err_xlate(err); }
krb5_error_code KRB5_CALLCONV krb5_stdccv3_switch_to (krb5_context context, krb5_ccache id) { krb5_error_code retval; stdccCacheDataPtr ccapi_data = id->data; int err; retval = stdccv3_setup(context, ccapi_data); if (retval) return cc_err_xlate(retval); err = cc_ccache_set_default(ccapi_data->NamedCache); return cc_err_xlate(err); }
/* * initialize * * initialize the cache, check to see if one already exists for this * principal if not set our principal to this principal. This * searching enables ticket sharing */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_initialize (krb5_context context, krb5_ccache id, krb5_principal princ) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; char *name = NULL; cc_ccache_t ccache = NULL; if (id == NULL) { err = KRB5_CC_NOMEM; } if (!err) { err = stdccv3_setup (context, NULL); } if (!err) { err = krb5_unparse_name(context, princ, &name); } if (!err) { err = cc_context_create_ccache (gCntrlBlock, ccapi_data->cache_name, cc_credentials_v5, name, &ccache); } if (!err) { err = stdccv3_set_timeoffset (context, ccache); } if (!err) { if (ccapi_data->NamedCache) { err = cc_ccache_release (ccapi_data->NamedCache); } ccapi_data->NamedCache = ccache; ccache = NULL; /* take ownership */ cache_changed (); } if (ccache) { cc_ccache_release (ccache); } if (name ) { krb5_free_unparsed_name(context, name); } return cc_err_xlate(err); }
/* * end seq * * just free up the storage assoicated with the cursor (if we can) */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_end_seq_get (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_credentials_iterator_t iterator = *cursor; if (!iterator) { return 0; } if (!err) { err = stdccv3_setup (context, ccapi_data); } if (!err) { err = cc_credentials_iterator_release(iterator); } return cc_err_xlate(err); }
krb5_error_code KRB5_CALLCONV krb5_stdccv3_last_change_time (krb5_context context, krb5_ccache id, krb5_timestamp *change_time) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_time_t ccapi_change_time = 0; *change_time = 0; if (!err) { err = stdccv3_setup(context, ccapi_data); } if (!err) { err = cc_ccache_get_change_time (ccapi_data->NamedCache, &ccapi_change_time); } if (!err) { *change_time = ccapi_change_time; } return cc_err_xlate (err); }
krb5_error_code KRB5_CALLCONV krb5_stdccv3_ptcursor_new(krb5_context context, krb5_cc_ptcursor *cursor) { krb5_error_code err = 0; krb5_cc_ptcursor ptcursor = NULL; cc_ccache_iterator_t iterator = NULL; ptcursor = malloc(sizeof(*ptcursor)); if (ptcursor == NULL) { err = ENOMEM; } else { memset(ptcursor, 0, sizeof(*ptcursor)); } if (!err) { err = stdccv3_setup(context, NULL); } if (!err) { ptcursor->ops = &krb5_cc_stdcc_ops; err = cc_context_new_ccache_iterator(gCntrlBlock, &iterator); } if (!err) { ptcursor->data = iterator; } if (err) { if (ptcursor) { krb5_stdccv3_ptcursor_free(context, &ptcursor); } // krb5_stdccv3_ptcursor_free sets ptcursor to NULL for us } *cursor = ptcursor; return err; }
/* * start_seq_get * * begin an iterator call to get all of the credentials in the cache */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_start_seq_get (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor ) { krb5_error_code err = 0; stdccCacheDataPtr ccapi_data = id->data; cc_credentials_iterator_t iterator = NULL; if (!err) { err = stdccv3_setup (context, ccapi_data); } if (!err) { err = cc_ccache_new_credentials_iterator(ccapi_data->NamedCache, &iterator); } if (!err) { *cursor = iterator; } return cc_err_xlate (err); }
/* * -- generate_new -------------------------------- * * create a new cache with a unique name, corresponds to creating a * named cache initialize the API here if we have to. */ krb5_error_code KRB5_CALLCONV krb5_stdccv3_generate_new (krb5_context context, krb5_ccache *id ) { krb5_error_code err = 0; krb5_ccache newCache = NULL; stdccCacheDataPtr ccapi_data = NULL; cc_ccache_t ccache = NULL; cc_string_t ccstring = NULL; char *name = NULL; if (!err) { err = stdccv3_setup(context, NULL); } if (!err) { newCache = (krb5_ccache) malloc (sizeof (*newCache)); if (!newCache) { err = KRB5_CC_NOMEM; } } if (!err) { ccapi_data = (stdccCacheDataPtr) malloc (sizeof (*ccapi_data)); if (!ccapi_data) { err = KRB5_CC_NOMEM; } } if (!err) { err = cc_context_create_new_ccache (gCntrlBlock, cc_credentials_v5, "", &ccache); } if (!err) { err = stdccv3_set_timeoffset (context, ccache); } if (!err) { err = cc_ccache_get_name (ccache, &ccstring); } if (!err) { name = strdup (ccstring->data); if (!name) { err = KRB5_CC_NOMEM; } } if (!err) { ccapi_data->cache_name = name; name = NULL; /* take ownership */ ccapi_data->NamedCache = ccache; ccache = NULL; /* take ownership */ newCache->ops = &krb5_cc_stdcc_ops; newCache->data = ccapi_data; ccapi_data = NULL; /* take ownership */ /* return a pointer to the new cache */ *id = newCache; newCache = NULL; } if (ccstring) { cc_string_release (ccstring); } if (name) { free (name); } if (ccache) { cc_ccache_release (ccache); } if (ccapi_data) { free (ccapi_data); } if (newCache) { free (newCache); } return cc_err_xlate (err); }