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; }
/* * 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; }
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; }
/* 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; }