summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/config/SSSDConfig/__init__.py.in1
-rwxr-xr-xsrc/config/SSSDConfigTest.py2
-rw-r--r--src/config/etc/sssd.api.conf1
-rw-r--r--src/man/sssd-ipa.5.xml13
-rw-r--r--src/providers/dp_dyndns.c18
-rw-r--r--src/providers/dp_dyndns.h4
-rw-r--r--src/providers/ipa/ipa_opts.h1
-rw-r--r--src/providers/ldap/sdap_dyndns.c8
-rw-r--r--src/tests/cmocka/test_dyndns.c6
9 files changed, 45 insertions, 9 deletions
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 79bf6aa4e..c5475ffd8 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 7add141ce..21b4db709 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 396063b4f..013fa9fe5 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 21a280479..795a72237 100644
--- a/src/man/sssd-ipa.5.xml
+++ b/src/man/sssd-ipa.5.xml
@@ -240,6 +240,19 @@
</varlistentry>
<varlistentry>
+ <term>dyndns_force_tcp (bool)</term>
+ <listitem>
+ <para>
+ Whether the nsupdate utility should default to using
+ TCP for communicating with the DNS server.
+ </para>
+ <para>
+ Default: False (let nsupdate choose the protocol)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>ipa_hbac_search_base (string)</term>
<listitem>
<para>
diff --git a/src/providers/dp_dyndns.c b/src/providers/dp_dyndns.c
index 79701c629..36cce4582 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 8fdbe487b..a1e31e450 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 bfb09e36c..97dd6ea9f 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 ccaec8e09..1c400f65a 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 0657bf1ba..6b52347be 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);