154
175
return khm_krb5_error(rc, functionName, freeContextFlag, ctx, cache);
155
176
#endif //!NO_KRB5
179
#define TIMET_TOLERANCE (60*5)
182
khm_get_identity_expiration_time(krb5_context ctx, krb5_ccache cc,
184
krb5_timestamp * pexpiration)
186
krb5_principal principal = 0;
187
char * princ_name = NULL;
189
krb5_error_code code;
190
krb5_error_code cc_code;
192
krb5_timestamp now, expiration = 0;
194
wchar_t w_ident_name[KCDB_IDENT_MAXCCH_NAME];
195
char ident_name[KCDB_IDENT_MAXCCH_NAME];
198
khm_int32 rv = KHM_ERROR_NOT_FOUND;
200
if (!ctx || !cc || !ident || !pexpiration)
201
return KHM_ERROR_GENERAL;
203
code = pkrb5_cc_get_principal(ctx, cc, &principal);
206
return KHM_ERROR_INVALID_PARAM;
208
cb = sizeof(w_ident_name);
209
kcdb_identity_get_name(ident, w_ident_name, &cb);
210
UnicodeStrToAnsi(ident_name, sizeof(ident_name), w_ident_name);
212
code = pkrb5_unparse_name(ctx, principal, &princ_name);
214
/* compare principal to ident. */
216
if ( code || !princ_name ||
217
strcmp(princ_name, ident_name) ) {
219
pkrb5_free_unparsed_name(ctx, princ_name);
220
pkrb5_free_principal(ctx, principal);
221
return KHM_ERROR_UNKNOWN;
224
pkrb5_free_unparsed_name(ctx, princ_name);
225
pkrb5_free_principal(ctx, principal);
227
code = pkrb5_timeofday(ctx, &now);
230
return KHM_ERROR_UNKNOWN;
232
cc_code = pkrb5_cc_start_seq_get(ctx, cc, &cur);
234
while (!(cc_code = pkrb5_cc_next_cred(ctx, cc, &cur, &creds))) {
235
krb5_data * c0 = krb5_princ_name(ctx, creds.server);
236
krb5_data * c1 = krb5_princ_component(ctx, creds.server, 1);
237
krb5_data * r = krb5_princ_realm(ctx, creds.server);
239
if ( c0 && c1 && r && c1->length == r->length &&
240
!strncmp(c1->data,r->data,r->length) &&
241
!strncmp("krbtgt",c0->data,c0->length) ) {
243
/* we have a TGT, check for the expiration time.
244
* if it is valid and renewable, use the renew time
247
if (!(creds.ticket_flags & TKT_FLG_INVALID) &&
248
creds.times.starttime < (now + TIMET_TOLERANCE) &&
249
(creds.times.endtime + TIMET_TOLERANCE) > now) {
250
expiration = creds.times.endtime;
252
if ((creds.ticket_flags & TKT_FLG_RENEWABLE) &&
253
(creds.times.renew_till > creds.times.endtime)) {
254
expiration = creds.times.renew_till;
260
if (cc_code == KRB5_CC_END) {
261
cc_code = pkrb5_cc_end_seq_get(ctx, cc, &cur);
262
rv = KHM_ERROR_SUCCESS;
263
*pexpiration = expiration;
270
khm_krb5_find_ccache_for_identity(khm_handle ident, krb5_context *pctx,
271
void * buffer, khm_size * pcbbuf)
273
krb5_context ctx = 0;
274
krb5_ccache cache = 0;
275
krb5_error_code code;
277
struct _infoNC ** pNCi = NULL;
282
krb5_timestamp expiration = 0;
283
krb5_timestamp best_match_expiration = 0;
284
char best_match_ccname[256] = "";
285
khm_handle csp_params = NULL;
286
khm_handle csp_plugins = NULL;
288
if (!buffer || !pcbbuf)
289
return KHM_ERROR_GENERAL;
293
if (!pcc_initialize ||
299
code = pcc_initialize(&cc_ctx, CC_API_VER_2, NULL, NULL);
303
code = pcc_get_NC_info(cc_ctx, &pNCi);
308
for(i=0; pNCi[i]; i++) {
309
if (pNCi[i]->vers != CC_CRED_V5)
312
code = (*pkrb5_cc_resolve)(ctx, pNCi[i]->name, &cache);
316
/* need a function to check the cache for the identity
317
* and determine if it has valid tickets. If it has
318
* the right identity and valid tickets, store the
319
* expiration time and the cache name. If it has the
320
* right identity but no valid tickets, store the ccache
321
* name and an expiration time of zero. if it does not
322
* have the right identity don't save the name.
324
* Keep searching to find the best cache available.
327
if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache,
330
if ( expiration > best_match_expiration ) {
331
best_match_expiration = expiration;
332
StringCbCopyA(best_match_ccname,
333
sizeof(best_match_ccname),
335
StringCbCatA(best_match_ccname,
336
sizeof(best_match_ccname),
342
if(ctx != NULL && cache != NULL)
343
(*pkrb5_cc_close)(ctx, cache);
349
if (KHM_SUCCEEDED(kmm_get_plugins_config(0, &csp_plugins))) {
350
khc_open_space(csp_plugins, L"Krb5Cred\\Parameters", 0, &csp_params);
351
khc_close_space(csp_plugins);
356
if (csp_params == NULL) {
362
KHM_SUCCEEDED(khc_read_int32(csp_params, L"MsLsaList", &t)) && t) {
363
code = (*pkrb5_cc_resolve)(ctx, "MSLSA:", &cache);
364
if (code == 0 && cache) {
365
if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache,
368
if ( expiration > best_match_expiration ) {
369
best_match_expiration = expiration;
370
StringCbCopyA(best_match_ccname, sizeof(best_match_ccname),
377
if (ctx != NULL && cache != NULL)
378
(*pkrb5_cc_close)(ctx, cache);
384
khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb)
385
== KHM_ERROR_TOO_LONG &&
386
cb > sizeof(wchar_t) * 2) {
389
char ccname[MAX_PATH + 6];
397
khc_read_multi_string(csp_params, L"FileCCList", ms, &cb);
398
for(t = ms; t && *t; t = multi_string_next(t)) {
399
StringCchPrintfA(ccname, ARRAYLENGTH(ccname),
402
code = (*pkrb5_cc_resolve)(ctx, ccname, &cache);
406
if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache,
409
if ( expiration > best_match_expiration ) {
410
best_match_expiration = expiration;
411
StringCbCopyA(best_match_ccname,
412
sizeof(best_match_ccname),
418
if (ctx != NULL && cache != NULL)
419
(*pkrb5_cc_close)(ctx, cache);
427
khc_close_space(csp_params);
430
(*pcc_free_NC_info)(cc_ctx, &pNCi);
433
(*pcc_shutdown)(&cc_ctx);
435
if (best_match_ccname[0]) {
437
if (*pcbbuf = AnsiStrToUnicode((wchar_t *)buffer,
439
best_match_ccname)) {
441
*pcbbuf = (*pcbbuf + 1) * sizeof(wchar_t);
443
return KHM_ERROR_SUCCESS;
448
return KHM_ERROR_GENERAL;