/*
- * 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 21131 2007-06-18 20:48:09Z 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;
}
*/
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;
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;
}
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);
(*res)[num_srv++] = hi;
hi->proto = proto_num;
-
+
hi->def_port = def_port;
if (port != 0)
hi->port = port;
}
*count = num_srv;
-
- dns_free_data(r);
+
+ rk_dns_free_data(r);
return 0;
}
#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;
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'
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){
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;
}
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) {
{
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;
}
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;
hi = parse_hostspec(context, kd, host, def_port, port);
if(hi == NULL)
return ENOMEM;
-
+
append_host_hostinfo(kd, hi);
return 0;
}
* 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 = "";
* in `host'. free:ing is handled by krb5_krbhst_free.
*/
-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)
{
if (host->ai == NULL) {
make_hints(&hints, host->proto);
+ hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
snprintf (portstr, sizeof(portstr), "%d", host->port);
+
+ /* First try this as an IP address - the flags we have set
+ * will prevent it from looking up a name */
ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
+ if (ret == 0) {
+ *ai = host->ai;
+ return 0;
+ }
+
+ hints.ai_flags &= ~AI_NUMERICHOST;
+
+ /* Now that we know it's not an IP, we can manipulate
+ it as a dotted-name, to add a final . if we think
+ it's a fully qualified DNS name */
+ if (strchr(host->hostname, '.') &&
+ host->hostname[strlen(host->hostname)-1] != '.') {
+ char *hostname_dot = NULL;
+
+ /* avoid expansion of search domains from resolv.conf
+ - these can be very slow if the DNS server is not up
+ for the searched domain */
+ hostname_dot = malloc(strlen(host->hostname)+2);
+ if (hostname_dot) {
+ strcpy(hostname_dot, host->hostname);
+ hostname_dot[strlen(host->hostname)] = '.';
+ hostname_dot[strlen(host->hostname)+1] = 0;
+ }
+ ret = getaddrinfo(hostname_dot?hostname_dot:host->hostname, portstr, &hints, &host->ai);
+ if (hostname_dot)
+ free(hostname_dot);
+ } else {
+ ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
+ }
if (ret)
return krb5_eai_to_heim_errno(ret, errno);
}
}
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]);
*/
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;
/*
* 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;
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)
*/
if(kd->fallback_count == 0)
asprintf(&host, "%s.%s.", serv_string, kd->realm);
else
- asprintf(&host, "%s-%d.%s.",
- serv_string, kd->fallback_count, kd->realm);
+ asprintf(&host, "%s-%d.%s.",
+ serv_string, kd->fallback_count, kd->realm);
if (host == NULL)
return ENOMEM;
-
+
make_hints(&hints, proto);
snprintf(portstr, sizeof(portstr), "%d", port);
ret = getaddrinfo(host, portstr, &hints, &ai);
* 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;
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;
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;
(*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);
}
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) {
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;
return 0;
}
+ _krb5_debug(context, 0, "No KDC entries found for %s", kd->realm);
+
return KRB5_KDC_UNREACH; /* XXX */
}
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) {
return 0;
}
+ _krb5_debug(context, 0, "No admin entries found for realm %s", kd->realm);
+
return KRB5_KDC_UNREACH; /* XXX */
}
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) {
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
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) {
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)
{
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;
* 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,
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,
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;
* 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)
* 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,
}
-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;
/* 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;
while(krb5_krbhst_next(context, handle, &hostinfo) == 0)
nhost++;
- if(nhost == 0)
+ if(nhost == 0) {
+ 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));
if(*hostlist == NULL) {
krb5_krbhst_free(context, handle);
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);
return ENOMEM;
}
}
- (*hostlist)[nhost++] = NULL;
+ (*hostlist)[nhost] = NULL;
krb5_krbhst_free(context, handle);
return 0;
}
* 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)
* 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)
* 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)
* 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)
* 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)
{