Example #1
0
static krb5_error_code
decrypt_fast_reply(krb5_context context,
                   struct krb5int_fast_request_state *state,
                   krb5_pa_data **in_padata,
                   krb5_fast_response **response)
{
    krb5_error_code retval = 0;
    krb5_data scratch;
    krb5_enc_data *encrypted_response = NULL;
    krb5_pa_data *fx_reply = NULL;
    krb5_fast_response *local_resp = NULL;

    assert(state != NULL);
    assert(state->armor_key);
    fx_reply = krb5int_find_pa_data(context, in_padata, KRB5_PADATA_FX_FAST);
    if (fx_reply == NULL)
        retval = KRB5_ERR_FAST_REQUIRED;
    TRACE_FAST_DECODE(context);
    if (retval == 0) {
        scratch.data = (char *) fx_reply->contents;
        scratch.length = fx_reply->length;
        retval = decode_krb5_pa_fx_fast_reply(&scratch, &encrypted_response);
    }
    scratch.data = NULL;
    if (retval == 0) {
        scratch.data = malloc(encrypted_response->ciphertext.length);
        if (scratch.data == NULL)
            retval = ENOMEM;
        scratch.length = encrypted_response->ciphertext.length;
    }
    if (retval == 0)
        retval = krb5_c_decrypt(context, state->armor_key,
                                KRB5_KEYUSAGE_FAST_REP, NULL,
                                encrypted_response, &scratch);
    if (retval != 0)
        k5_prependmsg(context, retval, _("Failed to decrypt FAST reply"));
    if (retval == 0)
        retval = decode_krb5_fast_response(&scratch, &local_resp);
    if (retval == 0) {
        if (local_resp->nonce != state->nonce) {
            retval = KRB5_KDCREP_MODIFIED;
            k5_setmsg(context, retval, _("nonce modified in FAST response: "
                                         "KDC response modified"));
        }
    }
    if (retval == 0) {
        *response = local_resp;
        local_resp = NULL;
    }
    if (scratch.data)
        free(scratch.data);
    if (encrypted_response)
        krb5_free_enc_data(context, encrypted_response);
    if (local_resp)
        krb5_free_fast_response(context, local_resp);
    return retval;
}
Example #2
0
/*
 * Open the DB2 database described by dbc, using the specified flags and mode,
 * and return the resulting handle.  Try both hash and btree database types;
 * dbc->hashfirst determines which is attempted first.  If dbc->hashfirst
 * indicated the wrong type, update it to indicate the correct type.
 */
static krb5_error_code
open_db(krb5_context context, krb5_db2_context *dbc, int flags, int mode,
        DB **db_out)
{
    char *fname = NULL;
    DB *db;
    BTREEINFO bti;
    HASHINFO hashi;
    bti.flags = 0;
    bti.cachesize = 0;
    bti.psize = 4096;
    bti.lorder = 0;
    bti.minkeypage = 0;
    bti.compare = NULL;
    bti.prefix = NULL;

    *db_out = NULL;

    if (ctx_dbsuffix(dbc, SUFFIX_DB, &fname) != 0)
        return ENOMEM;

    hashi.bsize = 4096;
    hashi.cachesize = 0;
    hashi.ffactor = 40;
    hashi.hash = NULL;
    hashi.lorder = 0;
    hashi.nelem = 1;

    /* Try our best guess at the database type. */
    db = dbopen(fname, flags, mode,
                dbc->hashfirst ? DB_HASH : DB_BTREE,
                dbc->hashfirst ? (void *) &hashi : (void *) &bti);

    if (db == NULL && IS_EFTYPE(errno)) {
        db = dbopen(fname, flags, mode,
                    dbc->hashfirst ? DB_BTREE : DB_HASH,
                    dbc->hashfirst ? (void *) &bti : (void *) &hashi);
        /* If that worked, update our guess for next time. */
        if (db != NULL)
            dbc->hashfirst = !dbc->hashfirst;
    }

    /* Don't try unlocked iteration with a hash database. */
    if (db != NULL && dbc->hashfirst)
        dbc->unlockiter = FALSE;

    if (db == NULL) {
        k5_prependmsg(context, errno, _("Cannot open DB2 database '%s'"),
                      fname);
    }

    *db_out = db;
    free(fname);
    return (db == NULL) ? errno : 0;
}
Example #3
0
krb5_error_code
krb5int_fast_as_armor(krb5_context context,
                      struct krb5int_fast_request_state *state,
                      krb5_get_init_creds_opt *opt, krb5_kdc_req *request)
{
    krb5_error_code retval = 0;
    krb5_ccache ccache = NULL;
    krb5_principal target_principal = NULL;
    krb5_data *target_realm;
    const char *ccname = k5_gic_opt_get_fast_ccache_name(opt);
    krb5_flags fast_flags;

    krb5_clear_error_message(context);
    target_realm = &request->server->realm;
    if (ccname != NULL) {
        TRACE_FAST_ARMOR_CCACHE(context, ccname);
        state->fast_state_flags |= KRB5INT_FAST_ARMOR_AVAIL;
        retval = krb5_cc_resolve(context, ccname, &ccache);
        if (retval == 0) {
            retval = krb5int_tgtname(context, target_realm, target_realm,
                                     &target_principal);
        }
        if (retval == 0) {
            krb5_data config_data;
            config_data.data = NULL;
            retval = krb5_cc_get_config(context, ccache, target_principal,
                                        KRB5_CC_CONF_FAST_AVAIL, &config_data);
            if ((retval == 0) && config_data.data) {
                TRACE_FAST_CCACHE_CONFIG(context);
                state->fast_state_flags |= KRB5INT_FAST_DO_FAST;
            }
            krb5_free_data_contents(context, &config_data);
            retval = 0;
        }
        fast_flags = k5_gic_opt_get_fast_flags(opt);
        if (fast_flags & KRB5_FAST_REQUIRED) {
            TRACE_FAST_REQUIRED(context);
            state->fast_state_flags |= KRB5INT_FAST_DO_FAST;
        }
        if (retval == 0 && (state->fast_state_flags & KRB5INT_FAST_DO_FAST)) {
            retval = fast_armor_ap_request(context, state, ccache,
                                           target_principal);
        }
        if (retval != 0) {
            k5_prependmsg(context, retval,
                          _("Error constructing AP-REQ armor"));
        }
    }
    if (ccache)
        krb5_cc_close(context, ccache);
    if (target_principal)
        krb5_free_principal(context, target_principal);
    return retval;
}
Example #4
0
/* Ensure that we have the parameters we need to authenticate to the LDAP
 * server.  Read the password if necessary. */
static krb5_error_code
validate_context(krb5_context context, krb5_ldap_context *ctx)
{
    krb5_error_code ret;

    if (ctx->sasl_mech != NULL) {
        /* Read the password for use as the SASL secret if we can, but do not
         * require one as not all mechanisms need it. */
        if (ctx->bind_pwd == NULL && ctx->sasl_authcid != NULL &&
            ctx->service_password_file != NULL) {
            (void)krb5_ldap_readpassword(context, ctx->service_password_file,
                                         ctx->sasl_authcid, &ctx->bind_pwd);
        }
        return 0;
    }

    /* For a simple bind, a DN and password are required. */

    if (ctx->bind_dn == NULL) {
        k5_setmsg(context, EINVAL, _("LDAP bind dn value missing"));
        return EINVAL;
    }

    if (ctx->bind_pwd == NULL && ctx->service_password_file == NULL) {
        k5_setmsg(context, EINVAL, _("LDAP bind password value missing"));
        return EINVAL;
    }

    if (ctx->bind_pwd == NULL && ctx->service_password_file != NULL) {
        ret = krb5_ldap_readpassword(context, ctx->service_password_file,
                                     ctx->bind_dn, &ctx->bind_pwd);
        if (ret) {
            k5_prependmsg(context, ret,
                          _("Error reading password from stash"));
            return ret;
        }
    }

    /* An empty password is not allowed. */
    if (*ctx->bind_pwd == '\0') {
        k5_setmsg(context, EINVAL, _("Service password length is zero"));
        return EINVAL;
    }

    return 0;
}