summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2013-04-16 15:11:38 +0200
committerJakub Hrozek <jhrozek@redhat.com>2013-05-03 20:25:46 +0200
commite15a9f81eb33066937710d7dee6976a3646d119c (patch)
tree12a0d8a30494b6c09653c3a1f7538cd6ec10ed08
parente45b81abe0aafa8a04bd64ac31a2fac63ce675b7 (diff)
downloadsssd2-e15a9f81eb33066937710d7dee6976a3646d119c.tar.gz
sssd2-e15a9f81eb33066937710d7dee6976a3646d119c.tar.xz
sssd2-e15a9f81eb33066937710d7dee6976a3646d119c.zip
dyndns: new option dyndns_auth
This options is mostly provided for future expansion. Currently it is undocumented and both IPA and AD dynamic DNS updates default to GSS-TSIG. Allowed values are GSS-TSIG and none.
-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/providers/dp_dyndns.c94
-rw-r--r--src/providers/dp_dyndns.h8
-rw-r--r--src/providers/ipa/ipa_dyndns.c1
-rw-r--r--src/providers/ipa/ipa_opts.h1
-rw-r--r--src/providers/ldap/sdap_dyndns.c8
-rw-r--r--src/providers/ldap/sdap_dyndns.h2
-rw-r--r--src/tests/cmocka/test_dyndns.c3
10 files changed, 100 insertions, 21 deletions
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index c5475ffd..bc7bb0a7 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -131,6 +131,7 @@ option_strings = {
'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"),
+ 'dyndns_auth' : _("What kind of authentication should be used to perform the DNS update"),
# [provider/ipa]
'ipa_domain' : _('IPA domain'),
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index 21b4db70..9de4b2b4 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -513,6 +513,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
'dyndns_refresh_interval',
'dyndns_update_ptr',
'dyndns_force_tcp',
+ 'dyndns_auth',
'override_gid',
'case_sensitive',
'override_homedir',
@@ -862,6 +863,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
'dyndns_refresh_interval',
'dyndns_update_ptr',
'dyndns_force_tcp',
+ 'dyndns_auth',
'override_gid',
'case_sensitive',
'override_homedir',
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index 013fa9fe..54cd703e 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -128,6 +128,7 @@ dyndns_iface = str, None, false
dyndns_refresh_interval = int, None, false
dyndns_update_ptr = bool, None, false
dyndns_force_tcp = bool, None, false
+dyndns_auth = str, None, false
# Special providers
[provider/permit]
diff --git a/src/providers/dp_dyndns.c b/src/providers/dp_dyndns.c
index 36cce458..a7bf54f9 100644
--- a/src/providers/dp_dyndns.c
+++ b/src/providers/dp_dyndns.c
@@ -932,9 +932,13 @@ struct be_nsupdate_state {
};
static void be_nsupdate_done(struct tevent_req *subreq);
+static char **be_nsupdate_args(TALLOC_CTX *mem_ctx,
+ enum be_nsupdate_auth auth_type,
+ bool force_tcp);
struct tevent_req *be_nsupdate_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
+ enum be_nsupdate_auth auth_type,
char *nsupdate_msg,
bool force_tcp)
{
@@ -944,7 +948,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[4];
+ char **args;
req = tevent_req_create(mem_ctx, &state, struct be_nsupdate_state);
if (req == NULL) {
@@ -963,24 +967,6 @@ 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");
- 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) {
@@ -990,6 +976,12 @@ struct tevent_req *be_nsupdate_send(TALLOC_CTX *mem_ctx,
goto done;
}
+ args = be_nsupdate_args(state, auth_type, force_tcp);
+ if (args == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
errno = 0;
execv(NSUPDATE_PATH, args);
/* The child should never end up here */
@@ -1022,6 +1014,58 @@ done:
return req;
}
+static char **
+be_nsupdate_args(TALLOC_CTX *mem_ctx,
+ enum be_nsupdate_auth auth_type,
+ bool force_tcp)
+{
+ char **argv;
+ int argc = 0;
+
+ argv = talloc_zero_array(mem_ctx, char *, 4);
+ if (argv == NULL) {
+ return NULL;
+ }
+
+ argv[argc] = talloc_strdup(argv, NSUPDATE_PATH);
+ if (argv[argc] == NULL) {
+ goto fail;
+ }
+ argc++;
+
+ switch (auth_type) {
+ case BE_NSUPDATE_AUTH_NONE:
+ DEBUG(SSSDBG_FUNC_DATA, ("nsupdate auth type: none\n"));
+ break;
+ case BE_NSUPDATE_AUTH_GSS_TSIG:
+ DEBUG(SSSDBG_FUNC_DATA, ("nsupdate auth type: GSS-TSIG\n"));
+ argv[argc] = talloc_strdup(argv, "-g");
+ if (argv[argc] == NULL) {
+ goto fail;
+ }
+ argc++;
+ break;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Unknown nsupdate auth type\n"));
+ goto fail;
+ }
+
+ if (force_tcp) {
+ DEBUG(SSSDBG_FUNC_DATA, ("TCP is set to on\n"));
+ argv[argc] = talloc_strdup(argv, "-v");
+ if (argv[argc] == NULL) {
+ goto fail;
+ }
+ argc++;
+ }
+
+ return argv;
+
+fail:
+ talloc_free(argv);
+ return NULL;
+}
+
static void
be_nsupdate_done(struct tevent_req *subreq)
{
@@ -1129,6 +1173,7 @@ static struct dp_option default_dyndns_opts[] = {
{ "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 },
+ { "dyndns_auth", DP_OPT_STRING, { "gss-tsig" }, NULL_STRING },
DP_OPTION_TERMINATOR
};
@@ -1143,6 +1188,7 @@ be_nsupdate_init(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx,
errno_t ret;
struct dp_option *src_opts;
struct be_nsupdate_ctx *ctx;
+ char *strauth;
ctx = talloc_zero(mem_ctx, struct be_nsupdate_ctx);
if (ctx == NULL) return ENOMEM;
@@ -1156,6 +1202,16 @@ be_nsupdate_init(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx,
return ret;
}
+ strauth = dp_opt_get_string(ctx->opts, DP_OPT_DYNDNS_AUTH);
+ if (strcasecmp(strauth, "gss-tsig") == 0) {
+ ctx->auth_type = BE_NSUPDATE_AUTH_GSS_TSIG;
+ } else if (strcasecmp(strauth, "none") == 0) {
+ ctx->auth_type = BE_NSUPDATE_AUTH_NONE;
+ } else {
+ DEBUG(SSSDBG_OP_FAILURE, ("Uknown dyndns auth type %s\n", strauth));
+ return EINVAL;
+ }
+
ctx->timer_callback = timer_callback;
ctx->timer_pvt = timer_pvt;
be_nsupdate_timer_schedule(be_ctx->ev, ctx);
diff --git a/src/providers/dp_dyndns.h b/src/providers/dp_dyndns.h
index a1e31e45..14b2dd08 100644
--- a/src/providers/dp_dyndns.h
+++ b/src/providers/dp_dyndns.h
@@ -31,8 +31,14 @@ struct sss_iface_addr;
typedef void (*nsupdate_timer_fn_t)(void *pvt);
+enum be_nsupdate_auth {
+ BE_NSUPDATE_AUTH_NONE,
+ BE_NSUPDATE_AUTH_GSS_TSIG,
+};
+
struct be_nsupdate_ctx {
struct dp_option *opts;
+ enum be_nsupdate_auth auth_type;
time_t last_refresh;
bool timer_in_progress;
@@ -48,6 +54,7 @@ enum dp_dyndns_opts {
DP_OPT_DYNDNS_TTL,
DP_OPT_DYNDNS_UPDATE_PTR,
DP_OPT_DYNDNS_FORCE_TCP,
+ DP_OPT_DYNDNS_AUTH,
DP_OPT_DYNDNS /* attrs counter */
};
@@ -104,6 +111,7 @@ 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,
+ enum be_nsupdate_auth auth_type,
char *nsupdate_msg,
bool force_tcp);
errno_t be_nsupdate_recv(struct tevent_req *req, int *child_status);
diff --git a/src/providers/ipa/ipa_dyndns.c b/src/providers/ipa/ipa_dyndns.c
index bb38d105..b752f116 100644
--- a/src/providers/ipa/ipa_dyndns.c
+++ b/src/providers/ipa/ipa_dyndns.c
@@ -245,6 +245,7 @@ ipa_dyndns_update_send(struct ipa_options *ctx)
sdap_ctx->be,
ctx->dyndns_ctx->opts,
sdap_ctx,
+ ctx->dyndns_ctx->auth_type,
dp_opt_get_string(ctx->dyndns_ctx->opts,
DP_OPT_DYNDNS_IFACE),
dp_opt_get_string(ctx->basic,
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index 97dd6ea9..de9592b8 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -58,6 +58,7 @@ struct dp_option ipa_dyndns_opts[] = {
{ "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 },
+ { "dyndns_auth", DP_OPT_STRING, { "gss-tsig" }, NULL_STRING },
DP_OPTION_TERMINATOR
};
diff --git a/src/providers/ldap/sdap_dyndns.c b/src/providers/ldap/sdap_dyndns.c
index 1c400f65..fbeb6a3d 100644
--- a/src/providers/ldap/sdap_dyndns.c
+++ b/src/providers/ldap/sdap_dyndns.c
@@ -57,6 +57,7 @@ struct sdap_dyndns_update_state {
bool update_ptr;
bool check_diff;
+ enum be_nsupdate_auth auth_type;
bool use_server_with_nsupdate;
char *update_msg;
};
@@ -76,6 +77,7 @@ sdap_dyndns_update_send(TALLOC_CTX *mem_ctx,
struct be_ctx *be_ctx,
struct dp_option *opts,
struct sdap_id_ctx *sdap_ctx,
+ enum be_nsupdate_auth auth_type,
const char *ifname,
const char *hostname,
const char *dns_zone,
@@ -104,6 +106,7 @@ sdap_dyndns_update_send(TALLOC_CTX *mem_ctx,
state->be_res = be_ctx->be_res;
state->ev = ev;
state->opts = opts;
+ state->auth_type = auth_type;
if (ifname) {
/* Unless one family is restricted, just replace all
@@ -323,7 +326,8 @@ 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->auth_type,
+ state->update_msg,
dp_opt_get_bool(state->opts,
DP_OPT_DYNDNS_FORCE_TCP));
if (subreq == NULL) {
@@ -406,7 +410,7 @@ 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,
+ subreq = be_nsupdate_send(state, state->ev, state->auth_type,
state->update_msg,
dp_opt_get_bool(state->opts,
DP_OPT_DYNDNS_FORCE_TCP));
diff --git a/src/providers/ldap/sdap_dyndns.h b/src/providers/ldap/sdap_dyndns.h
index a18a71fc..66de64a5 100644
--- a/src/providers/ldap/sdap_dyndns.h
+++ b/src/providers/ldap/sdap_dyndns.h
@@ -27,6 +27,7 @@
#include "util/util.h"
#include "providers/dp_backend.h"
+#include "providers/dp_dyndns.h"
#include "providers/ldap/ldap_common.h"
struct tevent_req *
@@ -35,6 +36,7 @@ sdap_dyndns_update_send(TALLOC_CTX *mem_ctx,
struct be_ctx *be_ctx,
struct dp_option *opts,
struct sdap_id_ctx *sdap_ctx,
+ enum be_nsupdate_auth auth_type,
const char *ifname,
const char *hostname,
const char *dns_zone,
diff --git a/src/tests/cmocka/test_dyndns.c b/src/tests/cmocka/test_dyndns.c
index 6b52347b..3ff5a30b 100644
--- a/src/tests/cmocka/test_dyndns.c
+++ b/src/tests/cmocka/test_dyndns.c
@@ -210,6 +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,
+ BE_NSUPDATE_AUTH_GSS_TSIG,
discard_const("test message"), false);
assert_non_null(req);
tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx);
@@ -240,6 +241,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,
+ BE_NSUPDATE_AUTH_GSS_TSIG,
discard_const("test message"), false);
assert_non_null(req);
tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx);
@@ -270,6 +272,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,
+ BE_NSUPDATE_AUTH_GSS_TSIG,
discard_const("test message"), false);
assert_non_null(req);
tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx);