summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/krb5/krbhst.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/krb5/krbhst.c')
-rw-r--r--source4/heimdal/lib/krb5/krbhst.c97
1 files changed, 94 insertions, 3 deletions
diff --git a/source4/heimdal/lib/krb5/krbhst.c b/source4/heimdal/lib/krb5/krbhst.c
index e7b2579229..f395f0d0c3 100644
--- a/source4/heimdal/lib/krb5/krbhst.c
+++ b/source4/heimdal/lib/krb5/krbhst.c
@@ -33,8 +33,9 @@
#include "krb5_locl.h"
#include <resolve.h>
+#include "locate_plugin.h"
-RCSID("$Id: krbhst.c,v 1.57 2006/10/06 17:11:02 lha Exp $");
+RCSID("$Id: krbhst.c,v 1.58 2006/11/12 20:05:20 lha Exp $");
static int
string_to_proto(const char *string)
@@ -147,6 +148,7 @@ struct krb5_krbhst_data {
#define KD_FALLBACK 16
#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_krbhst_info**);
@@ -460,8 +462,8 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
hi->proto = proto;
hi->port = hi->def_port = port;
hi->ai = ai;
- memmove(hi->hostname, host, hostlen - 1);
- hi->hostname[hostlen - 1] = '\0';
+ memmove(hi->hostname, host, hostlen);
+ hi->hostname[hostlen] = '\0';
free(host);
append_host_hostinfo(kd, hi);
kd->fallback_count++;
@@ -469,6 +471,88 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
return 0;
}
+/*
+ * Fetch hosts from plugin
+ */
+
+static krb5_error_code
+add_locate(void *ctx, int type, struct sockaddr *addr)
+{
+ struct krb5_krbhst_info *hi;
+ struct krb5_krbhst_data *kd = ctx;
+ char host[NI_MAXHOST], port[NI_MAXSERV];
+ struct addrinfo hints, *ai;
+ socklen_t socklen;
+ size_t hostlen;
+ int ret;
+
+ socklen = socket_sockaddr_size(addr);
+
+ ret = getnameinfo(addr, socklen, host, sizeof(host), port, sizeof(port),
+ NI_NUMERICHOST|NI_NUMERICSERV);
+ if (ret != 0)
+ return 0;
+
+ memset(&hints, 0, sizeof(hints));
+ ret = getaddrinfo(host, port, &hints, &ai);
+ if (ret)
+ return 0;
+
+ hostlen = strlen(host);
+
+ hi = calloc(1, sizeof(*hi) + hostlen);
+ if(hi == NULL) {
+ free(host);
+ return ENOMEM;
+ }
+
+ hi->proto = krbhst_get_default_proto(kd);
+ hi->port = hi->def_port = socket_get_port(addr);
+ hi->ai = ai;
+ memmove(hi->hostname, host, hostlen);
+ hi->hostname[hostlen] = '\0';
+ append_host_hostinfo(kd, hi);
+
+ return 0;
+}
+
+static void
+plugin_get_hosts(krb5_context context,
+ struct krb5_krbhst_data *kd,
+ enum locate_service_type type)
+{
+ struct krb5_plugin *list, *e;
+ krb5_error_code ret;
+
+ ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, "resolve", &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 = _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");
+ break;
+ }
+ }
+ _krb5_plugin_free(list);
+}
+
+/*
+ *
+ */
+
static krb5_error_code
kdc_get_next(krb5_context context,
struct krb5_krbhst_data *kd,
@@ -476,6 +560,13 @@ kdc_get_next(krb5_context context,
{
krb5_error_code ret;
+ if ((kd->flags & KD_PLUGIN) == 0) {
+ plugin_get_hosts(context, kd, locate_service_kdc);
+ kd->flags |= KD_PLUGIN;
+ if(get_next(kd, host))
+ return 0;
+ }
+
if((kd->flags & KD_CONFIG) == 0) {
config_get_hosts(context, kd, "kdc");
kd->flags |= KD_CONFIG;