From 7a7696e489087f3e02f7d484766dc55112fe7803 Mon Sep 17 00:00:00 2001 From: Pavel Reichl Date: Wed, 8 Jul 2015 09:08:03 -0400 Subject: [PATCH 04/14] DYNDNS: support mult. interfaces for dyndns_iface opt Resolves: https://fedorahosted.org/sssd/ticket/2549 --- src/man/sssd-ad.5.xml | 11 +++--- src/man/sssd-ipa.5.xml | 10 ++++-- src/providers/dp_dyndns.c | 6 ++++ src/providers/dp_dyndns.h | 4 +++ src/providers/ldap/sdap_dyndns.c | 72 +++++++++++++++++++++++++++++++++++----- 5 files changed, 87 insertions(+), 16 deletions(-) diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml index 938a443e027b9bf83c75c240a7d6b2a0876b92c8..ff43ea37066514a87934d07b141e680416dcc05b 100644 --- a/src/man/sssd-ad.5.xml +++ b/src/man/sssd-ad.5.xml @@ -754,15 +754,16 @@ ad_gpo_map_deny = +my_pam_service Optional. Applicable only when dyndns_update - is true. Choose the interface whose IP address - should be used for dynamic DNS updates. - - - NOTE: This option currently supports only one interface. + is true. Choose the interface or a list of interfaces + whose IP addresses should be used for dynamic DNS + updates. Default: Use the IP address of the AD LDAP connection + + Example: dyndns_iface = em1, vnet1, vnet2 + diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml index 0716b6235f93965170983856b930799bfded6258..d450c2fadbb1713096ff766bf536702195cfd137 100644 --- a/src/man/sssd-ipa.5.xml +++ b/src/man/sssd-ipa.5.xml @@ -166,11 +166,12 @@ 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. - NOTE: This option currently supports only one interface. + NOTE: This option currently supports multiple interfaces. NOTE: While it is still possible to use the old @@ -181,6 +182,9 @@ Default: Use the IP address of the IPA LDAP connection + + Example: dyndns_iface = em1, vnet1, vnet2 + diff --git a/src/providers/dp_dyndns.c b/src/providers/dp_dyndns.c index 2ac43a108ff6197d9e2662198a6da976ca348e76..76562840ef1d427629e41617b871caaedab779d4 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 23b833dace58a0ecbb1e2e21963a55186f1d06a8..deba112538ad22cd7f59be07934778ee9d4361e7 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 e99a4f6687035928f6775c38b9df6b2a06d38f38..f5929cff3db6f724efcedeb963e3a12d04f6e1d3 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; -- 2.5.0