Beispiel #1
0
/* Store the error state for code from context into errsave, but only if code
 * indicates an error and errsave is empty. */
static void
save_first_error(krb5_context context, krb5_error_code code,
                 struct errinfo *errsave)
{
    if (code && code != KRB5_CC_END && !errsave->code)
        k5_save_ctx_error(context, code, errsave);
}
Beispiel #2
0
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);
}