krb5_error_code KRB5_CALLCONV krb5_get_init_creds_keytab(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_keytab arg_keytab, krb5_deltat start_time, const char *in_tkt_service, krb5_get_init_creds_opt *options) { krb5_error_code ret; int use_master; krb5_keytab keytab; struct errinfo errsave = EMPTY_ERRINFO; if (arg_keytab == NULL) { if ((ret = krb5_kt_default(context, &keytab))) return ret; } else { keytab = arg_keytab; } use_master = 0; /* first try: get the requested tkt from any kdc */ ret = get_init_creds_keytab(context, creds, client, keytab, start_time, in_tkt_service, options, &use_master); /* check for success */ if (ret == 0) goto cleanup; /* If all the kdc's are unavailable fail */ if ((ret == KRB5_KDC_UNREACH) || (ret == KRB5_REALM_CANT_RESOLVE)) goto cleanup; /* if the reply did not come from the master kdc, try again with the master kdc */ if (!use_master) { use_master = 1; k5_save_ctx_error(context, ret, &errsave); ret = get_init_creds_keytab(context, creds, client, keytab, start_time, in_tkt_service, options, &use_master); if (ret == 0) goto cleanup; /* If the master is unreachable, return the error from the slave we * were able to contact. */ if (ret == KRB5_KDC_UNREACH || ret == KRB5_REALM_CANT_RESOLVE || ret == KRB5_REALM_UNKNOWN) ret = k5_restore_ctx_error(context, &errsave); } /* at this point, we have a response from the master. Since we don't do any prompting or changing for keytabs, that's it. */ cleanup: if (arg_keytab == NULL) krb5_kt_close(context, keytab); k5_clear_error(&errsave); return(ret); }
krb5_error_code KRB5_CALLCONV krb5_cccol_have_content(krb5_context context) { krb5_error_code ret; krb5_cccol_cursor col_cursor; krb5_cc_cursor cache_cursor; krb5_ccache cache; krb5_creds creds; krb5_boolean found = FALSE; struct errinfo errsave = EMPTY_ERRINFO; const char *defname; ret = krb5_cccol_cursor_new(context, &col_cursor); save_first_error(context, ret, &errsave); if (ret) goto no_entries; while (!found) { ret = krb5_cccol_cursor_next(context, col_cursor, &cache); save_first_error(context, ret, &errsave); if (ret || cache == NULL) break; ret = krb5_cc_start_seq_get(context, cache, &cache_cursor); save_first_error(context, ret, &errsave); if (ret) continue; while (!found) { ret = krb5_cc_next_cred(context, cache, &cache_cursor, &creds); save_first_error(context, ret, &errsave); if (ret) break; if (!krb5_is_config_principal(context, creds.server)) found = TRUE; krb5_free_cred_contents(context, &creds); } krb5_cc_end_seq_get(context, cache, &cache_cursor); krb5_cc_close(context, cache); } krb5_cccol_cursor_free(context, &col_cursor); if (found) return 0; no_entries: if (errsave.code) { /* Report the first error we encountered. */ ret = k5_restore_ctx_error(context, &errsave); k5_wrapmsg(context, ret, KRB5_CC_NOTFOUND, _("No Kerberos credentials available")); } else { /* Report the default cache name. */ defname = krb5_cc_default_name(context); if (defname != NULL) { k5_setmsg(context, KRB5_CC_NOTFOUND, _("No Kerberos credentials available " "(default cache: %s)"), defname); } } return KRB5_CC_NOTFOUND; }