diff options
Diffstat (limited to 'lib/krb5/krbhst.c')
| -rw-r--r-- | lib/krb5/krbhst.c | 355 | 
1 files changed, 233 insertions, 122 deletions
| diff --git a/lib/krb5/krbhst.c b/lib/krb5/krbhst.c index 094fd4f9c64d..3242cdb99956 100644 --- a/lib/krb5/krbhst.c +++ b/lib/krb5/krbhst.c @@ -1,50 +1,48 @@  /* - * Copyright (c) 2001 - 2003 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden).  - * All rights reserved.  + * Copyright (c) 2001 - 2003 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved.   * - * Redistribution and use in source and binary forms, with or without  - * modification, are permitted provided that the following conditions  - * are met:  + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met:   * - * 1. Redistributions of source code must retain the above copyright  - *    notice, this list of conditions and the following disclaimer.  + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer.   * - * 2. Redistributions in binary form must reproduce the above copyright  - *    notice, this list of conditions and the following disclaimer in the  - *    documentation and/or other materials provided with the distribution.  + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution.   * - * 3. Neither the name of the Institute nor the names of its contributors  - *    may be used to endorse or promote products derived from this software  - *    without specific prior written permission.  + * 3. Neither the name of the Institute nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission.   * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  - * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  - * SUCH DAMAGE.  + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE.   */  #include "krb5_locl.h"  #include <resolve.h>  #include "locate_plugin.h" -RCSID("$Id: krbhst.c 21457 2007-07-10 12:53:25Z lha $"); -  static int  string_to_proto(const char *string)  {      if(strcasecmp(string, "udp") == 0)  	return KRB5_KRBHST_UDP; -    else if(strcasecmp(string, "tcp") == 0)  +    else if(strcasecmp(string, "tcp") == 0)  	return KRB5_KRBHST_TCP; -    else if(strcasecmp(string, "http") == 0)  +    else if(strcasecmp(string, "http") == 0)  	return KRB5_KRBHST_HTTP;      return -1;  } @@ -56,13 +54,13 @@ string_to_proto(const char *string)   */  static krb5_error_code -srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,  +srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,  	       const char *realm, const char *dns_type,  	       const char *proto, const char *service, int port)  {      char domain[1024]; -    struct dns_reply *r; -    struct resource_record *rr; +    struct rk_dns_reply *r; +    struct rk_resource_record *rr;      int num_srv;      int proto_num;      int def_port; @@ -72,7 +70,9 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,      proto_num = string_to_proto(proto);      if(proto_num < 0) { -	krb5_set_error_string(context, "unknown protocol `%s'", proto); +	krb5_set_error_message(context, EINVAL, +			       N_("unknown protocol `%s' to lookup", ""), +			       proto);  	return EINVAL;      } @@ -85,31 +85,35 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,      snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm); -    r = dns_lookup(domain, dns_type); -    if(r == NULL) +    r = rk_dns_lookup(domain, dns_type); +    if(r == NULL) { +	_krb5_debug(context, 0, +		    "DNS lookup failed domain: %s", domain);  	return KRB5_KDC_UNREACH; +    } -    for(num_srv = 0, rr = r->head; rr; rr = rr->next)  -	if(rr->type == T_SRV) +    for(num_srv = 0, rr = r->head; rr; rr = rr->next) +	if(rr->type == rk_ns_t_srv)  	    num_srv++;      *res = malloc(num_srv * sizeof(**res));      if(*res == NULL) { -	dns_free_data(r); -	krb5_set_error_string(context, "malloc: out of memory"); +	rk_dns_free_data(r); +	krb5_set_error_message(context, ENOMEM, +			       N_("malloc: out of memory", ""));  	return ENOMEM;      } -    dns_srv_order(r); +    rk_dns_srv_order(r); -    for(num_srv = 0, rr = r->head; rr; rr = rr->next)  -	if(rr->type == T_SRV) { +    for(num_srv = 0, rr = r->head; rr; rr = rr->next) +	if(rr->type == rk_ns_t_srv) {  	    krb5_krbhst_info *hi;  	    size_t len = strlen(rr->u.srv->target);  	    hi = calloc(1, sizeof(*hi) + len);  	    if(hi == NULL) { -		dns_free_data(r); +		rk_dns_free_data(r);  		while(--num_srv >= 0)  		    free((*res)[num_srv]);  		free(*res); @@ -119,7 +123,7 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,  	    (*res)[num_srv++] = hi;  	    hi->proto = proto_num; -	     +  	    hi->def_port = def_port;  	    if (port != 0)  		hi->port = port; @@ -130,8 +134,8 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,  	}      *count = num_srv; -	     -    dns_free_data(r); + +    rk_dns_free_data(r);      return 0;  } @@ -149,7 +153,7 @@ struct krb5_krbhst_data {  #define KD_CONFIG_EXISTS	32  #define KD_LARGE_MSG		64  #define KD_PLUGIN	       128 -    krb5_error_code (*get_next)(krb5_context, struct krb5_krbhst_data *,  +    krb5_error_code (*get_next)(krb5_context, struct krb5_krbhst_data *,  				krb5_krbhst_info**);      unsigned int fallback_count; @@ -175,6 +179,15 @@ krbhst_get_default_proto(struct krb5_krbhst_data *kd)      return KRB5_KRBHST_UDP;  } +/* + * + */ + +const char * +_krb5_krbhst_get_realm(krb5_krbhst_handle handle) +{ +    return handle->realm; +}  /*   * parse `spec' into a krb5_krbhst_info, defaulting the port to `def_port' @@ -185,13 +198,13 @@ static struct krb5_krbhst_info*  parse_hostspec(krb5_context context, struct krb5_krbhst_data *kd,  	       const char *spec, int def_port, int port)  { -    const char *p = spec; +    const char *p = spec, *q;      struct krb5_krbhst_info *hi; -     +      hi = calloc(1, sizeof(*hi) + strlen(spec));      if(hi == NULL)  	return NULL; -        +      hi->proto = krbhst_get_default_proto(kd);      if(strncmp(p, "http://", 7) == 0){ @@ -208,7 +221,17 @@ parse_hostspec(krb5_context context, struct krb5_krbhst_data *kd,  	p += 4;      } -    if(strsep_copy(&p, ":", hi->hostname, strlen(spec) + 1) < 0) { +    if (p[0] == '[' && (q = strchr(p, ']')) != NULL) { +	/* if address looks like [foo:bar] or [foo:bar]: its a ipv6 +	   adress, strip of [] */ +	memcpy(hi->hostname, &p[1], q - p - 1); +	hi->hostname[q - p - 1] = '\0'; +	p = q + 1; +	/* get trailing : */ +	if (p[0] == ':') +	    p++; +    } else if(strsep_copy(&p, ":", hi->hostname, strlen(spec) + 1) < 0) { +	/* copy everything before : */  	free(hi);  	return NULL;      } @@ -217,7 +240,7 @@ parse_hostspec(krb5_context context, struct krb5_krbhst_data *kd,      strlwr(hi->hostname);      hi->port = hi->def_port = def_port; -    if(p != NULL) { +    if(p != NULL && p[0]) {  	char *end;  	hi->port = strtol(p, &end, 0);  	if(end == p) { @@ -245,9 +268,10 @@ _krb5_krbhost_info_move(krb5_context context,  {      size_t hostnamelen = strlen(from->hostname);      /* trailing NUL is included in structure */ -    *to = calloc(1, sizeof(**to) + hostnamelen);  +    *to = calloc(1, sizeof(**to) + hostnamelen);      if(*to == NULL) { -	krb5_set_error_string(context, "malloc - out of memory"); +	krb5_set_error_message(context, ENOMEM, +			       N_("malloc: out of memory", ""));  	return ENOMEM;      } @@ -268,8 +292,8 @@ append_host_hostinfo(struct krb5_krbhst_data *kd, struct krb5_krbhst_info *host)      struct krb5_krbhst_info *h;      for(h = kd->hosts; h; h = h->next) -	if(h->proto == host->proto &&  -	   h->port == host->port &&  +	if(h->proto == host->proto && +	   h->port == host->port &&  	   strcmp(h->hostname, host->hostname) == 0) {  	    _krb5_free_krbhst_info(host);  	    return; @@ -287,7 +311,7 @@ append_host_string(krb5_context context, struct krb5_krbhst_data *kd,      hi = parse_hostspec(context, kd, host, def_port, port);      if(hi == NULL)  	return ENOMEM; -     +      append_host_hostinfo(kd, hi);      return 0;  } @@ -296,8 +320,8 @@ append_host_string(krb5_context context, struct krb5_krbhst_data *kd,   * return a readable representation of `host' in `hostname, hostlen'   */ -krb5_error_code KRB5_LIB_FUNCTION -krb5_krbhst_format_string(krb5_context context, const krb5_krbhst_info *host,  +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_krbhst_format_string(krb5_context context, const krb5_krbhst_info *host,  			  char *hostname, size_t hostlen)  {      const char *proto = ""; @@ -332,28 +356,66 @@ make_hints(struct addrinfo *hints, int proto)      }  } -/* - * return an `struct addrinfo *' in `ai' corresponding to the information - * in `host'.  free:ing is handled by krb5_krbhst_free. +/** + * Return an `struct addrinfo *' for a KDC host. + * + * Returns an the struct addrinfo in in that corresponds to the + * information in `host'.  free:ing is handled by krb5_krbhst_free, so + * the returned ai must not be released. + * + * @ingroup krb5   */ -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL  krb5_krbhst_get_addrinfo(krb5_context context, krb5_krbhst_info *host,  			 struct addrinfo **ai)  { -    struct addrinfo hints; -    char portstr[NI_MAXSERV]; -    int ret; +    int ret = 0;      if (host->ai == NULL) { -	make_hints(&hints, host->proto); +	struct addrinfo hints; +	char portstr[NI_MAXSERV]; +	char *hostname = host->hostname; +  	snprintf (portstr, sizeof(portstr), "%d", host->port); +	make_hints(&hints, host->proto); + +	/** +	 * First try this as an IP address, this allows us to add a +	 * dot at the end to stop using the search domains. +	 */ + +	hints.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV; +  	ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai); -	if (ret) -	    return krb5_eai_to_heim_errno(ret, errno); +	if (ret == 0) +	    goto out; + +	/** +	 * If the hostname contains a dot, assumes it's a FQDN and +	 * don't use search domains since that might be painfully slow +	 * when machine is disconnected from that network. +	 */ + +	hints.ai_flags &= ~(AI_NUMERICHOST); + +	if (strchr(hostname, '.') && hostname[strlen(hostname) - 1] != '.') { +	    ret = asprintf(&hostname, "%s.", host->hostname); +	    if (ret < 0 || hostname == NULL) +		return ENOMEM; +	} + +	ret = getaddrinfo(hostname, portstr, &hints, &host->ai); +	if (hostname != host->hostname) +	    free(hostname); +	if (ret) { +	    ret = krb5_eai_to_heim_errno(ret, errno); +	    goto out; +	}      } + out:      *ai = host->ai; -    return 0; +    return ret;  }  static krb5_boolean @@ -369,14 +431,18 @@ get_next(struct krb5_krbhst_data *kd, krb5_krbhst_info **host)  }  static void -srv_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,  +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 (srv_find_realm(context, &res, &count, kd->realm, "SRV", proto, service, -		       kd->port)) +    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]); @@ -389,15 +455,17 @@ srv_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,   */  static void -config_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,  +config_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,  		 const char *conf_string)  {      int i; -	      char **hostlist; -    hostlist = krb5_config_get_strings(context, NULL,  +    hostlist = krb5_config_get_strings(context, NULL,  				       "realms", kd->realm, conf_string, NULL); +    _krb5_debug(context, 2, "configuration file for realm %s%s found", +		kd->realm, hostlist ? "" : " not"); +      if(hostlist == NULL)  	return;      kd->flags |= KD_CONFIG_EXISTS; @@ -410,21 +478,24 @@ config_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,  /*   * as a fallback, look for `serv_string.kd->realm' (typically   * kerberos.REALM, kerberos-1.REALM, ... - * `port' is the default port for the service, and `proto' the  + * `port' is the default port for the service, and `proto' the   * protocol   */  static krb5_error_code -fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,  +fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,  		   const char *serv_string, int port, int proto)  { -    char *host; +    char *host = NULL;      int ret;      struct addrinfo *ai;      struct addrinfo hints;      char portstr[NI_MAXSERV]; -    /*  +    _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)       */ @@ -434,14 +505,14 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,      }      if(kd->fallback_count == 0) -	asprintf(&host, "%s.%s.", serv_string, kd->realm); +	ret = asprintf(&host, "%s.%s.", serv_string, kd->realm);      else -	asprintf(&host, "%s-%d.%s.",  -		 serv_string, kd->fallback_count, kd->realm);	     +	ret = asprintf(&host, "%s-%d.%s.", +		       serv_string, kd->fallback_count, kd->realm); -    if (host == NULL) +    if (ret < 0 || host == NULL)  	return ENOMEM; -     +      make_hints(&hints, proto);      snprintf(portstr, sizeof(portstr), "%d", port);      ret = getaddrinfo(host, portstr, &hints, &ai); @@ -475,7 +546,7 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,   * Fetch hosts from plugin   */ -static krb5_error_code  +static krb5_error_code  add_locate(void *ctx, int type, struct sockaddr *addr)  {      struct krb5_krbhst_info *hi; @@ -503,7 +574,7 @@ add_locate(void *ctx, int type, struct sockaddr *addr)      hi = calloc(1, sizeof(*hi) + hostlen);      if(hi == NULL)  	return ENOMEM; -     +      hi->proto = krbhst_get_default_proto(kd);      hi->port  = hi->def_port = socket_get_port(addr);      hi->ai    = ai; @@ -522,12 +593,11 @@ plugin_get_hosts(krb5_context context,      struct krb5_plugin *list = NULL, *e;      krb5_error_code ret; -    ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, "resolve", &list); +    ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, +			    KRB5_PLUGIN_LOCATE, &list);      if(ret != 0 || list == NULL)  	return; -    kd->flags |= KD_CONFIG_EXISTS; -      for (e = list; e != NULL; e = _krb5_plugin_get_next(e)) {  	krb5plugin_service_locate_ftable *service;  	void *ctx; @@ -535,14 +605,20 @@ plugin_get_hosts(krb5_context context,  	service = _krb5_plugin_get_symbol(e);  	if (service->minor_version != 0)  	    continue; -	 +  	(*service->init)(context, &ctx);  	ret = (*service->lookup)(ctx, type, kd->realm, 0, 0, add_locate, kd);  	(*service->fini)(ctx); -	if (ret) { -	    krb5_set_error_string(context, "Plugin failed to lookup"); +	if (ret && ret != KRB5_PLUGIN_NO_HANDLE) { +	    krb5_set_error_message(context, ret, +				   N_("Locate plugin failed to lookup realm %s: %d", ""), +				   kd->realm, ret);  	    break; +	} else if (ret == 0) { +	    _krb5_debug(context, 2, "plugin found result for realm %s", kd->realm); +	    kd->flags |= KD_CONFIG_EXISTS;  	} +      }      _krb5_plugin_free(list);  } @@ -572,8 +648,12 @@ kdc_get_next(krb5_context context,  	    return 0;      } -    if (kd->flags & KD_CONFIG_EXISTS) -	return KRB5_KDC_UNREACH; /* XXX */ +    if (kd->flags & KD_CONFIG_EXISTS) { +	_krb5_debug(context, 1, +		    "Configuration exists for realm %s, wont go to DNS", +		    kd->realm); +	return KRB5_KDC_UNREACH; +    }      if(context->srv_lookup) {  	if((kd->flags & KD_SRV_UDP) == 0 && (kd->flags & KD_LARGE_MSG) == 0) { @@ -599,7 +679,7 @@ kdc_get_next(krb5_context context,      while((kd->flags & KD_FALLBACK) == 0) {  	ret = fallback_get_hosts(context, kd, "kerberos", -				 kd->def_port,  +				 kd->def_port,  				 krbhst_get_default_proto(kd));  	if(ret)  	    return ret; @@ -607,6 +687,8 @@ kdc_get_next(krb5_context context,  	    return 0;      } +    _krb5_debug(context, 0, "No KDC entries found for %s", kd->realm); +      return KRB5_KDC_UNREACH; /* XXX */  } @@ -631,8 +713,12 @@ admin_get_next(krb5_context context,  	    return 0;      } -    if (kd->flags & KD_CONFIG_EXISTS) -	return KRB5_KDC_UNREACH; /* XXX */ +    if (kd->flags & KD_CONFIG_EXISTS) { +	_krb5_debug(context, 1, +		    "Configuration exists for realm %s, wont go to DNS", +		    kd->realm); +	return KRB5_KDC_UNREACH; +    }      if(context->srv_lookup) {  	if((kd->flags & KD_SRV_TCP) == 0) { @@ -655,6 +741,8 @@ admin_get_next(krb5_context context,  	    return 0;      } +    _krb5_debug(context, 0, "No admin entries found for realm %s", kd->realm); +      return KRB5_KDC_UNREACH;	/* XXX */  } @@ -679,8 +767,12 @@ kpasswd_get_next(krb5_context context,  	    return 0;      } -    if (kd->flags & KD_CONFIG_EXISTS) -	return KRB5_KDC_UNREACH; /* XXX */ +    if (kd->flags & KD_CONFIG_EXISTS) { +	_krb5_debug(context, 1, +		    "Configuration exists for realm %s, wont go to DNS", +		    kd->realm); +	return KRB5_KDC_UNREACH; +    }      if(context->srv_lookup) {  	if((kd->flags & KD_SRV_UDP) == 0) { @@ -709,7 +801,9 @@ kpasswd_get_next(krb5_context context,  	return ret;      } -    return KRB5_KDC_UNREACH; /* XXX */ +    _krb5_debug(context, 0, "No kpasswd entries found for realm %s", kd->realm); + +    return KRB5_KDC_UNREACH;  }  static krb5_error_code @@ -731,8 +825,12 @@ krb524_get_next(krb5_context context,  	kd->flags |= KD_CONFIG;      } -    if (kd->flags & KD_CONFIG_EXISTS) -	return KRB5_KDC_UNREACH; /* XXX */ +    if (kd->flags & KD_CONFIG_EXISTS) { +	_krb5_debug(context, 1, +		    "Configuration exists for realm %s, wont go to DNS", +		    kd->realm); +	return KRB5_KDC_UNREACH; +    }      if(context->srv_lookup) {  	if((kd->flags & KD_SRV_UDP) == 0) { @@ -759,11 +857,14 @@ krb524_get_next(krb5_context context,  	return (*kd->get_next)(context, kd, host);      } -    return KRB5_KDC_UNREACH; /* XXX */ +    _krb5_debug(context, 0, "No kpasswd entries found for realm %s", kd->realm); + +    return KRB5_KDC_UNREACH;  }  static struct krb5_krbhst_data*  common_init(krb5_context context, +	    const char *service,  	    const char *realm,  	    int flags)  { @@ -777,6 +878,9 @@ common_init(krb5_context context,  	return NULL;      } +    _krb5_debug(context, 2, "Trying to find service %s for realm %s flags %x", +		service, realm, flags); +      /* For 'realms' without a . do not even think of going to DNS */      if (!strchr(realm, '.'))  	kd->flags |= KD_CONFIG_EXISTS; @@ -791,7 +895,7 @@ common_init(krb5_context context,   * initialize `handle' to look for hosts of type `type' in realm `realm'   */ -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL  krb5_krbhst_init(krb5_context context,  		 const char *realm,  		 unsigned int type, @@ -800,7 +904,7 @@ krb5_krbhst_init(krb5_context context,      return krb5_krbhst_init_flags(context, realm, type, 0, handle);  } -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL  krb5_krbhst_init_flags(krb5_context context,  		       const char *realm,  		       unsigned int type, @@ -808,34 +912,40 @@ krb5_krbhst_init_flags(krb5_context context,  		       krb5_krbhst_handle *handle)  {      struct krb5_krbhst_data *kd; -    krb5_error_code (*next)(krb5_context, struct krb5_krbhst_data *,  +    krb5_error_code (*next)(krb5_context, struct krb5_krbhst_data *,  			    krb5_krbhst_info **);      int def_port; +    const char *service;      switch(type) {      case KRB5_KRBHST_KDC:  	next = kdc_get_next;  	def_port = ntohs(krb5_getportbyname (context, "kerberos", "udp", 88)); +	service = "kdc";  	break;      case KRB5_KRBHST_ADMIN:  	next = admin_get_next;  	def_port = ntohs(krb5_getportbyname (context, "kerberos-adm",  					     "tcp", 749)); +	service = "admin";  	break;      case KRB5_KRBHST_CHANGEPW:  	next = kpasswd_get_next;  	def_port = ntohs(krb5_getportbyname (context, "kpasswd", "udp",  					     KPASSWD_PORT)); +	service = "change_password";  	break;      case KRB5_KRBHST_KRB524:  	next = krb524_get_next;  	def_port = ntohs(krb5_getportbyname (context, "krb524", "udp", 4444)); +	service = "524";  	break;      default: -	krb5_set_error_string(context, "unknown krbhst type (%u)", type); +	krb5_set_error_message(context, ENOTTY, +			       N_("unknown krbhst type (%u)", ""), type);  	return ENOTTY;      } -    if((kd = common_init(context, realm, flags)) == NULL) +    if((kd = common_init(context, service, realm, flags)) == NULL)  	return ENOMEM;      kd->get_next = next;      kd->def_port = def_port; @@ -847,7 +957,7 @@ krb5_krbhst_init_flags(krb5_context context,   * return the next host information from `handle' in `host'   */ -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL  krb5_krbhst_next(krb5_context context,  		 krb5_krbhst_handle handle,  		 krb5_krbhst_info **host) @@ -863,7 +973,7 @@ krb5_krbhst_next(krb5_context context,   * in `hostname' (or length `hostlen)   */ -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL  krb5_krbhst_next_as_string(krb5_context context,  			   krb5_krbhst_handle handle,  			   char *hostname, @@ -878,13 +988,13 @@ krb5_krbhst_next_as_string(krb5_context context,  } -void KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION void KRB5_LIB_CALL  krb5_krbhst_reset(krb5_context context, krb5_krbhst_handle handle)  {      handle->index = &handle->hosts;  } -void KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION void KRB5_LIB_CALL  krb5_krbhst_free(krb5_context context, krb5_krbhst_handle handle)  {      krb5_krbhst_info *h, *next; @@ -904,7 +1014,7 @@ krb5_krbhst_free(krb5_context context, krb5_krbhst_handle handle)  /* backwards compatibility ahead */  static krb5_error_code -gethostlist(krb5_context context, const char *realm,  +gethostlist(krb5_context context, const char *realm,  	    unsigned int type, char ***hostlist)  {      krb5_error_code ret; @@ -920,7 +1030,8 @@ gethostlist(krb5_context context, const char *realm,      while(krb5_krbhst_next(context, handle, &hostinfo) == 0)  	nhost++;      if(nhost == 0) { -	krb5_set_error_string(context, "No KDC found for realm %s", realm); +	krb5_set_error_message(context, KRB5_KDC_UNREACH, +			       N_("No KDC found for realm %s", ""), realm);  	return KRB5_KDC_UNREACH;      }      *hostlist = calloc(nhost + 1, sizeof(**hostlist)); @@ -931,7 +1042,7 @@ gethostlist(krb5_context context, const char *realm,      krb5_krbhst_reset(context, handle);      nhost = 0; -    while(krb5_krbhst_next_as_string(context, handle,  +    while(krb5_krbhst_next_as_string(context, handle,  				     host, sizeof(host)) == 0) {  	if(((*hostlist)[nhost++] = strdup(host)) == NULL) {  	    krb5_free_krbhst(context, *hostlist); @@ -939,7 +1050,7 @@ gethostlist(krb5_context context, const char *realm,  	    return ENOMEM;  	}      } -    (*hostlist)[nhost++] = NULL; +    (*hostlist)[nhost] = NULL;      krb5_krbhst_free(context, handle);      return 0;  } @@ -948,7 +1059,7 @@ gethostlist(krb5_context context, const char *realm,   * return an malloced list of kadmin-hosts for `realm' in `hostlist'   */ -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL  krb5_get_krb_admin_hst (krb5_context context,  			const krb5_realm *realm,  			char ***hostlist) @@ -960,7 +1071,7 @@ krb5_get_krb_admin_hst (krb5_context context,   * return an malloced list of changepw-hosts for `realm' in `hostlist'   */ -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL  krb5_get_krb_changepw_hst (krb5_context context,  			   const krb5_realm *realm,  			   char ***hostlist) @@ -972,7 +1083,7 @@ krb5_get_krb_changepw_hst (krb5_context context,   * return an malloced list of 524-hosts for `realm' in `hostlist'   */ -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL  krb5_get_krb524hst (krb5_context context,  		    const krb5_realm *realm,  		    char ***hostlist) @@ -985,7 +1096,7 @@ krb5_get_krb524hst (krb5_context context,   * return an malloced list of KDC's for `realm' in `hostlist'   */ -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL  krb5_get_krbhst (krb5_context context,  		 const krb5_realm *realm,  		 char ***hostlist) @@ -997,7 +1108,7 @@ krb5_get_krbhst (krb5_context context,   * free all the memory allocated in `hostlist'   */ -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL  krb5_free_krbhst (krb5_context context,  		  char **hostlist)  { | 
