From ab60a57bd9ce5d76e729e16ab94365f71852c447 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Tue, 17 Jul 2012 10:38:40 -0400
Subject: [PATCH 2/4] LOCATOR: Create struct for address and port

---
 src/krb5_plugin/sssd_krb5_locator_plugin.c |  111 +++++++++++++++++++---------
 1 file changed, 78 insertions(+), 33 deletions(-)

diff --git a/src/krb5_plugin/sssd_krb5_locator_plugin.c b/src/krb5_plugin/sssd_krb5_locator_plugin.c
index c33068bb9906ed8662faf6b0b5e86f4fcc3a0115..07a93d7e6e0c0018157f87fde38ec608b2e8f3a4 100644
--- a/src/krb5_plugin/sssd_krb5_locator_plugin.c
+++ b/src/krb5_plugin/sssd_krb5_locator_plugin.c
@@ -53,12 +53,18 @@
     } \
 } while(0)
 
+struct sssd_kserver_ctx {
+    struct sssd_kserver_ctx *prev;
+    struct sssd_kserver_ctx *next;
+
+    char *addr;
+    uint16_t port;
+};
+
 struct sssd_ctx {
     char *sssd_realm;
-    char *kdc_addr;
-    uint16_t kdc_port;
-    char *kpasswd_addr;
-    uint16_t kpasswd_port;
+    struct sssd_kserver_ctx *kdc;
+    struct sssd_kserver_ctx *kpasswd;
     bool debug;
 };
 
@@ -80,6 +86,26 @@ void debug_fn(const char *format, ...)
     talloc_free(s);
 }
 
+static struct sssd_kserver_ctx *
+sssd_kserver_ctx_init(TALLOC_CTX *mem_ctx, const char *address, uint16_t port)
+{
+    struct sssd_kserver_ctx *kctx;
+
+    kctx = talloc_zero(mem_ctx, struct sssd_kserver_ctx);
+    if (!kctx) return NULL;
+
+    kctx->addr = talloc_strdup(kctx, address);
+    if (!kctx->addr) {
+        talloc_free(kctx);
+        return NULL;
+    }
+
+    kctx->port = port;
+
+    return kctx;
+}
+
+
 static int get_krb5info(const char *realm, struct sssd_ctx *ctx,
                         enum locate_service_type svc)
 {
@@ -174,24 +200,22 @@ static int get_krb5info(const char *realm, struct sssd_ctx *ctx,
 
     switch (svc) {
         case locate_service_kdc:
-            talloc_zfree(ctx->kdc_addr);
-            ctx->kdc_addr = talloc_strdup(ctx, (char *) buf);
-            if (ctx->kdc_addr == NULL) {
-                PLUGIN_DEBUG(("strdup failed.\n"));
+            talloc_zfree(ctx->kdc);
+            ctx->kdc = sssd_kserver_ctx_init(ctx, (char *)buf, port);
+            if (ctx->kdc == NULL) {
+                PLUGIN_DEBUG(("kserver ctx init failed.\n"));
                 ret = ENOMEM;
                 goto done;
             }
-            ctx->kdc_port = (uint16_t) port;
             break;
         case locate_service_kpasswd:
-            talloc_zfree(ctx->kpasswd_addr);
-            ctx->kpasswd_addr = talloc_strdup(ctx, (char *) buf);
-            if (ctx->kpasswd_addr == NULL) {
-                PLUGIN_DEBUG(("strdup failed.\n"));
+            talloc_zfree(ctx->kpasswd);
+            ctx->kpasswd = sssd_kserver_ctx_init(ctx, (char *)buf, port);
+            if (ctx->kpasswd == NULL) {
+                PLUGIN_DEBUG(("kserver ctx init failed.\n"));
                 ret = ENOMEM;
                 goto done;
             }
-            ctx->kpasswd_port = (uint16_t) port;
             break;
         default:
             PLUGIN_DEBUG(("Unsupported service [%d].\n", svc));
@@ -205,14 +229,23 @@ done:
     return ret;
 }
 
-krb5_error_code sssd_krb5_locator_init(krb5_context context,
-                                       void **private_data)
+errno_t sssd_ctx_init(struct sssd_ctx **_ctx)
 {
-    struct sssd_ctx *ctx;
     const char *dummy;
+    struct sssd_ctx *ctx;
 
-    ctx = talloc_zero(NULL, struct sssd_ctx);
-    if (ctx == NULL) return KRB5_PLUGIN_NO_HANDLE;
+    if (*_ctx) {
+        ctx = *_ctx;
+    } else {
+        ctx = talloc_zero(NULL, struct sssd_ctx);
+        if (!ctx) {
+            return ENOMEM;
+        }
+        *_ctx = ctx;
+    }
+
+    talloc_free_children(ctx);
+    memset(ctx, 0, sizeof(struct sssd_ctx));
 
     dummy = getenv(SSSD_KRB5_LOCATOR_DEBUG);
     if (dummy == NULL) {
@@ -222,6 +255,18 @@ krb5_error_code sssd_krb5_locator_init(krb5_context context,
         PLUGIN_DEBUG(("sssd_krb5_locator_init called\n"));
     }
 
+    return EOK;
+}
+
+krb5_error_code sssd_krb5_locator_init(krb5_context context,
+                                       void **private_data)
+{
+    errno_t ret;
+    struct sssd_ctx *ctx = NULL;
+
+    ret = sssd_ctx_init(&ctx);
+    if (ret != EOK) return KRB5_PLUGIN_NO_HANDLE;
+
     *private_data = ctx;
 
     return 0;
@@ -261,7 +306,12 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
     ctx = talloc_get_type_abort(private_data, struct sssd_ctx);
 
     if (ctx->sssd_realm == NULL || strcmp(ctx->sssd_realm, realm) != 0) {
-        talloc_zfree(ctx->sssd_realm);
+        ret = sssd_ctx_init(&ctx);
+        if (ret != EOK) {
+            PLUGIN_DEBUG(("re-init failed.\n"));
+            return KRB5_PLUGIN_NO_HANDLE;
+        }
+
         ctx->sssd_realm = talloc_strdup(ctx, realm);
         if (ctx->sssd_realm == NULL) {
             PLUGIN_DEBUG(("strdup failed.\n"));
@@ -280,13 +330,8 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
             if (ret != EOK) {
                 PLUGIN_DEBUG(("reading kpasswd address failed, "
                               "using kdc address.\n"));
-                talloc_zfree(ctx->kpasswd_addr);
-                ctx->kpasswd_addr = talloc_strdup(ctx, ctx->kdc_addr);
-                if (ctx->kpasswd_addr == NULL) {
-                    PLUGIN_DEBUG(("strdup failed.\n"));
-                    return KRB5_PLUGIN_NO_HANDLE;
-                }
-                ctx->kpasswd_port = 0;
+
+                ctx->kpasswd = ctx->kdc;
             }
         }
     }
@@ -297,20 +342,20 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
 
     switch (svc) {
         case locate_service_kdc:
-            addr = ctx->kdc_addr;
-            port = ctx->kdc_port ? ctx->kdc_port : DEFAULT_KERBEROS_PORT;
+            addr = ctx->kdc->addr;
+            port = ctx->kdc->port ? ctx->kdc->port : DEFAULT_KERBEROS_PORT;
             break;
         case locate_service_master_kdc:
-            addr = ctx->kpasswd_addr;
+            addr = ctx->kpasswd->addr;
             port = DEFAULT_KERBEROS_PORT;
             break;
         case locate_service_kadmin:
-            addr = ctx->kpasswd_addr;
+            addr = ctx->kpasswd->addr;
             port = DEFAULT_KADMIN_PORT;
             break;
         case locate_service_kpasswd:
-            addr = ctx->kpasswd_addr;
-            port = ctx->kpasswd_port ? ctx->kpasswd_port : DEFAULT_KPASSWD_PORT;
+            addr = ctx->kpasswd->addr;
+            port = ctx->kpasswd->port ? ctx->kpasswd->port : DEFAULT_KPASSWD_PORT;
             break;
         case locate_service_krb524:
             return KRB5_PLUGIN_NO_HANDLE;
-- 
1.7.10.4

