From 038b9ba28a618e3e553803da632116a040b94034 Mon Sep 17 00:00:00 2001 From: Pavel Reichl Date: Jul 24 2015 07:30:41 +0000 Subject: DYNDNS: support mult. interfaces for dyndns_iface opt Resolves: https://fedorahosted.org/sssd/ticket/2549 --- diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml index 938a443..ff43ea3 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 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. + Default: Use the IP address of the AD LDAP connection - 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 0716b62..d450c2f 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 2ac43a1..7656284 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 23b833d..deba112 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 e99a4f6..f5929cf 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;