86
86
snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm);
88
88
r = rk_dns_lookup(domain, dns_type);
90
_krb5_debug(context, 0,
91
"DNS lookup failed domain: %s", domain);
90
92
return KRB5_KDC_UNREACH;
92
95
for(num_srv = 0, rr = r->head; rr; rr = rr->next)
93
96
if(rr->type == rk_ns_t_srv)
186
198
parse_hostspec(krb5_context context, struct krb5_krbhst_data *kd,
187
199
const char *spec, int def_port, int port)
189
const char *p = spec;
201
const char *p = spec, *q;
190
202
struct krb5_krbhst_info *hi;
192
204
hi = calloc(1, sizeof(*hi) + strlen(spec));
212
if(strsep_copy(&p, ":", hi->hostname, strlen(spec) + 1) < 0) {
224
if (p[0] == '[' && (q = strchr(p, ']')) != NULL) {
225
/* if address looks like [foo:bar] or [foo:bar]: its a ipv6
226
adress, strip of [] */
227
memcpy(hi->hostname, &p[1], q - p - 1);
228
hi->hostname[q - p - 1] = '\0';
233
} else if(strsep_copy(&p, ":", hi->hostname, strlen(spec) + 1) < 0) {
234
/* copy everything before : */
298
320
* return a readable representation of `host' in `hostname, hostlen'
301
krb5_error_code KRB5_LIB_FUNCTION
323
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
302
324
krb5_krbhst_format_string(krb5_context context, const krb5_krbhst_info *host,
303
325
char *hostname, size_t hostlen)
338
* return an `struct addrinfo *' in `ai' corresponding to the information
339
* in `host'. free:ing is handled by krb5_krbhst_free.
360
* Return an `struct addrinfo *' for a KDC host.
362
* Returns an the struct addrinfo in in that corresponds to the
363
* information in `host'. free:ing is handled by krb5_krbhst_free, so
364
* the returned ai must not be released.
342
krb5_error_code KRB5_LIB_FUNCTION
369
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
343
370
krb5_krbhst_get_addrinfo(krb5_context context, krb5_krbhst_info *host,
344
371
struct addrinfo **ai)
346
struct addrinfo hints;
347
char portstr[NI_MAXSERV];
350
375
if (host->ai == NULL) {
376
struct addrinfo hints;
377
char portstr[NI_MAXSERV];
378
char *hostname = host->hostname;
380
snprintf (portstr, sizeof(portstr), "%d", host->port);
351
381
make_hints(&hints, host->proto);
352
snprintf (portstr, sizeof(portstr), "%d", host->port);
384
* First try this as an IP address, this allows us to add a
385
* dot at the end to stop using the search domains.
388
hints.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV;
353
390
ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
355
return krb5_eai_to_heim_errno(ret, errno);
395
* If the hostname contains a dot, assumes it's a FQDN and
396
* don't use search domains since that might be painfully slow
397
* when machine is disconnected from that network.
400
hints.ai_flags &= ~(AI_NUMERICHOST);
402
if (strchr(hostname, '.') && hostname[strlen(hostname) - 1] != '.') {
403
ret = asprintf(&hostname, "%s.", host->hostname);
404
if (ret < 0 || hostname == NULL)
408
ret = getaddrinfo(hostname, portstr, &hints, &host->ai);
409
if (hostname != host->hostname)
412
ret = krb5_eai_to_heim_errno(ret, errno);
361
421
static krb5_boolean
374
434
srv_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
375
435
const char *proto, const char *service)
377
438
krb5_krbhst_info **res;
380
if (srv_find_realm(context, &res, &count, kd->realm, "SRV", proto, service,
441
ret = srv_find_realm(context, &res, &count, kd->realm, "SRV", proto, service,
443
_krb5_debug(context, 2, "searching DNS for realm %s %s.%s -> %d",
444
kd->realm, proto, service, ret);
383
447
for(i = 0; i < count; i++)
384
448
append_host_hostinfo(kd, res[i]);
395
459
const char *conf_string)
400
463
hostlist = krb5_config_get_strings(context, NULL,
401
464
"realms", kd->realm, conf_string, NULL);
466
_krb5_debug(context, 2, "configuration file for realm %s%s found",
467
kd->realm, hostlist ? "" : " not");
403
469
if(hostlist == NULL)
405
471
kd->flags |= KD_CONFIG_EXISTS;
420
486
fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
421
487
const char *serv_string, int port, int proto)
425
491
struct addrinfo *ai;
426
492
struct addrinfo hints;
427
493
char portstr[NI_MAXSERV];
495
_krb5_debug(context, 2, "fallback lookup %d for realm %s (service %s)",
496
kd->fallback_count, kd->realm, serv_string);
430
499
* Don't try forever in case the DNS server keep returning us
431
500
* entries (like wildcard entries or the .nu TLD)
438
507
if(kd->fallback_count == 0)
439
asprintf(&host, "%s.%s.", serv_string, kd->realm);
508
ret = asprintf(&host, "%s.%s.", serv_string, kd->realm);
441
asprintf(&host, "%s-%d.%s.",
442
serv_string, kd->fallback_count, kd->realm);
510
ret = asprintf(&host, "%s-%d.%s.",
511
serv_string, kd->fallback_count, kd->realm);
513
if (ret < 0 || host == NULL)
447
516
make_hints(&hints, proto);
545
614
N_("Locate plugin failed to lookup realm %s: %d", ""),
617
} else if (ret == 0) {
618
_krb5_debug(context, 2, "plugin found result for realm %s", kd->realm);
549
619
kd->flags |= KD_CONFIG_EXISTS;
552
623
_krb5_plugin_free(list);
580
if (kd->flags & KD_CONFIG_EXISTS)
581
return KRB5_KDC_UNREACH; /* XXX */
651
if (kd->flags & KD_CONFIG_EXISTS) {
652
_krb5_debug(context, 1,
653
"Configuration exists for realm %s, wont go to DNS",
655
return KRB5_KDC_UNREACH;
583
658
if(context->srv_lookup) {
584
659
if((kd->flags & KD_SRV_UDP) == 0 && (kd->flags & KD_LARGE_MSG) == 0) {
639
if (kd->flags & KD_CONFIG_EXISTS)
640
return KRB5_KDC_UNREACH; /* XXX */
716
if (kd->flags & KD_CONFIG_EXISTS) {
717
_krb5_debug(context, 1,
718
"Configuration exists for realm %s, wont go to DNS",
720
return KRB5_KDC_UNREACH;
642
723
if(context->srv_lookup) {
643
724
if((kd->flags & KD_SRV_TCP) == 0) {
687
if (kd->flags & KD_CONFIG_EXISTS)
688
return KRB5_KDC_UNREACH; /* XXX */
770
if (kd->flags & KD_CONFIG_EXISTS) {
771
_krb5_debug(context, 1,
772
"Configuration exists for realm %s, wont go to DNS",
774
return KRB5_KDC_UNREACH;
690
777
if(context->srv_lookup) {
691
778
if((kd->flags & KD_SRV_UDP) == 0) {
736
825
kd->flags |= KD_CONFIG;
739
if (kd->flags & KD_CONFIG_EXISTS)
740
return KRB5_KDC_UNREACH; /* XXX */
828
if (kd->flags & KD_CONFIG_EXISTS) {
829
_krb5_debug(context, 1,
830
"Configuration exists for realm %s, wont go to DNS",
832
return KRB5_KDC_UNREACH;
742
835
if(context->srv_lookup) {
743
836
if((kd->flags & KD_SRV_UDP) == 0) {
764
857
return (*kd->get_next)(context, kd, host);
767
return KRB5_KDC_UNREACH; /* XXX */
860
_krb5_debug(context, 0, "No kpasswd entries found for realm %s", kd->realm);
862
return KRB5_KDC_UNREACH;
770
865
static struct krb5_krbhst_data*
771
866
common_init(krb5_context context,
772
868
const char *realm,
805
904
return krb5_krbhst_init_flags(context, realm, type, 0, handle);
808
krb5_error_code KRB5_LIB_FUNCTION
907
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
809
908
krb5_krbhst_init_flags(krb5_context context,
810
909
const char *realm,
811
910
unsigned int type,
816
915
krb5_error_code (*next)(krb5_context, struct krb5_krbhst_data *,
817
916
krb5_krbhst_info **);
821
921
case KRB5_KRBHST_KDC:
822
922
next = kdc_get_next;
823
923
def_port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88));
825
926
case KRB5_KRBHST_ADMIN:
826
927
next = admin_get_next;
827
928
def_port = ntohs(krb5_getportbyname (context, "kerberos-adm",
830
932
case KRB5_KRBHST_CHANGEPW:
831
933
next = kpasswd_get_next;
832
934
def_port = ntohs(krb5_getportbyname (context, "kpasswd", "udp",
936
service = "change_password";
835
938
case KRB5_KRBHST_KRB524:
836
939
next = krb524_get_next;
837
940
def_port = ntohs(krb5_getportbyname (context, "krb524", "udp", 4444));
840
944
krb5_set_error_message(context, ENOTTY,
841
945
N_("unknown krbhst type (%u)", ""), type);
844
if((kd = common_init(context, realm, flags)) == NULL)
948
if((kd = common_init(context, service, realm, flags)) == NULL)
846
950
kd->get_next = next;
847
951
kd->def_port = def_port;
853
957
* return the next host information from `handle' in `host'
856
krb5_error_code KRB5_LIB_FUNCTION
960
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
857
961
krb5_krbhst_next(krb5_context context,
858
962
krb5_krbhst_handle handle,
859
963
krb5_krbhst_info **host)
869
973
* in `hostname' (or length `hostlen)
872
krb5_error_code KRB5_LIB_FUNCTION
976
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
873
977
krb5_krbhst_next_as_string(krb5_context context,
874
978
krb5_krbhst_handle handle,
887
void KRB5_LIB_FUNCTION
991
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
888
992
krb5_krbhst_reset(krb5_context context, krb5_krbhst_handle handle)
890
994
handle->index = &handle->hosts;
893
void KRB5_LIB_FUNCTION
997
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
894
998
krb5_krbhst_free(krb5_context context, krb5_krbhst_handle handle)
896
1000
krb5_krbhst_info *h, *next;