KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL _krb5_kdc_retry(krb5_context context, krb5_sendto_ctx ctx, void *data, const krb5_data *reply, int *action) { krb5_error_code ret; KRB_ERROR error; if(krb5_rd_error(context, reply, &error)) return 0; ret = krb5_error_from_rd_error(context, &error, NULL); krb5_free_error_contents(context, &error); switch(ret) { case KRB5KRB_ERR_RESPONSE_TOO_BIG: { if (krb5_sendto_ctx_get_flags(ctx) & KRB5_KRBHST_FLAGS_LARGE_MSG) break; krb5_sendto_ctx_add_flags(ctx, KRB5_KRBHST_FLAGS_LARGE_MSG); *action = KRB5_SENDTO_RESET; break; } case KRB5KDC_ERR_SVC_UNAVAILABLE: *action = KRB5_SENDTO_RESET; break; } return 0; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_sendto_kdc_flags(krb5_context context, const krb5_data *send_data, const krb5_realm *realm, krb5_data *receive, int flags) { krb5_error_code ret; krb5_sendto_ctx ctx; ret = krb5_sendto_ctx_alloc(context, &ctx); if (ret) return ret; krb5_sendto_ctx_add_flags(ctx, flags); krb5_sendto_ctx_set_func(ctx, _krb5_kdc_retry, NULL); ret = krb5_sendto_context(context, ctx, send_data, *realm, receive); krb5_sendto_ctx_free(context, ctx); return ret; }
static krb5_error_code change_password_loop(krb5_context context, struct request *request, int *result_code, krb5_data *result_code_string, krb5_data *result_string, struct kpwd_proc *proc) { krb5_error_code ret; krb5_data zero, zero2; krb5_sendto_ctx ctx = NULL; krb5_realm realm; krb5_data_zero(&zero); krb5_data_zero(&zero2); if (request->target) realm = request->target->realm; else realm = request->creds->client->realm; _krb5_debugx(context, 1, "trying to set password using: %s in realm %s", proc->name, realm); ret = krb5_auth_con_init(context, &request->ac); if (ret) goto out; krb5_auth_con_setflags(context, request->ac, KRB5_AUTH_CONTEXT_DO_SEQUENCE); ret = krb5_sendto_ctx_alloc(context, &ctx); if (ret) goto out; krb5_sendto_ctx_set_type(ctx, KRB5_KRBHST_CHANGEPW); /* XXX this is a evil hack */ if (request->creds->ticket.length > 700) { _krb5_debugx(context, 1, "using TCP since the ticket is large: %lu", (unsigned long)request->creds->ticket.length); krb5_sendto_ctx_add_flags(ctx, KRB5_KRBHST_FLAGS_LARGE_MSG); } _krb5_sendto_ctx_set_prexmit(ctx, proc->prexmit, request); ret = krb5_sendto_context(context, ctx, &zero, realm, &zero2); if (ret == 0) ret = proc->process_rep(context, request->ac, &zero2, result_code, result_code_string, result_string); out: _krb5_debugx(context, 1, "set password using %s returned: %d result_code %d", proc->name, ret, *result_code); krb5_auth_con_free(context, request->ac); if (ctx) krb5_sendto_ctx_free(context, ctx); krb5_data_free(&zero2); if (ret == KRB5_KDC_UNREACH) { krb5_set_error_message(context, ret, N_("Unable to reach any changepw server " " in realm %s", "realm"), realm); *result_code = KRB5_KPASSWD_HARDERROR; } return ret; }