Esempio n. 1
0
static krb5_error_code
search_sprinc(kdc_realm_t *kdc_active_realm, krb5_kdc_req *req,
              krb5_flags flags, krb5_db_entry **server, const char **status)
{
    krb5_error_code ret;
    krb5_principal princ = req->server;
    krb5_principal reftgs = NULL;

    ret = db_get_svc_princ(kdc_context, princ, flags, server, status);
    if (ret == 0 || ret != KRB5_KDB_NOENTRY)
        goto cleanup;

    if (!is_cross_tgs_principal(req->server)) {
        ret = find_referral_tgs(kdc_active_realm, req, &reftgs);
        if (ret != 0)
            goto cleanup;
        ret = db_get_svc_princ(kdc_context, reftgs, flags, server, status);
        if (ret == 0 || ret != KRB5_KDB_NOENTRY)
            goto cleanup;

        princ = reftgs;
    }
    ret = find_alternate_tgs(kdc_active_realm, princ, server, status);

cleanup:
    if (ret != 0 && ret != KRB5KDC_ERR_SVC_UNAVAILABLE) {
        ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
        if (*status == NULL)
            *status = "LOOKING_UP_SERVER";
    }
    krb5_free_principal(kdc_context, reftgs);
    return ret;
}
Esempio n. 2
0
static krb5_error_code
search_sprinc(kdc_realm_t *kdc_active_realm, krb5_kdc_req *req,
              krb5_flags flags, krb5_db_entry **server, const char **status)
{
    krb5_error_code ret;
    krb5_principal princ = req->server;
    krb5_principal reftgs = NULL;
    krb5_boolean allow_referral;

    /* Do not allow referrals for u2u or ticket modification requests, because
     * the server is supposed to match an already-issued ticket. */
    allow_referral = !(req->kdc_options & NO_REFERRAL_OPTION);
    if (!allow_referral)
        flags &= ~KRB5_KDB_FLAG_CANONICALIZE;

    ret = db_get_svc_princ(kdc_context, princ, flags, server, status);
    if (ret == 0 || ret != KRB5_KDB_NOENTRY || !allow_referral)
        goto cleanup;

    if (!is_cross_tgs_principal(req->server)) {
        ret = find_referral_tgs(kdc_active_realm, req, &reftgs);
        if (ret != 0)
            goto cleanup;
        ret = db_get_svc_princ(kdc_context, reftgs, flags, server, status);
        if (ret == 0 || ret != KRB5_KDB_NOENTRY)
            goto cleanup;

        princ = reftgs;
    }
    ret = find_alternate_tgs(kdc_active_realm, princ, server, status);

cleanup:
    if (ret != 0 && ret != KRB5KDC_ERR_SVC_UNAVAILABLE) {
        ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
        if (*status == NULL)
            *status = "LOOKING_UP_SERVER";
    }
    krb5_free_principal(kdc_context, reftgs);
    return ret;
}
Esempio n. 3
0
/*
 * The request seems to be for a ticket-granting service somewhere else,
 * but we don't have a ticket for the final TGS.  Try to give the requestor
 * some intermediate realm.
 */
static krb5_error_code
find_alternate_tgs(kdc_realm_t *kdc_active_realm, krb5_principal princ,
                   krb5_db_entry **server_ptr, const char **status)
{
    krb5_error_code retval;
    krb5_principal *plist = NULL, *pl2;
    krb5_data tmp;
    krb5_db_entry *server = NULL;

    *server_ptr = NULL;
    assert(is_cross_tgs_principal(princ));
    if ((retval = krb5_walk_realm_tree(kdc_context,
                                       krb5_princ_realm(kdc_context, princ),
                                       krb5_princ_component(kdc_context, princ, 1),
                                       &plist, KRB5_REALM_BRANCH_CHAR))) {
        goto cleanup;
    }
    /* move to the end */
    for (pl2 = plist; *pl2; pl2++);

    /* the first entry in this array is for krbtgt/local@local, so we
       ignore it */
    while (--pl2 > plist) {
        tmp = *krb5_princ_realm(kdc_context, *pl2);
        krb5_princ_set_realm(kdc_context, *pl2,
                             krb5_princ_realm(kdc_context, princ));
        retval = db_get_svc_princ(kdc_context, *pl2, 0, &server, status);
        krb5_princ_set_realm(kdc_context, *pl2, &tmp);
        if (retval == KRB5_KDB_NOENTRY)
            continue;
        else if (retval)
            goto cleanup;

        log_tgs_alt_tgt(kdc_context, server->princ);
        *server_ptr = server;
        server = NULL;
        goto cleanup;
    }
cleanup:
    if (retval == 0 && *server_ptr == NULL)
        retval = KRB5_KDB_NOENTRY;
    if (retval != 0)
        *status = "UNKNOWN_SERVER";

    krb5_free_realm_tree(kdc_context, plist);
    krb5_db_free_principal(kdc_context, server);
    return retval;
}