diff --git a/lib/krb5/krbhst.c b/lib/krb5/krbhst.c index 4d86f465a..330c5433e 100644 --- a/lib/krb5/krbhst.c +++ b/lib/krb5/krbhst.c @@ -139,13 +139,13 @@ struct krb5_krbhst_data { unsigned int flags; int def_port; int port; /* hardwired port number if != 0 */ -#define KD_CONFIG 1 -#define KD_SRV_UDP 2 -#define KD_SRV_TCP 4 -#define KD_SRV_HTTP 8 -#define KD_FALLBACK 16 -#define KD_CONFIG_EXISTS 32 - +#define KD_CONFIG 1 +#define KD_SRV_UDP 2 +#define KD_SRV_TCP 4 +#define KD_SRV_HTTP 8 +#define KD_FALLBACK 16 +#define KD_CONFIG_EXISTS 32 +#define KD_LARGE_MSG 64 krb5_error_code (*get_next)(krb5_context, struct krb5_krbhst_data *, krb5_krbhst_info**); @@ -160,13 +160,27 @@ krbhst_empty(const struct krb5_krbhst_data *kd) return kd->index == &kd->hosts; } +/* + * Return the default protocol for the `kd' (either TCP or UDP) + */ + +static int +krbhst_get_default_proto(struct krb5_krbhst_data *kd) +{ + if (kd->flags & KD_LARGE_MSG) + return KRB5_KRBHST_TCP; + return KRB5_KRBHST_UDP; +} + + /* * parse `spec' into a krb5_krbhst_info, defaulting the port to `def_port' * and forcing it to `port' if port != 0 */ static struct krb5_krbhst_info* -parse_hostspec(krb5_context context, const char *spec, int def_port, int port) +parse_hostspec(krb5_context context, struct krb5_krbhst_data *kd, + const char *spec, int def_port, int port) { const char *p = spec; struct krb5_krbhst_info *hi; @@ -175,7 +189,7 @@ parse_hostspec(krb5_context context, const char *spec, int def_port, int port) if(hi == NULL) return NULL; - hi->proto = KRB5_KRBHST_UDP; + hi->proto = krbhst_get_default_proto(kd); if(strncmp(p, "http://", 7) == 0){ hi->proto = KRB5_KRBHST_HTTP; @@ -243,7 +257,7 @@ append_host_string(krb5_context context, struct krb5_krbhst_data *kd, { struct krb5_krbhst_info *hi; - hi = parse_hostspec(context, host, def_port, port); + hi = parse_hostspec(context, kd, host, def_port, port); if(hi == NULL) return ENOMEM; @@ -438,7 +452,7 @@ kdc_get_next(krb5_context context, return KRB5_KDC_UNREACH; /* XXX */ if(context->srv_lookup) { - if((kd->flags & KD_SRV_UDP) == 0) { + if((kd->flags & KD_SRV_UDP) == 0 && (kd->flags & KD_LARGE_MSG) == 0) { srv_get_hosts(context, kd, "udp", "kerberos"); kd->flags |= KD_SRV_UDP; if(get_next(kd, host)) @@ -461,7 +475,8 @@ kdc_get_next(krb5_context context, while((kd->flags & KD_FALLBACK) == 0) { ret = fallback_get_hosts(context, kd, "kerberos", - kd->def_port, KRB5_KRBHST_UDP); + kd->def_port, + krbhst_get_default_proto(kd)); if(ret) return ret; if(get_next(kd, host)) @@ -500,7 +515,8 @@ admin_get_next(krb5_context context, if (krbhst_empty(kd) && (kd->flags & KD_FALLBACK) == 0) { ret = fallback_get_hosts(context, kd, "kerberos", - kd->def_port, KRB5_KRBHST_UDP); + kd->def_port, + krbhst_get_default_proto(kd)); if(ret) return ret; kd->flags |= KD_FALLBACK; @@ -544,7 +560,7 @@ kpasswd_get_next(krb5_context context, kd->get_next = admin_get_next; ret = (*kd->get_next)(context, kd, host); if (ret == 0) - (*host)->proto = KRB5_KRBHST_UDP; + (*host)->proto = krbhst_get_default_proto(kd); return ret; } @@ -596,7 +612,8 @@ krb524_get_next(krb5_context context, static struct krb5_krbhst_data* common_init(krb5_context context, - const char *realm) + const char *realm, + int flags) { struct krb5_krbhst_data *kd; @@ -608,6 +625,8 @@ common_init(krb5_context context, return NULL; } + if (flags & KRB5_KRBHST_FLAGS_LARGE_MSG) + kd->flags |= KD_LARGE_MSG; kd->end = kd->index = &kd->hosts; return kd; } @@ -621,6 +640,16 @@ krb5_krbhst_init(krb5_context context, const char *realm, unsigned int type, krb5_krbhst_handle *handle) +{ + return krb5_krbhst_init_flags(context, realm, type, 0, handle); +} + +krb5_error_code +krb5_krbhst_init_flags(krb5_context context, + const char *realm, + unsigned int type, + int flags, + krb5_krbhst_handle *handle) { struct krb5_krbhst_data *kd; krb5_error_code (*get_next)(krb5_context, struct krb5_krbhst_data *, @@ -650,7 +679,7 @@ krb5_krbhst_init(krb5_context context, krb5_set_error_string(context, "unknown krbhst type (%u)", type); return ENOTTY; } - if((kd = common_init(context, realm)) == NULL) + if((kd = common_init(context, realm, flags)) == NULL) return ENOMEM; kd->get_next = get_next; kd->def_port = def_port;