>From 932b81f4cdd6acf819f5bd1f481c608c5ab8b3d2 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Tue, 16 Apr 2013 14:19:15 +0200 Subject: [PATCH 4/5] dyndns: new option dyndns_force_tcp https://fedorahosted.org/sssd/ticket/1831 Adds a new option that can be used to force nsupdate to only use TCP to communicate with the DNS server. --- src/config/SSSDConfig/__init__.py.in | 1 + src/config/SSSDConfigTest.py | 2 ++ src/config/etc/sssd.api.conf | 1 + src/man/sssd-ipa.5.xml | 13 +++++++++++++ src/providers/dp_dyndns.c | 18 +++++++++++++++--- src/providers/dp_dyndns.h | 4 +++- src/providers/ipa/ipa_opts.h | 1 + src/providers/ldap/sdap_dyndns.c | 8 ++++++-- src/tests/cmocka/test_dyndns.c | 6 +++--- 9 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in index 79bf6aa4e97ed75391f97472a780d6349fd1060a..c5475ffd8b599d3f60d7f1c992847d3ce00847b7 100644 --- a/src/config/SSSDConfig/__init__.py.in +++ b/src/config/SSSDConfig/__init__.py.in @@ -130,6 +130,7 @@ option_strings = { 'dyndns_iface' : _("The interface whose IP should be used for dynamic DNS updates"), 'dyndns_refresh_interval' : _("How often to periodically update the client's DNS entry"), 'dyndns_update_ptr' : _("Whether the provider should explicitly update the PTR record as well"), + 'dyndns_force_tcp' : _("Whether the nsupdate utility should default to using TCP"), # [provider/ipa] 'ipa_domain' : _('IPA domain'), diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py index 86ff29df1f8225a846903ad6c61c2a6147c9bc69..13418b90669a881721cf172314c0674afa77ec2c 100755 --- a/src/config/SSSDConfigTest.py +++ b/src/config/SSSDConfigTest.py @@ -512,6 +512,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): 'dyndns_iface', 'dyndns_refresh_interval', 'dyndns_update_ptr', + 'dyndns_force_tcp', 'override_gid', 'case_sensitive', 'override_homedir', @@ -860,6 +861,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): 'dyndns_iface', 'dyndns_refresh_interval', 'dyndns_update_ptr', + 'dyndns_force_tcp', 'override_gid', 'case_sensitive', 'override_homedir', diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf index 396063b4fd9fe08e65860bd24a68350401a0d7f0..013fa9fe5a38bdd5c3dd1aa648287c56a0aa4211 100644 --- a/src/config/etc/sssd.api.conf +++ b/src/config/etc/sssd.api.conf @@ -127,6 +127,7 @@ dyndns_ttl = int, None, false dyndns_iface = str, None, false dyndns_refresh_interval = int, None, false dyndns_update_ptr = bool, None, false +dyndns_force_tcp = bool, None, false # Special providers [provider/permit] diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml index 21a28047969043e1abb8f54a708fddc7727d8073..795a72237dee7093e790135244ce0ff9baf7e61b 100644 --- a/src/man/sssd-ipa.5.xml +++ b/src/man/sssd-ipa.5.xml @@ -240,6 +240,19 @@ + dyndns_force_tcp (bool) + + + Whether the nsupdate utility should default to using + TCP for communicating with the DNS server. + + + Default: False (let nsupdate choose the protocol) + + + + + ipa_hbac_search_base (string) diff --git a/src/providers/dp_dyndns.c b/src/providers/dp_dyndns.c index 79701c6294c595c33e69f978fe044a7fdaf5a9c6..36cce458216b51ab6a9b233b6c7dde29705828eb 100644 --- a/src/providers/dp_dyndns.c +++ b/src/providers/dp_dyndns.c @@ -935,7 +935,8 @@ static void be_nsupdate_done(struct tevent_req *subreq); struct tevent_req *be_nsupdate_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - char *nsupdate_msg) + char *nsupdate_msg, + bool force_tcp) { int pipefd_to_child[2]; pid_t child_pid; @@ -943,7 +944,7 @@ struct tevent_req *be_nsupdate_send(TALLOC_CTX *mem_ctx, struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct be_nsupdate_state *state; - char *args[3]; + char *args[4]; req = tevent_req_create(mem_ctx, &state, struct be_nsupdate_state); if (req == NULL) { @@ -962,14 +963,24 @@ struct tevent_req *be_nsupdate_send(TALLOC_CTX *mem_ctx, child_pid = fork(); if (child_pid == 0) { /* child */ + memset(args, 0, 4 * sizeof(char *)); + args[0] = talloc_strdup(state, NSUPDATE_PATH); args[1] = talloc_strdup(state, "-g"); - args[2] = NULL; if (args[0] == NULL || args[1] == NULL) { ret = ENOMEM; goto done; } + if (force_tcp) { + DEBUG(SSSDBG_FUNC_DATA, ("TCP is set to on\n")); + args[2] = talloc_strdup(state, "-v"); + if (args[2] == NULL) { + ret = ENOMEM; + goto done; + } + } + close(pipefd_to_child[1]); ret = dup2(pipefd_to_child[0], STDIN_FILENO); if (ret == -1) { @@ -1117,6 +1128,7 @@ static struct dp_option default_dyndns_opts[] = { { "dyndns_iface", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "dyndns_ttl", DP_OPT_NUMBER, { .number = 1200 }, NULL_NUMBER }, { "dyndns_update_ptr", DP_OPT_BOOL, BOOL_TRUE, BOOL_FALSE }, + { "dyndns_force_tcp", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, DP_OPTION_TERMINATOR }; diff --git a/src/providers/dp_dyndns.h b/src/providers/dp_dyndns.h index 8fdbe487b5a857cb02b13e099176ce07b27da0c4..a1e31e450c10f64abf8bc1ec86d408abfcd557e8 100644 --- a/src/providers/dp_dyndns.h +++ b/src/providers/dp_dyndns.h @@ -47,6 +47,7 @@ enum dp_dyndns_opts { DP_OPT_DYNDNS_IFACE, DP_OPT_DYNDNS_TTL, DP_OPT_DYNDNS_UPDATE_PTR, + DP_OPT_DYNDNS_FORCE_TCP, DP_OPT_DYNDNS /* attrs counter */ }; @@ -103,7 +104,8 @@ be_nsupdate_create_ptr_msg(TALLOC_CTX *mem_ctx, const char *realm, */ struct tevent_req *be_nsupdate_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - char *nsupdate_msg); + char *nsupdate_msg, + bool force_tcp); errno_t be_nsupdate_recv(struct tevent_req *req, int *child_status); struct tevent_req * nsupdate_get_addrs_send(TALLOC_CTX *mem_ctx, diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h index bfb09e36cb3562b61c5bdb1dd928c5b124bdd0ce..97dd6ea9fd1444ed1661240efc8e95773d160380 100644 --- a/src/providers/ipa/ipa_opts.h +++ b/src/providers/ipa/ipa_opts.h @@ -57,6 +57,7 @@ struct dp_option ipa_dyndns_opts[] = { { "dyndns_iface", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "dyndns_ttl", DP_OPT_NUMBER, { .number = 1200 }, NULL_NUMBER }, { "dyndns_update_ptr", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, + { "dyndns_force_tcp", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, DP_OPTION_TERMINATOR }; diff --git a/src/providers/ldap/sdap_dyndns.c b/src/providers/ldap/sdap_dyndns.c index ccaec8e09819c6ec592775469672604e9d9c6b4a..1c400f65af559889aac8be176f1b3f56190441b9 100644 --- a/src/providers/ldap/sdap_dyndns.c +++ b/src/providers/ldap/sdap_dyndns.c @@ -323,7 +323,9 @@ sdap_dyndns_update_step(struct tevent_req *req) } /* Fork a child process to perform the DNS update */ - subreq = be_nsupdate_send(state, state->ev, state->update_msg); + subreq = be_nsupdate_send(state, state->ev, state->update_msg, + dp_opt_get_bool(state->opts, + DP_OPT_DYNDNS_FORCE_TCP)); if (subreq == NULL) { return EIO; } @@ -405,7 +407,9 @@ sdap_dyndns_update_ptr_step(struct tevent_req *req) /* Fork a child process to perform the DNS update */ subreq = be_nsupdate_send(state, state->ev, - state->update_msg); + state->update_msg, + dp_opt_get_bool(state->opts, + DP_OPT_DYNDNS_FORCE_TCP)); if (subreq == NULL) { return EIO; } diff --git a/src/tests/cmocka/test_dyndns.c b/src/tests/cmocka/test_dyndns.c index 0657bf1ba558845639c2b25c6500681a5610faca..6b52347be7aeb0e34f068dae459de4cb9ff27895 100644 --- a/src/tests/cmocka/test_dyndns.c +++ b/src/tests/cmocka/test_dyndns.c @@ -210,7 +210,7 @@ void dyndns_test_ok(void **state) dyndns_test_ctx->state = MOCK_NSUPDATE_OK; req = be_nsupdate_send(tmp_ctx, dyndns_test_ctx->tctx->ev, - discard_const("test message")); + discard_const("test message"), false); assert_non_null(req); tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx); @@ -240,7 +240,7 @@ void dyndns_test_error(void **state) dyndns_test_ctx->state = MOCK_NSUPDATE_ERR; req = be_nsupdate_send(tmp_ctx, dyndns_test_ctx->tctx->ev, - discard_const("test message")); + discard_const("test message"), false); assert_non_null(req); tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx); @@ -270,7 +270,7 @@ void dyndns_test_timeout(void **state) dyndns_test_ctx->state = MOCK_NSUPDATE_TIMEOUT; req = be_nsupdate_send(tmp_ctx, dyndns_test_ctx->tctx->ev, - discard_const("test message")); + discard_const("test message"), false); assert_non_null(req); tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx); -- 1.8.2.1