>From 7ebac8accdd8cb07c82b650222f0d7c97fe5b955 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Thu, 23 Jul 2015 10:51:50 -0400
Subject: [PATCH 1/2] DYNDNS: use realm and server commands only as fallback

Resolves:
https://fedorahosted.org/sssd/ticket/2495
---
 src/providers/ad/ad_dyndns.c     |  9 ---------
 src/providers/dp_dyndns.c        | 17 ++++++++++++-----
 src/providers/ipa/ipa_dyndns.c   |  7 -------
 src/providers/ldap/sdap_dyndns.c | 41 ++++++++++++++++++++++------------------
 src/providers/ldap/sdap_dyndns.h |  1 -
 5 files changed, 35 insertions(+), 40 deletions(-)

diff --git a/src/providers/ad/ad_dyndns.c b/src/providers/ad/ad_dyndns.c
index 5f8638128b966f0981c85a44e50e3201c73d561e..a4d38c442a69ff0440e459da32d8852bda314484 100644
--- a/src/providers/ad/ad_dyndns.c
+++ b/src/providers/ad/ad_dyndns.c
@@ -159,7 +159,6 @@ static void ad_dyndns_nsupdate_done(struct tevent_req *req)
 
 struct ad_dyndns_update_state {
     struct ad_options *ad_ctx;
-    const char *servername;
 };
 
 static void ad_dyndns_sdap_update_done(struct tevent_req *subreq);
@@ -217,13 +216,6 @@ ad_dyndns_update_send(struct ad_options *ctx)
         goto done;
     }
 
-    state->servername = talloc_strdup(state, lud->lud_host);
-    ldap_free_urldesc(lud);
-    if (!state->servername) {
-        ret = ENOMEM;
-        goto done;
-    }
-
     subreq = sdap_dyndns_update_send(state, sdap_ctx->be->ev,
                                      sdap_ctx->be,
                                      ctx->dyndns_ctx->opts,
@@ -235,7 +227,6 @@ ad_dyndns_update_send(struct ad_options *ctx)
                                                        AD_HOSTNAME),
                                      dp_opt_get_string(ctx->basic,
                                                        AD_KRB5_REALM),
-                                     state->servername,
                                      dp_opt_get_int(ctx->dyndns_ctx->opts,
                                                     DP_OPT_DYNDNS_TTL),
                                      false);
diff --git a/src/providers/dp_dyndns.c b/src/providers/dp_dyndns.c
index a5eb383bd4f6c08b846a69f0588b9c25647dc5c8..782dcb60a8ae26b972f0ab2403573cf43cb0a67c 100644
--- a/src/providers/dp_dyndns.c
+++ b/src/providers/dp_dyndns.c
@@ -376,6 +376,17 @@ static char *nsupdate_msg_add_ptr(char *update_msg,
 }
 
 static char *
+nsupdate_msg_add_realm_cmd(TALLOC_CTX *mem_ctx, const char *realm)
+{
+#ifdef HAVE_NSUPDATE_REALM
+    if (realm != NULL) {
+        return talloc_asprintf(mem_ctx, "realm %s\n", realm);
+    }
+#endif
+    return talloc_asprintf(mem_ctx, "\n");
+}
+
+static char *
 nsupdate_msg_create_common(TALLOC_CTX *mem_ctx, const char *realm,
                            const char *servername)
 {
@@ -386,11 +397,7 @@ nsupdate_msg_create_common(TALLOC_CTX *mem_ctx, const char *realm,
     tmp_ctx = talloc_new(NULL);
     if (tmp_ctx == NULL) return NULL;
 
-#ifdef HAVE_NSUPDATE_REALM
-    realm_directive = talloc_asprintf(tmp_ctx, "realm %s\n", realm);
-#else
-    realm_directive = talloc_asprintf(tmp_ctx, "\n");
-#endif
+    realm_directive = nsupdate_msg_add_realm_cmd(tmp_ctx, realm);
     if (!realm_directive) {
         goto fail;
     }
diff --git a/src/providers/ipa/ipa_dyndns.c b/src/providers/ipa/ipa_dyndns.c
index e7026eb275798f0ed21fb8490295b6e6d419d8ee..1a7014718366ce3c898eef24eabd6903101dc92e 100644
--- a/src/providers/ipa/ipa_dyndns.c
+++ b/src/providers/ipa/ipa_dyndns.c
@@ -153,7 +153,6 @@ ipa_dyndns_update_send(struct ipa_options *ctx)
     struct ipa_dyndns_update_state *state;
     struct tevent_req *req, *subreq;
     struct sdap_id_ctx *sdap_ctx = ctx->id_ctx->sdap_id_ctx;
-    const char *servername;
 
     DEBUG(SSSDBG_TRACE_FUNC, "Performing update\n");
 
@@ -179,11 +178,6 @@ ipa_dyndns_update_send(struct ipa_options *ctx)
         ret = EIO;
         goto done;
     }
-    servername = ctx->service->sdap->uri + 7;
-    if (servername[0] == '\0') {
-        ret = EIO;
-        goto done;
-    }
 
     subreq = sdap_dyndns_update_send(state, sdap_ctx->be->ev,
                                      sdap_ctx->be,
@@ -196,7 +190,6 @@ ipa_dyndns_update_send(struct ipa_options *ctx)
                                                        IPA_HOSTNAME),
                                      dp_opt_get_string(ctx->basic,
                                                        IPA_KRB5_REALM),
-                                     servername,
                                      dp_opt_get_int(ctx->dyndns_ctx->opts,
                                                     DP_OPT_DYNDNS_TTL),
                                      true);
diff --git a/src/providers/ldap/sdap_dyndns.c b/src/providers/ldap/sdap_dyndns.c
index 3a52a11d1e1c86ee7b26cf6affd81f7cf1bb7d03..456aa55929c798e4212ce974d532658c9f209f26 100644
--- a/src/providers/ldap/sdap_dyndns.c
+++ b/src/providers/ldap/sdap_dyndns.c
@@ -89,7 +89,6 @@ sdap_dyndns_update_send(TALLOC_CTX *mem_ctx,
                         const char *ifname,
                         const char *hostname,
                         const char *realm,
-                        const char *servername,
                         const int ttl,
                         bool check_diff)
 {
@@ -107,7 +106,7 @@ sdap_dyndns_update_send(TALLOC_CTX *mem_ctx,
     state->update_ptr = dp_opt_get_bool(opts, DP_OPT_DYNDNS_UPDATE_PTR);
     state->hostname = hostname;
     state->realm = realm;
-    state->servername = servername;
+    state->servername = NULL;
     state->fallback_mode = false;
     state->ttl = ttl;
     state->be_res = be_ctx->be_res;
@@ -321,18 +320,20 @@ sdap_dyndns_update_step(struct tevent_req *req)
     errno_t ret;
     struct sdap_dyndns_update_state *state;
     const char *servername;
+    const char *realm;
     struct tevent_req *subreq;
 
     state = tevent_req_data(req, struct sdap_dyndns_update_state);
 
     servername = NULL;
-    if (state->fallback_mode == true &&
-        state->servername) {
+    realm = NULL;
+    if (state->fallback_mode) {
         servername = state->servername;
+        realm = state->realm;
     }
 
-    ret = be_nsupdate_create_fwd_msg(state, state->realm,
-                                     servername, state->hostname,
+    ret = be_nsupdate_create_fwd_msg(state, realm, servername,
+                                     state->hostname,
                                      state->ttl, state->remove_af,
                                      state->addresses,
                                      &state->update_msg);
@@ -369,11 +370,12 @@ sdap_dyndns_update_done(struct tevent_req *subreq)
     talloc_zfree(subreq);
     if (ret != EOK) {
         /* If the update didn't succeed, we can retry using the server name */
-        if (state->fallback_mode == false && state->servername &&
-            WIFEXITED(child_status) && WEXITSTATUS(child_status) != 0) {
+        if (state->fallback_mode == false
+                && WIFEXITED(child_status)
+                && WEXITSTATUS(child_status) != 0) {
             state->fallback_mode = true;
             DEBUG(SSSDBG_MINOR_FAILURE,
-                   "nsupdate failed, retrying with server name\n");
+                  "nsupdate failed, retrying.\n");
             ret = sdap_dyndns_update_step(req);
             if (ret == EOK) {
                 return;
@@ -459,15 +461,17 @@ sdap_dyndns_update_ptr_step(struct tevent_req *req)
     errno_t ret;
     struct sdap_dyndns_update_state *state;
     const char *servername;
+    const char *realm;
     struct tevent_req *subreq;
     struct sockaddr_storage *address;
 
     state = tevent_req_data(req, struct sdap_dyndns_update_state);
 
     servername = NULL;
-    if (state->fallback_mode == true &&
-        state->servername) {
+    realm = NULL;
+    if (state->fallback_mode == true) {
         servername = state->servername;
+        realm = state->realm;
     }
 
     address = sss_iface_addr_get_address(state->ptr_addr_iter);
@@ -475,9 +479,10 @@ sdap_dyndns_update_ptr_step(struct tevent_req *req)
         return EIO;
     }
 
-    ret = be_nsupdate_create_ptr_msg(state, state->realm, servername,
-                                     state->hostname, state->ttl, address,
-                                     state->del_phase, &state->update_msg);
+    ret = be_nsupdate_create_ptr_msg(state, realm, servername, state->hostname,
+                                     state->ttl, address, state->del_phase,
+                                     &state->update_msg);
+
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, "Can't get addresses for DNS update\n");
         return ret;
@@ -511,11 +516,11 @@ sdap_dyndns_update_ptr_done(struct tevent_req *subreq)
     talloc_zfree(subreq);
     if (ret != EOK) {
         /* If the update didn't succeed, we can retry using the server name */
-        if (state->fallback_mode == false && state->servername &&
-            WIFEXITED(child_status) && WEXITSTATUS(child_status) != 0) {
+        if (state->fallback_mode == false
+                && WIFEXITED(child_status)
+                && WEXITSTATUS(child_status) != 0) {
             state->fallback_mode = true;
-            DEBUG(SSSDBG_MINOR_FAILURE,
-                   "nsupdate failed, retrying with server name\n");
+            DEBUG(SSSDBG_MINOR_FAILURE, "nsupdate failed, retrying\n");
             ret = sdap_dyndns_update_ptr_step(req);
             if (ret == EOK) {
                 return;
diff --git a/src/providers/ldap/sdap_dyndns.h b/src/providers/ldap/sdap_dyndns.h
index a9481b7941be6af0f172afce5f4d54f57ef85e48..fda4530b61cfcfcf98207638efd4de70498d90dc 100644
--- a/src/providers/ldap/sdap_dyndns.h
+++ b/src/providers/ldap/sdap_dyndns.h
@@ -40,7 +40,6 @@ sdap_dyndns_update_send(TALLOC_CTX *mem_ctx,
                         const char *ifname,
                         const char *hostname,
                         const char *realm,
-                        const char *servername,
                         const int ttl,
                         bool check_diff);
 
-- 
2.4.3

