krb5_tkt_creds_init(krb5_context context, krb5_ccache ccache,
krb5_creds *creds, int kdcopt, krb5_tkt_creds_context *ctx);
+krb5_error_code KRB5_CALLCONV
+krb5_tkt_creds_get(krb5_context context, krb5_tkt_creds_context ctx);
+
krb5_error_code KRB5_CALLCONV
krb5_tkt_creds_get_creds(krb5_context context, krb5_tkt_creds_context ctx,
krb5_creds *creds);
{
krb5_error_code code;
char **hrealms;
- krb5_creds *server_tgt;
if (ctx->server->length < 2) {
/* We need a type/host format principal to find a fallback realm. */
static krb5_error_code
begin(krb5_context context, krb5_tkt_creds_context ctx)
{
- krb5_creds *server_tgt;
krb5_error_code code;
/* If the server realm is unspecified, start with the client realm. */
free(ctx);
}
+krb5_error_code
+krb5_tkt_creds_get(krb5_context context, krb5_tkt_creds_context ctx)
+{
+ krb5_error_code code;
+ krb5_data request = empty_data(), reply = empty_data();
+ krb5_data realm = empty_data();
+ unsigned int flags = 0;
+ int tcp_only = 0, use_master;
+
+ for (;;) {
+ /* Get the next request and realm. Turn on TCP if necessary. */
+ code = krb5_tkt_creds_step(context, ctx, &reply, &request, &realm,
+ &flags);
+ if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !tcp_only)
+ tcp_only = 1;
+ else if (code != 0 || (flags & 1) == 0)
+ break;
+ krb5_free_data_contents(context, &reply);
+
+ /* Send it to a KDC for the appropriate realm. */
+ use_master = 0;
+ code = krb5_sendto_kdc(context, &request, &realm,
+ &reply, &use_master, tcp_only);
+ if (code != 0)
+ break;
+
+ krb5_free_data_contents(context, &request);
+ krb5_free_data_contents(context, &realm);
+ }
+
+ krb5_free_data_contents(context, &request);
+ krb5_free_data_contents(context, &reply);
+ krb5_free_data_contents(context, &realm);
+ return code;
+}
+
krb5_error_code KRB5_CALLCONV
krb5_tkt_creds_step(krb5_context context, krb5_tkt_creds_context ctx,
krb5_data *in, krb5_data *out, krb5_data *realm,