Example #1
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_kt_get_entry(krb5_context context,
		  krb5_keytab id,
		  krb5_const_principal principal,
		  krb5_kvno kvno,
		  krb5_enctype enctype,
		  krb5_keytab_entry *entry)
{
    krb5_error_code ret;
    krb5_const_principal try_princ;
    krb5_name_canon_iterator name_canon_iter;

    if (!principal)
	return krb5_kt_get_entry_wrapped(context, id, principal, kvno, enctype,
					 entry);

    ret = krb5_name_canon_iterator_start(context, principal, &name_canon_iter);
    if (ret)
	return ret;

    do {
	ret = krb5_name_canon_iterate(context, &name_canon_iter, &try_princ,
                                      NULL);
	if (ret)
	    break;
        if (try_princ == NULL) {
            ret = KRB5_KT_NOTFOUND;
            continue;
        }
	ret = krb5_kt_get_entry_wrapped(context, id, try_princ, kvno,
					enctype, entry);
    } while (ret == KRB5_KT_NOTFOUND && name_canon_iter);

    if (ret != KRB5_KT_NOTFOUND)
	krb5_set_error_message(context, ret,
			       N_("Name canon failed while searching keytab",
				  ""));
    krb5_free_name_canon_iterator(context, name_canon_iter);
    return ret;
}
Example #2
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_get_creds(krb5_context context,
	       krb5_get_creds_opt opt,
	       krb5_ccache ccache,
	       krb5_const_principal inprinc,
	       krb5_creds **out_creds)
{
    krb5_kdc_flags flags;
    krb5_flags options;
    krb5_creds in_creds;
    krb5_error_code ret;
    krb5_creds **tgts;
    krb5_creds *try_creds;
    krb5_creds *res_creds;
    krb5_name_canon_iterator name_canon_iter = NULL;
    krb5_name_canon_rule_options rule_opts;
    int i;

    if (opt && opt->enctype) {
	ret = krb5_enctype_valid(context, opt->enctype);
	if (ret)
	    return ret;
    }

    memset(&in_creds, 0, sizeof(in_creds));
    in_creds.server = rk_UNCONST(inprinc);

    ret = krb5_cc_get_principal(context, ccache, &in_creds.client);
    if (ret)
	return ret;

    if (opt)
	options = opt->options;
    else
	options = 0;
    flags.i = 0;

    *out_creds = NULL;
    res_creds = calloc(1, sizeof(*res_creds));
    if (res_creds == NULL) {
	krb5_free_principal(context, in_creds.client);
	return krb5_enomem(context);
    }

    if (opt && opt->enctype) {
	in_creds.session.keytype = opt->enctype;
	options |= KRB5_TC_MATCH_KEYTYPE;
    }

    /* Check for entry in ccache */
    if (inprinc->name.name_type == KRB5_NT_SRV_HST_NEEDS_CANON) {
	ret = check_cc(context, options, ccache, &in_creds, res_creds);
	if (ret == 0) {
	    *out_creds = res_creds;
	    goto out;
	}
    }

    ret = krb5_name_canon_iterator_start(context, NULL, &in_creds,
					 &name_canon_iter);
    if (ret)
	goto out;

next_rule:
    ret = krb5_name_canon_iterate_creds(context, &name_canon_iter, &try_creds,
					&rule_opts);
    if (ret)
	return ret;
    if (name_canon_iter == NULL) {
	if (options & KRB5_GC_CACHED)
	    ret = KRB5_CC_NOTFOUND;
	else
	    ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
	goto out;
    }
    ret = check_cc(context, options, ccache, try_creds, res_creds);
    if (ret == 0) {
	*out_creds = res_creds;
	goto out;
    } else if(ret != KRB5_CC_END) {
	goto out;
    }
    if(options & KRB5_GC_CACHED)
	goto next_rule;

    if(rule_opts & KRB5_NCRO_USE_REFERRALS)
	flags.b.canonicalize = 1;
    else if(rule_opts & KRB5_NCRO_NO_REFERRALS)
	flags.b.canonicalize = 0;
    else
	flags.b.canonicalize = (options & KRB5_GC_CANONICALIZE) ? 1 : 0;
    if(options & KRB5_GC_USER_USER) {
	flags.b.enc_tkt_in_skey = 1;
	options |= KRB5_GC_NO_STORE;
    }
    if (options & KRB5_GC_FORWARDABLE)
	flags.b.forwardable = 1;
    if (options & KRB5_GC_NO_TRANSIT_CHECK)
	flags.b.disable_transited_check = 1;
    if (options & KRB5_GC_CONSTRAINED_DELEGATION) {
	flags.b.request_anonymous = 1; /* XXX ARGH confusion */
	flags.b.constrained_delegation = 1;
    }

    tgts = NULL;
    ret = _krb5_get_cred_kdc_any(context, flags, ccache,
				 try_creds, opt ? opt->self : 0,
				 opt ? opt->ticket : 0, out_creds,
				 &tgts);
    for(i = 0; tgts && tgts[i]; i++) {
	krb5_cc_store_cred(context, ccache, tgts[i]);
	krb5_free_creds(context, tgts[i]);
    }
    free(tgts);

    if (ret == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN &&
	!(rule_opts & KRB5_NCRO_SECURE))
	goto next_rule;

    if(ret == 0 && (options & KRB5_GC_NO_STORE) == 0)
	store_cred(context, ccache, inprinc, *out_creds);

out:
    if (ret) {
	krb5_free_creds(context, res_creds);
	ret = not_found(context, inprinc, ret);
    }
    krb5_free_principal(context, in_creds.client);
    krb5_free_name_canon_iterator(context, name_canon_iter);
    _krb5_debug(context, 5, "krb5_get_creds: ret = %d", ret);
    return ret;
}
Example #3
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_get_credentials_with_flags(krb5_context context,
				krb5_flags options,
				krb5_kdc_flags flags,
				krb5_ccache ccache,
				krb5_creds *in_creds,
				krb5_creds **out_creds)
{
    krb5_error_code ret;
    krb5_name_canon_iterator name_canon_iter = NULL;
    krb5_name_canon_rule_options rule_opts;
    krb5_creds **tgts;
    krb5_creds *try_creds;
    krb5_creds *res_creds;
    int i;

    if (in_creds->session.keytype) {
	ret = krb5_enctype_valid(context, in_creds->session.keytype);
	if (ret)
	    return ret;
	options |= KRB5_TC_MATCH_KEYTYPE;
    }

    *out_creds = NULL;
    res_creds = calloc(1, sizeof(*res_creds));
    if (res_creds == NULL)
	return krb5_enomem(context);

    if (in_creds->server->name.name_type == KRB5_NT_SRV_HST_NEEDS_CANON) {
	ret = check_cc(context, options, ccache, in_creds, res_creds);
	if (ret == 0) {
	    *out_creds = res_creds;
	    return 0;
	}
    }

    ret = krb5_name_canon_iterator_start(context, NULL, in_creds,
					 &name_canon_iter);
    if (ret)
	return ret;

next_rule:
    krb5_free_cred_contents(context, res_creds);
    memset(res_creds, 0, sizeof (*res_creds));
    ret = krb5_name_canon_iterate_creds(context, &name_canon_iter, &try_creds,
					&rule_opts);
    if (ret)
	goto out;
    if (name_canon_iter == NULL) {
	if (options & KRB5_GC_CACHED)
	    ret = KRB5_CC_NOTFOUND;
	else
	    ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
	goto out;
    }

    ret = check_cc(context, options, ccache, try_creds, res_creds);
    if (ret == 0) {
	*out_creds = res_creds;
	goto out;
    } else if(ret != KRB5_CC_END) {
        goto out;
    }
    if(options & KRB5_GC_CACHED)
	goto next_rule;

    if(options & KRB5_GC_USER_USER)
	flags.b.enc_tkt_in_skey = 1;
    if (flags.b.enc_tkt_in_skey)
	options |= KRB5_GC_NO_STORE;

    tgts = NULL;
    ret = _krb5_get_cred_kdc_any(context, flags, ccache,
				 try_creds, NULL, NULL, out_creds, &tgts);
    for(i = 0; tgts && tgts[i]; i++) {
	krb5_cc_store_cred(context, ccache, tgts[i]);
	krb5_free_creds(context, tgts[i]);
    }
    free(tgts);
    if (ret == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN &&
	!(rule_opts & KRB5_NCRO_SECURE))
	goto next_rule;

    if(ret == 0 && (options & KRB5_GC_NO_STORE) == 0)
	store_cred(context, ccache, in_creds->server, *out_creds);

out:
    krb5_free_name_canon_iterator(context, name_canon_iter);
    if (ret) {
	krb5_free_creds(context, res_creds);
	return not_found(context, in_creds->server, ret);
    }
    return 0;
}