summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Reichl <preichl@redhat.com>2015-07-08 09:08:03 -0400
committerPavel Březina <pbrezina@redhat.com>2015-07-27 17:25:20 +0200
commit2f47d56eb551d3945030ed77b138122158a68669 (patch)
treefb5e510a26109ddbb70577baf04910d81cc87a5b
parent4e64b82fe58f2cd603481f300d0d550fb402ec04 (diff)
downloadsssd-2f47d56eb551d3945030ed77b138122158a68669.tar.gz
sssd-2f47d56eb551d3945030ed77b138122158a68669.tar.xz
sssd-2f47d56eb551d3945030ed77b138122158a68669.zip
DYNDNS: support mult. interfaces for dyndns_iface opt
Resolves: https://fedorahosted.org/sssd/ticket/2549
-rw-r--r--src/man/sssd-ad.5.xml9
-rw-r--r--src/man/sssd-ipa.5.xml10
-rw-r--r--src/providers/dp_dyndns.c6
-rw-r--r--src/providers/dp_dyndns.h4
-rw-r--r--src/providers/ldap/sdap_dyndns.c72
5 files changed, 86 insertions, 15 deletions
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index 938a443e0..ff43ea370 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -754,14 +754,15 @@ ad_gpo_map_deny = +my_pam_service
<listitem>
<para>
Optional. Applicable only when dyndns_update
- is true. Choose the interface whose IP address
- should be used for dynamic DNS updates.
+ is true. Choose the interface or a list of interfaces
+ whose IP addresses should be used for dynamic DNS
+ updates.
</para>
<para>
- NOTE: This option currently supports only one interface.
+ Default: Use the IP address of the AD LDAP connection
</para>
<para>
- Default: Use the IP address of the AD LDAP connection
+ Example: dyndns_iface = em1, vnet1, vnet2
</para>
</listitem>
</varlistentry>
diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml
index 0716b6235..d450c2fad 100644
--- a/src/man/sssd-ipa.5.xml
+++ b/src/man/sssd-ipa.5.xml
@@ -166,11 +166,12 @@
<listitem>
<para>
Optional. Applicable only when dyndns_update
- is true. Choose the interface whose IP address
- should be used for dynamic DNS updates.
+ is true. Choose the interface or a list of interfaces
+ whose IP addresses should be used for dynamic DNS
+ updates.
</para>
<para>
- NOTE: This option currently supports only one interface.
+ NOTE: This option currently supports multiple interfaces.
</para>
<para>
NOTE: While it is still possible to use the old
@@ -181,6 +182,9 @@
<para>
Default: Use the IP address of the IPA LDAP connection
</para>
+ <para>
+ Example: dyndns_iface = em1, vnet1, vnet2
+ </para>
</listitem>
</varlistentry>
diff --git a/src/providers/dp_dyndns.c b/src/providers/dp_dyndns.c
index 2ac43a108..76562840e 100644
--- a/src/providers/dp_dyndns.c
+++ b/src/providers/dp_dyndns.c
@@ -49,6 +49,12 @@ struct sss_iface_addr {
struct sockaddr_storage *addr;
};
+void sss_iface_addr_concatenate(struct sss_iface_addr **list,
+ struct sss_iface_addr *list2)
+{
+ DLIST_CONCATENATE((*list), list2, struct sss_iface_addr*);
+}
+
struct sss_iface_addr *
sss_iface_addr_add(TALLOC_CTX *mem_ctx, struct sss_iface_addr **list,
struct sockaddr_storage *ss)
diff --git a/src/providers/dp_dyndns.h b/src/providers/dp_dyndns.h
index 23b833dac..deba11253 100644
--- a/src/providers/dp_dyndns.h
+++ b/src/providers/dp_dyndns.h
@@ -128,4 +128,8 @@ nsupdate_get_addrs_recv(struct tevent_req *req,
struct sss_iface_addr **_addrlist,
size_t *_count);
+void
+sss_iface_addr_concatenate(struct sss_iface_addr **list,
+ struct sss_iface_addr *list2);
+
#endif /* DP_DYNDNS_H_ */
diff --git a/src/providers/ldap/sdap_dyndns.c b/src/providers/ldap/sdap_dyndns.c
index e99a4f668..f5929cff3 100644
--- a/src/providers/ldap/sdap_dyndns.c
+++ b/src/providers/ldap/sdap_dyndns.c
@@ -482,6 +482,65 @@ static void sdap_dyndns_get_addrs_done(struct tevent_req *subreq);
static errno_t sdap_dyndns_add_ldap_conn(struct sdap_dyndns_get_addrs_state *state,
struct sdap_handle *sh);
+static errno_t get_ifaces_addrs(TALLOC_CTX *mem_ctx,
+ const char *iface,
+ struct sss_iface_addr **_result)
+{
+ struct sss_iface_addr *result_addrs = NULL;
+ struct sss_iface_addr *intf_addrs;
+ TALLOC_CTX *tmp_ctx;
+ char **list_of_intfs;
+ int num_of_intfs;
+ errno_t ret;
+ int i;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = split_on_separator(tmp_ctx, iface, ',', true, true, &list_of_intfs,
+ &num_of_intfs);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Parsing names of interfaces failed - %d:[%s].\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ for (i = 0; i < num_of_intfs; i++) {
+ ret = sss_iface_addr_list_get(tmp_ctx, list_of_intfs[i], &intf_addrs);
+ if (ret == EOK) {
+ if (result_addrs != NULL) {
+ /* If there is already an existing list, head of this existing
+ * list will be considered as parent talloc context for the
+ * new list.
+ */
+ talloc_steal(result_addrs, intf_addrs);
+ }
+ sss_iface_addr_concatenate(&result_addrs, intf_addrs);
+ } else if (ret == ENOENT) {
+ /* non-critical failure */
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "Cannot get interface %s or there are no addresses "
+ "bind to it.\n", list_of_intfs[i]);
+ } else {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Cannot get list of addresses from interface %s - %d:[%s]\n",
+ list_of_intfs[i], ret, sss_strerror(ret));
+ goto done;
+ }
+ }
+
+ ret = EOK;
+ *_result = talloc_steal(mem_ctx, result_addrs);
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
static struct tevent_req *
sdap_dyndns_get_addrs_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -500,14 +559,11 @@ sdap_dyndns_get_addrs_send(TALLOC_CTX *mem_ctx,
}
if (iface) {
- ret = sss_iface_addr_list_get(state, iface, &state->addresses);
- if (ret != EOK) {
- DEBUG(ret == ENOENT ? SSSDBG_MINOR_FAILURE : SSSDBG_OP_FAILURE,
- "Cannot get list of addresses from interface %s\n", iface);
- /* non critical failure */
- if (ret == ENOENT) {
- ret = EOK;
- }
+ ret = get_ifaces_addrs(state, iface, &state->addresses);
+ if (ret != EOK || state->addresses == NULL) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "get_ifaces_addrs() failed: %d:[%s]\n",
+ ret, sss_strerror(ret));
}
/* We're done. Just fake an async request completion */
goto done;