summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--src/config/SSSDConfig/__init__.py.in3
-rwxr-xr-xsrc/config/SSSDConfigTest.py6
-rw-r--r--src/config/etc/sssd.api.conf5
-rw-r--r--src/man/sssd-ipa.5.xml28
-rw-r--r--src/providers/dp_dyndns.c57
-rw-r--r--src/providers/dp_dyndns.h24
-rw-r--r--src/providers/ipa/ipa_common.c96
-rw-r--r--src/providers/ipa/ipa_common.h7
-rw-r--r--src/providers/ipa/ipa_dyndns.c9
-rw-r--r--src/providers/ipa/ipa_init.c29
-rw-r--r--src/providers/ipa/ipa_opts.h10
-rw-r--r--src/tests/cmocka/test_dyndns.c2
13 files changed, 244 insertions, 35 deletions
diff --git a/Makefile.am b/Makefile.am
index 542a490d9..1bbfb01c3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1287,7 +1287,8 @@ dyndns_tests_SOURCES = \
$(TEST_MOCK_OBJ) \
$(SSSD_RESOLV_OBJ) \
src/tests/common_tev.c \
- src/tests/cmocka/test_dyndns.c
+ src/tests/cmocka/test_dyndns.c \
+ src/providers/data_provider_opts.c
dyndns_tests_CFLAGS = \
$(AM_CFLAGS) \
-DDYNDNS_TIMEOUT=2
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 256c4b314..9f11d31c2 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -125,6 +125,9 @@ option_strings = {
'entry_cache_service_timeout' : _('Entry cache timeout length (seconds)'),
'entry_cache_autofs_timeout' : _('Entry cache timeout length (seconds)'),
'entry_cache_sudo_timeout' : _('Entry cache timeout length (seconds)'),
+ 'dyndns_update' : _("Whether to automatically update the client's DNS entry"),
+ 'dyndns_ttl' : _("The TTL to apply to the client's DNS entry after updating it"),
+ 'dyndns_iface' : _("The interface whose IP should be used for dynamic DNS updates"),
# [provider/ipa]
'ipa_domain' : _('IPA domain'),
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index 9c0e34e64..2b4df8742 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -507,6 +507,9 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
'account_cache_expiration',
'dns_resolver_timeout',
'dns_discovery_domain',
+ 'dyndns_update',
+ 'dyndns_ttl',
+ 'dyndns_iface',
'override_gid',
'case_sensitive',
'override_homedir',
@@ -850,6 +853,9 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
'lookup_family_order',
'dns_resolver_timeout',
'dns_discovery_domain',
+ 'dyndns_update',
+ 'dyndns_ttl',
+ 'dyndns_iface',
'override_gid',
'case_sensitive',
'override_homedir',
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index 3ed9d583c..02e2a0a66 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -121,6 +121,11 @@ entry_cache_service_timeout = int, None, false
entry_cache_autofs_timeout = int, None, false
entry_cache_sudo_timeout = int, None, false
+# Dynamic DNS updates
+dyndns_update = bool, None, false
+dyndns_ttl = int, None, false
+dyndns_iface = str, None, false
+
# Special providers
[provider/permit]
diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml
index f8cb0939d..bedb11072 100644
--- a/src/man/sssd-ipa.5.xml
+++ b/src/man/sssd-ipa.5.xml
@@ -113,7 +113,7 @@
</varlistentry>
<varlistentry>
- <term>ipa_dyndns_update (boolean)</term>
+ <term>dyndns_update (boolean)</term>
<listitem>
<para>
Optional. This option tells SSSD to automatically
@@ -126,34 +126,52 @@
realm must be set properly in /etc/krb5.conf
</para>
<para>
+ NOTE: While it is still possible to use the old
+ <emphasis>ipa_dyndns_update</emphasis> option, users
+ should migrate to using <emphasis>dyndns_update</emphasis>
+ in their config file.
+ </para>
+ <para>
Default: false
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>ipa_dyndns_ttl (integer)</term>
+ <term>dyndns_ttl (integer)</term>
<listitem>
<para>
The TTL to apply to the client DNS record when updating it.
- If ipa_dyndns_update is false this has no effect. This will
+ If dyndns_update is false this has no effect. This will
override the TTL serverside if set by an administrator.
</para>
<para>
+ NOTE: While it is still possible to use the old
+ <emphasis>ipa_dyndns_ttl</emphasis> option, users
+ should migrate to using <emphasis>dyndns_ttl</emphasis>
+ in their config file.
+ </para>
+ <para>
Default: 1200 (seconds)
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>ipa_dyndns_iface (string)</term>
+ <term>dyndns_iface (string)</term>
<listitem>
<para>
- Optional. Applicable only when ipa_dyndns_update
+ Optional. Applicable only when dyndns_update
is true. Choose the interface whose IP address
should be used for dynamic DNS updates.
</para>
<para>
+ NOTE: While it is still possible to use the old
+ <emphasis>ipa_dyndns_iface</emphasis> option, users
+ should migrate to using <emphasis>dyndns_iface</emphasis>
+ in their config file.
+ </para>
+ <para>
Default: Use the IP address of the IPA LDAP connection
</para>
</listitem>
diff --git a/src/providers/dp_dyndns.c b/src/providers/dp_dyndns.c
index 7e5cc690e..81228d5cf 100644
--- a/src/providers/dp_dyndns.c
+++ b/src/providers/dp_dyndns.c
@@ -878,3 +878,60 @@ be_nsupdate_recv(struct tevent_req *req, int *child_status)
return EOK;
}
+
+errno_t
+be_nsupdate_check(void)
+{
+ errno_t ret;
+ struct stat stat_buf;
+
+ /* Ensure that nsupdate exists */
+ errno = 0;
+ ret = stat(NSUPDATE_PATH, &stat_buf);
+ if (ret == -1) {
+ ret = errno;
+ if (ret == ENOENT) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("%s does not exist. Dynamic DNS updates disabled\n",
+ NSUPDATE_PATH));
+ } else {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("Could not set up dynamic DNS updates: [%d][%s]\n",
+ ret, strerror(ret)));
+ }
+ }
+
+ return ret;
+}
+
+static struct dp_option default_dyndns_opts[] = {
+ { "dyndns_update", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
+ { "dyndns_iface", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "dyndns_ttl", DP_OPT_NUMBER, { .number = 1200 }, NULL_NUMBER },
+
+ DP_OPTION_TERMINATOR
+};
+
+errno_t
+be_nsupdate_init(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx,
+ struct dp_option *defopts, struct be_nsupdate_ctx **_ctx)
+{
+ errno_t ret;
+ struct dp_option *src_opts;
+ struct be_nsupdate_ctx *ctx;
+
+ ctx = talloc(mem_ctx, struct be_nsupdate_ctx);
+ if (ctx == NULL) return ENOMEM;
+
+ src_opts = defopts ? defopts : default_dyndns_opts;
+
+ ret = dp_get_options(ctx, be_ctx->cdb, be_ctx->conf_path,
+ src_opts, DP_OPT_DYNDNS, &ctx->opts);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot retrieve dynamic DNS options\n"));
+ return ret;
+ }
+
+ *_ctx = ctx;
+ return EOK;
+}
diff --git a/src/providers/dp_dyndns.h b/src/providers/dp_dyndns.h
index b0020560a..95403a3ae 100644
--- a/src/providers/dp_dyndns.h
+++ b/src/providers/dp_dyndns.h
@@ -22,12 +22,34 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+
+#ifndef DP_DYNDNS_H_
+#define DP_DYNDNS_H_
+
/* dynamic dns helpers */
struct sss_iface_addr;
+struct be_nsupdate_ctx {
+ struct dp_option *opts;
+};
+
+enum dp_dyndns_opts {
+ DP_OPT_DYNDNS_UPDATE,
+ DP_OPT_DYNDNS_IFACE,
+ DP_OPT_DYNDNS_TTL,
+
+ DP_OPT_DYNDNS /* attrs counter */
+};
+
#define DYNDNS_REMOVE_A 0x1
#define DYNDNS_REMOVE_AAAA 0x2
+errno_t be_nsupdate_check(void);
+
+errno_t
+be_nsupdate_init(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx,
+ struct dp_option *defopts, struct be_nsupdate_ctx **ctx);
+
errno_t
sss_iface_addr_list_get(TALLOC_CTX *mem_ctx, const char *ifname,
struct sss_iface_addr **_addrlist);
@@ -66,3 +88,5 @@ struct tevent_req * nsupdate_get_addrs_send(TALLOC_CTX *mem_ctx,
errno_t nsupdate_get_addrs_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
char ***_addrlist);
+
+#endif /* DP_DYNDNS_H_ */
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index be1bd1d2f..51750b2af 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -29,6 +29,7 @@
#include "db/sysdb_selinux.h"
#include "providers/ipa/ipa_common.h"
#include "providers/ldap/sdap_async_private.h"
+#include "providers/dp_dyndns.h"
#include "util/sss_krb5.h"
#include "db/sysdb_services.h"
#include "db/sysdb_autofs.h"
@@ -1008,3 +1009,98 @@ done:
talloc_free(tmp_ctx);
return ret;
}
+
+errno_t ipa_get_dyndns_options(struct be_ctx *be_ctx,
+ struct ipa_options *ctx)
+{
+ errno_t ret;
+ char *val;
+ bool update;
+ int ttl;
+
+ ret = be_nsupdate_init(ctx, be_ctx, ipa_dyndns_opts, &ctx->dyndns_ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("Cannot initialize IPA dyndns opts [%d]: %s\n",
+ ret, sss_strerror(ret)));
+ return ret;
+ }
+
+ if (ctx->basic == NULL) {
+ DEBUG(SSSDBG_MINOR_FAILURE, ("IPA basic options not (yet) "
+ "initialized, cannot copy legacy options\n"));
+ return EOK;
+ }
+
+ /* Reuse legacy option values */
+ ret = confdb_get_string(be_ctx->cdb, ctx, be_ctx->conf_path,
+ "ipa_dyndns_update", NULL, &val);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot get the value of %s\n",
+ "ipa_dyndns_update"));
+ /* Not fatal */
+ } else if (ret == EOK && val) {
+ if (strcasecmp(val, "FALSE") == 0) {
+ update = false;
+ } else if (strcasecmp(val, "TRUE") == 0) {
+ update = true;
+ } else {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("ipa_dyndns_update value is not a boolean!\n"));
+ talloc_free(val);
+ return EINVAL;
+ }
+
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Deprecation warning: The option %s is "
+ "deprecated and should not be used in favor of %s\n",
+ "ipa_dyndns_update", "dyndns_update"));
+
+ ret = dp_opt_set_bool(ctx->dyndns_ctx->opts,
+ DP_OPT_DYNDNS_UPDATE, update);
+ talloc_free(val);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot set option value\n"));
+ return ret;
+ }
+ }
+
+ ret = confdb_get_int(be_ctx->cdb, be_ctx->conf_path,
+ "ipa_dyndns_ttl", -1, &ttl);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot get the value of %s\n",
+ "ipa_dyndns_ttl"));
+ /* Not fatal */
+ } else if (ret == EOK && ttl != -1) {
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Deprecation warning: The option %s is "
+ "deprecated and should not be used in favor of %s\n",
+ "ipa_dyndns_ttl", "dyndns_ttl"));
+
+ ret = dp_opt_set_int(ctx->dyndns_ctx->opts, DP_OPT_DYNDNS_TTL, ttl);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot set option value\n"));
+ return ret;
+ }
+ }
+
+ /* Reuse legacy option values */
+ ret = confdb_get_string(be_ctx->cdb, ctx, be_ctx->conf_path,
+ "ipa_dyndns_iface", NULL, &val);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot get the value of %s\n",
+ "ipa_dyndns_iface"));
+ /* Not fatal */
+ } else if (ret == EOK && val) {
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Deprecation warning: The option %s is "
+ "deprecated and should not be used in favor of %s\n",
+ "ipa_dyndns_iface", "dyndns_iface"));
+
+ ret = dp_opt_set_string(ctx->dyndns_ctx->opts,
+ DP_OPT_DYNDNS_IFACE, val);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot set option value\n"));
+ return ret;
+ }
+ }
+
+ return EOK;
+}
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index 6e77c9972..a32867dd4 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -37,9 +37,6 @@ enum ipa_basic_opt {
IPA_SERVER,
IPA_BACKUP_SERVER,
IPA_HOSTNAME,
- IPA_DYNDNS_UPDATE,
- IPA_DYNDNS_TTL,
- IPA_DYNDNS_IFACE,
IPA_HBAC_SEARCH_BASE,
IPA_HOST_SEARCH_BASE,
IPA_SELINUX_SEARCH_BASE,
@@ -139,6 +136,7 @@ struct ipa_options {
struct sdap_options *id;
struct ipa_id_ctx *id_ctx;
struct be_resolv_ctx *be_res;
+ struct be_nsupdate_ctx *dyndns_ctx;
/* auth and chpass provider */
struct dp_option *auth;
@@ -169,6 +167,9 @@ int ipa_get_autofs_options(struct ipa_options *ipa_opts,
const char *conf_path,
struct sdap_options **_opts);
+errno_t ipa_get_dyndns_options(struct be_ctx *be_ctx,
+ struct ipa_options *ctx);
+
int ipa_autofs_init(struct be_ctx *be_ctx,
struct ipa_id_ctx *id_ctx,
struct bet_ops **ops,
diff --git a/src/providers/ipa/ipa_dyndns.c b/src/providers/ipa/ipa_dyndns.c
index 79918a261..8023b5336 100644
--- a/src/providers/ipa/ipa_dyndns.c
+++ b/src/providers/ipa/ipa_dyndns.c
@@ -28,6 +28,7 @@
#include "providers/ipa/ipa_common.h"
#include "providers/ipa/ipa_dyndns.h"
#include "providers/data_provider.h"
+#include "providers/dp_dyndns.h"
void ipa_dyndns_update(void *pvt);
@@ -135,16 +136,16 @@ ipa_dyndns_update_send(struct ipa_options *ctx)
subreq = sdap_dyndns_update_send(state, sdap_ctx->be->ev,
sdap_ctx->be, sdap_ctx,
- dp_opt_get_string(ctx->basic,
- IPA_DYNDNS_IFACE),
+ dp_opt_get_string(ctx->dyndns_ctx->opts,
+ DP_OPT_DYNDNS_IFACE),
dp_opt_get_string(ctx->basic,
IPA_HOSTNAME),
dns_zone,
dp_opt_get_string(ctx->basic,
IPA_KRB5_REALM),
servername,
- dp_opt_get_int(ctx->basic,
- IPA_DYNDNS_TTL),
+ dp_opt_get_int(ctx->dyndns_ctx->opts,
+ DP_OPT_DYNDNS_TTL),
true);
if (!subreq) {
ret = EIO;
diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index 0e9fe0dd1..5192bc81f 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -40,6 +40,7 @@
#include "providers/ldap/sdap_access.h"
#include "providers/ipa/ipa_subdomains.h"
#include "providers/ipa/ipa_srv.h"
+#include "providers/dp_dyndns.h"
struct ipa_options *ipa_options = NULL;
@@ -110,11 +111,9 @@ int sssm_ipa_id_init(struct be_ctx *bectx,
{
struct ipa_id_ctx *ipa_ctx;
struct sdap_id_ctx *sdap_ctx;
- struct stat stat_buf;
const char *hostname;
const char *ipa_domain;
struct ipa_srv_plugin_ctx *srv_ctx;
- errno_t err;
int ret;
if (!ipa_options) {
@@ -153,7 +152,12 @@ int sssm_ipa_id_init(struct be_ctx *bectx,
goto done;
}
- if(dp_opt_get_bool(ipa_options->basic, IPA_DYNDNS_UPDATE)) {
+ ret = ipa_get_dyndns_options(bectx, ipa_options);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ if (dp_opt_get_bool(ipa_options->dyndns_ctx->opts, DP_OPT_DYNDNS_UPDATE)) {
/* Perform automatic DNS updates when the
* IP address changes.
* Register a callback for successful LDAP
@@ -161,21 +165,10 @@ int sssm_ipa_id_init(struct be_ctx *bectx,
* identify that we have gone online.
*/
- /* Ensure that nsupdate exists */
- errno = 0;
- ret = stat(NSUPDATE_PATH, &stat_buf);
- if (ret == -1) {
- err = errno;
- if (err == ENOENT) {
- DEBUG(0, ("%s does not exist. Dynamic DNS updates disabled\n",
- NSUPDATE_PATH));
- }
- else {
- DEBUG(0, ("Could not set up dynamic DNS updates: [%d][%s]\n",
- err, strerror(err)));
- }
- }
- else {
+ DEBUG(SSSDBG_CONF_SETTINGS,
+ ("Dynamic DNS updates are on. Checking for nsupdate..\n"));
+ ret = be_nsupdate_check();
+ if (ret == EOK) {
/* nsupdate is available. Dynamic updates
* are supported
*/
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index 6adbdd96a..392fcd86f 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -35,9 +35,6 @@ struct dp_option ipa_basic_opts[] = {
{ "ipa_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ipa_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ipa_hostname", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ipa_dyndns_update", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
- { "ipa_dyndns_ttl", DP_OPT_NUMBER, { .number = 1200}, NULL_NUMBER},
- { "ipa_dyndns_iface", DP_OPT_STRING, NULL_STRING, NULL_STRING},
{ "ipa_hbac_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING},
{ "ipa_host_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ipa_selinux_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
@@ -54,6 +51,13 @@ struct dp_option ipa_basic_opts[] = {
DP_OPTION_TERMINATOR
};
+struct dp_option ipa_dyndns_opts[] = {
+ { "dyndns_update", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
+ { "dyndns_iface", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "dyndns_ttl", DP_OPT_NUMBER, { .number = 1200 }, NULL_NUMBER },
+ DP_OPTION_TERMINATOR
+};
+
struct dp_option ipa_def_ldap_opts[] = {
{ "ldap_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_backup_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING },
diff --git a/src/tests/cmocka/test_dyndns.c b/src/tests/cmocka/test_dyndns.c
index fd9240438..93d3373a4 100644
--- a/src/tests/cmocka/test_dyndns.c
+++ b/src/tests/cmocka/test_dyndns.c
@@ -81,7 +81,7 @@ void __wrap_execv(const char *path, char *const argv[])
int __wrap_getifaddrs(struct ifaddrs **_ifap)
{
- struct ifaddrs *ifap;
+ struct ifaddrs *ifap = NULL;
struct ifaddrs *ifap_prev = NULL;
struct ifaddrs *ifap_head = NULL;
char *name;