/* * store * * store some credentials in our cache */ krb5_error_code KRB5_CALLCONV krb5_stdcc_store (krb5_context context, krb5_ccache id, krb5_creds *creds ) { krb5_error_code retval; stdccCacheDataPtr ccapi_data = id->data; cred_union *cu = NULL; int err; if ((retval = stdcc_setup(context, ccapi_data))) return retval; /* copy the fields from the almost identical structures */ dupK5toCC(context, creds, &cu); /* * finally store the credential * store will copy (that is duplicate) everything */ err = cc_store(gCntrlBlock, ((stdccCacheDataPtr)(id->data))->NamedCache, *cu); if (err != CC_NOERROR) return cc_err_xlate(err); /* free the cred union using our local version of cc_free_creds() since we allocated it locally */ err = krb5int_free_cc_cred_union(&cu); cache_changed(); return err; }
/* * -- generate_new -------------------------------- * * create a new cache with a unique name, corresponds to creating a * named cache iniitialize the API here if we have to. */ krb5_error_code KRB5_CALLCONV krb5_stdcc_generate_new (krb5_context context, krb5_ccache *id ) { krb5_ccache newCache = NULL; krb5_error_code retval; stdccCacheDataPtr ccapi_data = NULL; char *name = NULL; cc_time_t change_time; int err; if ((retval = stdcc_setup(context, NULL))) return retval; retval = KRB5_CC_NOMEM; if (!(newCache = (krb5_ccache) malloc(sizeof(struct _krb5_ccache)))) goto errout; if (!(ccapi_data = (stdccCacheDataPtr)malloc(sizeof(stdccCacheData)))) goto errout; if (!(name = malloc(256))) goto errout; /* create a unique name */ cc_get_change_time(gCntrlBlock, &change_time); snprintf(name, 256, "gen_new_cache%d", change_time); /* create the new cache */ err = cc_create(gCntrlBlock, name, name, CC_CRED_V5, 0L, &ccapi_data->NamedCache); if (err != CC_NOERROR) { retval = cc_err_xlate(err); goto errout; } /* setup some fields */ newCache->ops = &krb5_cc_stdcc_ops; newCache->data = ccapi_data; ccapi_data->cache_name = name; /* return a pointer to the new cache */ *id = newCache; return 0; errout: if (newCache) free(newCache); if (ccapi_data) free(ccapi_data); if (name) free(name); return retval; }
/* * resolve * * create a new cache with the name stored in residual */ krb5_error_code KRB5_CALLCONV krb5_stdcc_resolve (krb5_context context, krb5_ccache *id , const char *residual ) { krb5_ccache newCache = NULL; stdccCacheDataPtr ccapi_data = NULL; int err; krb5_error_code retval; char *cName = NULL; if ((retval = stdcc_setup(context, NULL))) return retval; retval = KRB5_CC_NOMEM; if (!(newCache = (krb5_ccache) malloc(sizeof(struct _krb5_ccache)))) goto errout; if (!(ccapi_data = (stdccCacheDataPtr)malloc(sizeof(stdccCacheData)))) goto errout; if (!(cName = malloc(strlen(residual)+1))) goto errout; newCache->ops = &krb5_cc_stdcc_ops; newCache->data = ccapi_data; ccapi_data->cache_name = cName; strcpy(cName, residual); err = cc_open(gCntrlBlock, cName, CC_CRED_V5, 0L, &ccapi_data->NamedCache); if (err != CC_NOERROR) { ccapi_data->NamedCache = NULL; if (err != CC_NO_EXIST) { retval = cc_err_xlate(err); goto errout; } } /* return new cache structure */ *id = newCache; return 0; errout: if (newCache) free(newCache); if (ccapi_data) free(ccapi_data); if (cName) free(cName); return retval; }
krb5_error_code KRB5_CALLCONV krb5_stdcc_retrieve (krb5_context context, krb5_ccache id, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds ) { krb5_error_code retval; krb5_cc_cursor curs = NULL; krb5_creds *fetchcreds; if ((retval = stdcc_setup(context, NULL))) return retval; fetchcreds = (krb5_creds *)malloc(sizeof(krb5_creds)); if (fetchcreds == NULL) return KRB5_CC_NOMEM; /* we're going to use the iterators */ krb5_stdcc_start_seq_get(context, id, &curs); while (!krb5_stdcc_next_cred(context, id, &curs, fetchcreds)) { /* * look at each credential for a match * use this match routine since it takes the * whichfields and the API doesn't */ if (stdccCredsMatch(context, fetchcreds, mcreds, whichfields)) { /* we found it, copy and exit */ *creds = *fetchcreds; krb5_stdcc_end_seq_get(context, id, &curs); return 0; } /* free copy allocated by next_cred */ krb5_free_cred_contents(context, fetchcreds); } /* no luck, end get and exit */ krb5_stdcc_end_seq_get(context, id, &curs); /* we're not using this anymore so we should get rid of it! */ free(fetchcreds); return KRB5_CC_NOTFOUND; }
/* * 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_stdcc_initialize (krb5_context context, krb5_ccache id, krb5_principal princ) { stdccCacheDataPtr ccapi_data = NULL; int err; char *cName = NULL; krb5_error_code retval; if ((retval = stdcc_setup(context, NULL))) return retval; /* test id for null */ if (id == NULL) return KRB5_CC_NOMEM; if ((retval = krb5_unparse_name(context, princ, &cName))) return retval; ccapi_data = id->data; if (ccapi_data->NamedCache) cc_close(gCntrlBlock, &ccapi_data->NamedCache); err = cc_create(gCntrlBlock, ccapi_data->cache_name, cName, CC_CRED_V5, 0L, &ccapi_data->NamedCache); if (err != CC_NOERROR) { krb5_free_unparsed_name(context, cName); return cc_err_xlate(err); } #if 0 /* * Some implementations don't set the principal name * correctly, so we force set it to the correct value. */ err = cc_set_principal(gCntrlBlock, ccapi_data->NamedCache, CC_CRED_V5, cName); #endif krb5_free_unparsed_name(context, cName); cache_changed(); 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_stdcc_next_cred (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds) { krb5_error_code retval; stdccCacheDataPtr ccapi_data = id->data; int err; cred_union *credU = NULL; ccache_cit *iterator; if ((retval = stdcc_setup(context, ccapi_data))) return retval; #ifdef CC_API_VER2 iterator = *cursor; if (iterator == 0) return KRB5_CC_END; err = cc_seq_fetch_creds_next(gCntrlBlock, &credU, iterator); if (err == CC_END) { cc_seq_fetch_creds_end(gCntrlBlock, &iterator); *cursor = 0; } #else err = cc_seq_fetch_creds(gCntrlBlock, ccapi_data->NamedCache, &credU, (ccache_cit **)cursor); #endif if (err != CC_NOERROR) return cc_err_xlate(err); /* copy data (with translation) */ dupCCtoK5(context, credU->cred.pV5Cred, creds); /* free our version of the cred - okay to use cc_free_creds() here because we got it from the CCache library */ cc_free_creds(gCntrlBlock, &credU); return 0; }
/* * start_seq_get * * begin an iterator call to get all of the credentials in the cache */ krb5_error_code KRB5_CALLCONV krb5_stdcc_start_seq_get (krb5_context context, krb5_ccache id , krb5_cc_cursor *cursor ) { stdccCacheDataPtr ccapi_data = id->data; krb5_error_code retval; int err; ccache_cit *iterator; if ((retval = stdcc_setup(context, ccapi_data))) return retval; #ifdef CC_API_VER2 err = cc_seq_fetch_creds_begin(gCntrlBlock, ccapi_data->NamedCache, &iterator); if (err != CC_NOERROR) return cc_err_xlate(err); *cursor = iterator; #else /* all we have to do is initialize the cursor */ *cursor = NULL; #endif return 0; }