/* To keep happy libraries which are (for now) accessing internal stuff */
/* Make sure to increment by one when changing the struct */
-#define KRB5INT_ACCESS_STRUCT_VERSION 21
+#define KRB5INT_ACCESS_STRUCT_VERSION 22
typedef struct _krb5int_access {
krb5_error_code (*auth_con_get_subkey_enctype)(krb5_context,
krb5_auth_context,
krb5_enctype *);
- krb5_error_code (*clean_hostname)(krb5_context, const char *, char *,
- size_t);
-
krb5_error_code (*mandatory_cksumtype)(krb5_context, krb5_enctype,
krb5_cksumtype *);
krb5_error_code (KRB5_CALLCONV *ser_pack_int64)(int64_t, krb5_octet **,
#endif
S (auth_con_get_subkey_enctype, krb5_auth_con_get_subkey_enctype),
- S (clean_hostname, k5_clean_hostname),
-
#ifndef LEAN_CLIENT
#define SC(FIELD, VAL) S(FIELD, VAL)
#else /* disable */
$(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
$(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \
$(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
- $(top_srcdir)/include/socket-utils.h dnsglue.h locate_kdc.c \
- os-proto.h
+ $(top_srcdir)/include/socket-utils.h locate_kdc.c os-proto.h
lock_file.so lock_file.po $(OUTPRE)lock_file.$(OBJEXT): \
$(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
$(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
{
krb5_error_code retval = KRB5_ERR_HOST_REALM_UNKNOWN;
const unsigned char *p, *base;
- char host[MAXDNAME];
+ char *txtname = NULL;
int ret, rdlen, len;
struct krb5int_dns_state *ds = NULL;
struct k5buf buf;
* Form our query, and send it via DNS
*/
- k5_buf_init_fixed(&buf, host, sizeof(host));
+ k5_buf_init_dynamic(&buf);
if (name == NULL || name[0] == '\0') {
k5_buf_add(&buf, prefix);
} else {
the local domain or domain search lists to be expanded.
*/
- if (buf.len > 0 && host[buf.len - 1] != '.')
+ if (buf.len > 0 && ((char *)buf.data)[buf.len - 1] != '.')
k5_buf_add(&buf, ".");
}
if (k5_buf_status(&buf) != 0)
return KRB5_ERR_HOST_REALM_UNKNOWN;
- ret = krb5int_dns_init(&ds, host, C_IN, T_TXT);
+ txtname = buf.data;
+ ret = krb5int_dns_init(&ds, txtname, C_IN, T_TXT);
if (ret < 0) {
- TRACE_TXT_LOOKUP_NOTFOUND(context, host);
+ TRACE_TXT_LOOKUP_NOTFOUND(context, txtname);
goto errout;
}
if ( (*realm)[len-1] == '.' )
(*realm)[len-1] = '\0';
retval = 0;
- TRACE_TXT_LOOKUP_SUCCESS(context, host, *realm);
+ TRACE_TXT_LOOKUP_SUCCESS(context, txtname, *realm);
errout:
- if (ds != NULL) {
- krb5int_dns_fini(ds);
- ds = NULL;
- }
+ krb5int_dns_fini(ds);
+ free(txtname);
return retval;
}
#include <sys/param.h> /* for MAXHOSTNAMELEN */
#endif
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64 /* if we can't find it elswhere */
-#endif
-
#ifndef MAXDNAME
#ifdef NS_MAXDNAME
const unsigned char *, char *, int);
void krb5int_dns_fini(struct krb5int_dns_state *);
-struct srv_dns_entry {
- struct srv_dns_entry *next;
- int priority;
- int weight;
- unsigned short port;
- char *host;
-};
-
-krb5_error_code
-krb5int_make_srv_query_realm(krb5_context context, const krb5_data *realm,
- const char *service, const char *protocol,
- struct srv_dns_entry **answers);
-
-void krb5int_free_srv_dns_data(struct srv_dns_entry *);
-
-krb5_error_code
-k5_make_uri_query(krb5_context context, const krb5_data *realm,
- const char *service, struct srv_dns_entry **answers);
-
#endif /* KRB5_DNS_LOOKUP */
#endif /* !defined(KRB5_DNSGLUE_H) */
}
}
-/* Construct a DNS label of the form "service.[protocol.]realm.", placing the
- * result into fixed_buf. protocol may be NULL. */
-static krb5_error_code
-prepare_lookup_buf(const krb5_data *realm, const char *service,
- const char *protocol, char *fixed_buf, size_t bufsize)
+/* Construct a DNS label of the form "service.[protocol.]realm.". protocol may
+ * be NULL. */
+static char *
+make_lookup_name(const krb5_data *realm, const char *service,
+ const char *protocol)
{
struct k5buf buf;
if (memchr(realm->data, 0, realm->length))
- return EINVAL;
+ return NULL;
- k5_buf_init_fixed(&buf, fixed_buf, bufsize);
+ k5_buf_init_dynamic(&buf);
k5_buf_add_fmt(&buf, "%s.", service);
if (protocol != NULL)
k5_buf_add_fmt(&buf, "%s.", protocol);
if (buf.len > 0 && ((char *)buf.data)[buf.len - 1] != '.')
k5_buf_add(&buf, ".");
- return k5_buf_status(&buf);
+ return buf.data;
}
/* Insert new into the list *head, ordering by priority. Weight is not
const char *service, struct srv_dns_entry **answers)
{
const unsigned char *p = NULL, *base = NULL;
- char host[MAXDNAME];
+ char *name = NULL;
int size, ret, rdlen;
unsigned short priority, weight;
struct krb5int_dns_state *ds = NULL;
*answers = NULL;
/* Construct service.realm. */
- ret = prepare_lookup_buf(realm, service, NULL, host, sizeof(host));
- if (ret)
+ name = make_lookup_name(realm, service, NULL);
+ if (name == NULL)
return 0;
- TRACE_DNS_URI_SEND(context, host);
+ TRACE_DNS_URI_SEND(context, name);
- size = krb5int_dns_init(&ds, host, C_IN, T_URI);
+ size = krb5int_dns_init(&ds, name, C_IN, T_URI);
if (size < 0)
goto out;
out:
krb5int_dns_fini(ds);
+ free(name);
*answers = head;
return 0;
}
struct srv_dns_entry **answers)
{
const unsigned char *p = NULL, *base = NULL;
- char host[MAXDNAME];
+ char *name = NULL, host[MAXDNAME];
int size, ret, rdlen, nlen;
unsigned short priority, weight, port;
struct krb5int_dns_state *ds = NULL;
*
*/
- ret = prepare_lookup_buf(realm, service, protocol, host, sizeof(host));
- if (ret)
+ name = make_lookup_name(realm, service, protocol);
+ if (name == NULL)
return 0;
- TRACE_DNS_SRV_SEND(context, host);
+ TRACE_DNS_SRV_SEND(context, name);
- size = krb5int_dns_init(&ds, host, C_IN, T_SRV);
+ size = krb5int_dns_init(&ds, name, C_IN, T_SRV);
if (size < 0)
goto out;
out:
krb5int_dns_fini(ds);
+ free(name);
*answers = head;
return 0;
}
/* Get the canonical form of the local host name, using forward
* canonicalization only. */
krb5_error_code
-krb5int_get_fq_local_hostname(char *buf, size_t bufsize)
+krb5int_get_fq_local_hostname(char **hostname_out)
{
struct addrinfo *ai, hints;
+ char buf[MAXHOSTNAMELEN];
int err;
- buf[0] = '\0';
- if (gethostname(buf, bufsize) == -1)
+ *hostname_out = NULL;
+
+ if (gethostname(buf, sizeof(buf)) == -1)
return SOCKET_ERRNO;
memset(&hints, 0, sizeof(hints));
freeaddrinfo(ai);
return KRB5_EAI_FAIL;
}
- if (strlcpy(buf, ai->ai_canonname, bufsize) >= bufsize)
- return ENOMEM;
+ *hostname_out = strdup(ai->ai_canonname);
freeaddrinfo(ai);
- return 0;
+ return (*hostname_out == NULL) ? ENOMEM : 0;
}
-krb5_error_code
-k5_clean_hostname(krb5_context context, const char *host, char *cleanname,
- size_t lhsize)
+static krb5_error_code
+clean_hostname(krb5_context context, const char *host, char **cleanname_out)
{
- char *p;
+ char *p, *cleanname;
krb5_error_code ret;
size_t l;
- cleanname[0] = '\0';
+ *cleanname_out = NULL;
+
if (host != NULL) {
- if (strlcpy(cleanname, host, lhsize) >= lhsize)
+ cleanname = strdup(host);
+ if (cleanname == NULL)
return ENOMEM;
} else {
- ret = krb5int_get_fq_local_hostname(cleanname, lhsize);
+ ret = krb5int_get_fq_local_hostname(&cleanname);
if (ret)
return ret;
}
if (l > 0 && cleanname[l - 1] == '.')
cleanname[l - 1] = '\0';
+ *cleanname_out = cleanname;
return 0;
}
{
krb5_error_code ret;
struct hostrealm_module_handle **hp;
- char **realms, cleanname[1024];
+ char **realms, *cleanname = NULL;
*realms_out = NULL;
if (context->hostrealm_handles == NULL) {
ret = load_hostrealm_modules(context);
if (ret)
- return ret;
+ goto cleanup;
}
- ret = k5_clean_hostname(context, host, cleanname, sizeof(cleanname));
+ ret = clean_hostname(context, host, &cleanname);
if (ret)
- return ret;
+ goto cleanup;
/* Give each module a chance to determine the host's realms. */
for (hp = context->hostrealm_handles; *hp != NULL; hp++) {
if (ret == 0) {
ret = copy_list(realms, realms_out);
free_list(context, *hp, realms);
- return ret;
+ goto cleanup;
} else if (ret != KRB5_PLUGIN_NO_HANDLE) {
- return ret;
+ goto cleanup;
}
}
/* Return a list containing the "referral realm" (an empty realm), as a
* cue to try referrals. */
- return k5_make_realmlist(KRB5_REFERRAL_REALM, realms_out);
+ ret = k5_make_realmlist(KRB5_REFERRAL_REALM, realms_out);
+
+cleanup:
+ free(cleanname);
+ return ret;
}
krb5_error_code KRB5_CALLCONV
{
krb5_error_code ret;
struct hostrealm_module_handle **hp;
- char **realms, *defrealm, *host, cleanname[1024];
+ char **realms, *defrealm, *host, *cleanname = NULL;
*realms_out = NULL;
/* Convert hdata into a string and clean it. */
host = k5memdup0(hdata->data, hdata->length, &ret);
if (host == NULL)
- return ret;
- ret = k5_clean_hostname(context, host, cleanname, sizeof(cleanname));
+ goto cleanup;
+ ret = clean_hostname(context, host, &cleanname);
free(host);
if (ret)
- return ret;
+ goto cleanup;
if (context->hostrealm_handles == NULL) {
ret = load_hostrealm_modules(context);
if (ret)
- return ret;
+ goto cleanup;
}
/* Give each module a chance to determine the fallback realms. */
if (ret == 0) {
ret = copy_list(realms, realms_out);
free_list(context, *hp, realms);
- return ret;
+ goto cleanup;
} else if (ret != KRB5_PLUGIN_NO_HANDLE) {
- return ret;
+ goto cleanup;
}
}
/* Return a list containing the default realm. */
ret = krb5_get_default_realm(context, &defrealm);
if (ret)
- return ret;
+ goto cleanup;
ret = k5_make_realmlist(defrealm, realms_out);
krb5_free_default_realm(context, defrealm);
+
+cleanup:
+ free(cleanname);
return ret;
}
#include <krb5/hostrealm_plugin.h>
#ifdef KRB5_DNS_LOOKUP
-#include "dnsglue.h"
/* Try a _kerberos TXT lookup for fqdn and each parent domain; return the
* resulting realm (caller must free) or NULL. */
char ***realms_out)
{
krb5_error_code ret;
- char localhost[MAXDNAME + 1], *realm;
+ char *localhost, *realm;
*realms_out = NULL;
if (!_krb5_use_dns_realm(context))
return KRB5_PLUGIN_NO_HANDLE;
- ret = krb5int_get_fq_local_hostname(localhost, sizeof(localhost));
+ ret = krb5int_get_fq_local_hostname(&localhost);
if (ret)
return ret;
/* If we don't find a TXT record for localhost or any parent, look for a
* global record. */
realm = txt_lookup(context, localhost);
+ free(localhost);
if (realm == NULL)
(void)k5_try_realm_txt_rr(context, "_kerberos", NULL, &realm);
#include "k5-int.h"
#include "fake-addrinfo.h"
#include "os-proto.h"
+
#ifdef KRB5_DNS_LOOKUP
-#ifdef WSHELPER
-#include <wshelper.h>
-#else /* WSHELPER */
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-#include <netdb.h>
-#endif /* WSHELPER */
-#include "dnsglue.h"
#define DEFAULT_LOOKUP_KDC 1
#if KRB5_DNS_LOOKUP_REALM
#endif /* HAVE_NETINET_IN_H */
+struct srv_dns_entry {
+ struct srv_dns_entry *next;
+ int priority;
+ int weight;
+ unsigned short port;
+ char *host;
+};
+
+krb5_error_code
+krb5int_make_srv_query_realm(krb5_context context, const krb5_data *realm,
+ const char *service, const char *protocol,
+ struct srv_dns_entry **answers);
+
+void krb5int_free_srv_dns_data(struct srv_dns_entry *);
+
+krb5_error_code
+k5_make_uri_query(krb5_context context, const krb5_data *realm,
+ const char *service, struct srv_dns_entry **answers);
+
krb5_error_code k5_try_realm_txt_rr(krb5_context context, const char *prefix,
const char *name, char **realm);
void *),
void *msg_handler_data);
-krb5_error_code krb5int_get_fq_local_hostname(char *, size_t);
+krb5_error_code krb5int_get_fq_local_hostname(char **);
/* The io vector is *not* const here, unlike writev()! */
int krb5int_net_writev (krb5_context, int, sg_buf *, int);
krb5_timestamp *time_out,
krb5_int32 *usec_out);
void k5_set_prompt_types(krb5_context, krb5_prompt_type *);
-krb5_error_code k5_clean_hostname(krb5_context, const char *, char *, size_t);
krb5_boolean k5_is_numeric_address(const char *name);
krb5_error_code k5_make_realmlist(const char *realm, char ***realms_out);
krb5_error_code k5_kt_client_default_name(krb5_context context,