diff options
author | Pavel Reichl <preichl@redhat.com> | 2015-07-08 09:08:03 -0400 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2015-07-24 09:30:41 +0200 |
commit | 038b9ba28a618e3e553803da632116a040b94034 (patch) | |
tree | af4981d1506687ff32228a76e9c11b7bad2b40d8 | |
parent | aa3fd6fde3888c0e333cad852ae5b4f671d55f58 (diff) | |
download | sssd-038b9ba28a618e3e553803da632116a040b94034.tar.gz sssd-038b9ba28a618e3e553803da632116a040b94034.tar.xz sssd-038b9ba28a618e3e553803da632116a040b94034.zip |
DYNDNS: support mult. interfaces for dyndns_iface opt
Resolves:
https://fedorahosted.org/sssd/ticket/2549
-rw-r--r-- | src/man/sssd-ad.5.xml | 9 | ||||
-rw-r--r-- | src/man/sssd-ipa.5.xml | 10 | ||||
-rw-r--r-- | src/providers/dp_dyndns.c | 6 | ||||
-rw-r--r-- | src/providers/dp_dyndns.h | 4 | ||||
-rw-r--r-- | src/providers/ldap/sdap_dyndns.c | 72 |
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; |