static void srv_get_hosts(krb5_context context, struct krb5_krbhst_data *kd, const char *proto, const char *service) { krb5_error_code ret; krb5_krbhst_info **res; int count, i; if (krb5_realm_is_lkdc(kd->realm)) return; ret = srv_find_realm(context, &res, &count, kd->realm, "SRV", proto, service, kd->port); _krb5_debug(context, 2, "searching DNS for realm %s %s.%s -> %d", kd->realm, proto, service, ret); if (ret) return; for(i = 0; i < count; i++) append_host_hostinfo(kd, res[i]); free(res); }
static OM_uint32 iakerb_acceptor_start(OM_uint32 * minor_status, gsskrb5_ctx ctx, krb5_context context, const gss_cred_id_t acceptor_cred_handle, const gss_buffer_t input_token_buffer, const gss_channel_bindings_t input_chan_bindings, gss_name_t * src_name, gss_OID * mech_type, gss_buffer_t output_token, OM_uint32 * ret_flags, OM_uint32 * time_rec, gss_cred_id_t * delegated_cred_handle) { krb5_data indata, outdata; gss_buffer_desc idata; krb5_error_code kret; heim_ipc ictx; OM_uint32 ret; if (ctx->messages == NULL) { ctx->messages = krb5_storage_emem(); if (ctx->messages == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } } ret = _gsskrb5_iakerb_parse_header(minor_status, context, ctx, input_token_buffer, &indata); if (ret == GSS_S_DEFECTIVE_TOKEN) { ctx->acceptor_state = gsskrb5_acceptor_start; return GSS_S_COMPLETE; } else if (ret != GSS_S_COMPLETE) return ret; krb5_storage_write(ctx->messages, input_token_buffer->value, input_token_buffer->length); idata.value = indata.data; idata.length = indata.length; heim_assert(ctx->iakerbrealm != NULL, "realm not set by decoder, non OPT value"); if (krb5_realm_is_lkdc(ctx->iakerbrealm)) { kret = heim_ipc_init_context("ANY:org.h5l.kdc", &ictx); if (kret) { *minor_status = kret; return GSS_S_FAILURE; } kret = heim_ipc_call(ictx, &indata, &outdata, NULL); heim_ipc_free_context(ictx); if (kret) { _gsskrb5_error_token(minor_status, ctx->mech, context, kret, NULL, NULL, output_token); *minor_status = kret; return GSS_S_FAILURE; } ret = _gsskrb5_iakerb_make_header(minor_status, context, ctx, ctx->iakerbrealm, &outdata, output_token); heim_ipc_free_data(&outdata); if (ret) return ret; } else { /* XXX dont support non local realms right now */ *minor_status = EINVAL; return GSS_S_FAILURE; } krb5_storage_write(ctx->messages, output_token->value, output_token->length); return GSS_S_CONTINUE_NEEDED; }
static krb5_error_code fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd, const char *serv_string, int port, int proto) { char *host = NULL; int ret; struct addrinfo *ai; struct addrinfo hints; char portstr[NI_MAXSERV]; ret = krb5_config_get_bool_default(context, NULL, KRB5_FALLBACK_DEFAULT, "libdefaults", "use_fallback", NULL); if (!ret) { kd->flags |= KD_FALLBACK; return 0; } _krb5_debug(context, 2, "fallback lookup %d for realm %s (service %s)", kd->fallback_count, kd->realm, serv_string); /* * Don't try forever in case the DNS server keep returning us * entries (like wildcard entries or the .nu TLD) * * Also don't try LKDC realms since fallback wont work on them at all. */ if(kd->fallback_count >= 5 || krb5_realm_is_lkdc(kd->realm)) { kd->flags |= KD_FALLBACK; return 0; } if(kd->fallback_count == 0) ret = asprintf(&host, "%s.%s.", serv_string, kd->realm); else ret = asprintf(&host, "%s-%d.%s.", serv_string, kd->fallback_count, kd->realm); if (ret < 0 || host == NULL) return ENOMEM; make_hints(&hints, proto); snprintf(portstr, sizeof(portstr), "%d", port); ret = getaddrinfo(host, portstr, &hints, &ai); if (ret) { /* no more hosts, so we're done here */ free(host); kd->flags |= KD_FALLBACK; } else { struct krb5_krbhst_info *hi; size_t hostlen = strlen(host); hi = calloc(1, sizeof(*hi) + hostlen); if(hi == NULL) { free(host); return ENOMEM; } hi->proto = proto; hi->port = hi->def_port = port; hi->ai = ai; memmove(hi->hostname, host, hostlen); hi->hostname[hostlen] = '\0'; free(host); append_host_hostinfo(kd, hi); kd->fallback_count++; } return 0; }
krb5_boolean KRB5_LIB_FUNCTION krb5_principal_is_lkdc(krb5_context context, krb5_const_principal principal) { return krb5_realm_is_lkdc(principal->realm); }