dhclient listen on random port (in addition to port 68) by default even if ddns is not used (but compiled in). For some users in secure environments it's a problem. Changing the behaviour to open port only before actually using it. Bug-url: https://bugzilla.redhat.com/1299562 Bug-url: https://bugzilla.redhat.com/962950 Bug-url: https://bugzilla.redhat.com/1386624 --- common/dns.c | 43 +++++++++++++++++++++++++++++++++++++++++++ includes/omapip/isclib.h | 2 ++ omapip/isclib.c | 38 ++++++++++---------------------------- 3 files changed, 55 insertions(+), 28 deletions(-) diff --git a/common/dns.c b/common/dns.c index 0f8be80..37878bc 100644 --- a/common/dns.c +++ b/common/dns.c @@ -2132,6 +2132,41 @@ void ddns_interlude(isc_task_t *taskp, } /* + * Moved here from omapip/isclib.c, function dhcp_context_create. + * Create dnsclient only before the first use. + */ +static isc_result_t +dns_client_lazy() { + isc_result_t result; + if (dhcp_gbl_ctx.dnsclient == NULL){ + result = dns_client_createx2(dhcp_gbl_ctx.mctx, + dhcp_gbl_ctx.actx, + dhcp_gbl_ctx.taskmgr, + dhcp_gbl_ctx.socketmgr, + dhcp_gbl_ctx.timermgr, + 0, + &dhcp_gbl_ctx.dnsclient, + dhcp_gbl_ctx.local4_ptr, + dhcp_gbl_ctx.local6_ptr); + if (result != ISC_R_SUCCESS) + return result; + /* + * If we can't set up the servers we may not be able to + * do DDNS but we should continue to try and perform + * our basic functions and let the user sort it out. + */ + result = dhcp_dns_client_setservers(); + if (result != ISC_R_SUCCESS) { + log_error("Unable to set resolver from resolv.conf; " + "startup continuing but DDNS support " + "may be affected"); + } + }; + return ISC_R_SUCCESS; +} + + +/* * This routine does the generic work for sending a ddns message to * modify the forward record (A or AAAA) and calls one of a set of * routines to build the specific message. @@ -2154,6 +2189,10 @@ ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb, const char *file, int line) /* Get a pointer to the clientname to make things easier. */ clientname = (unsigned char *)ddns_cb->fwd_name.data; + result = dns_client_lazy(); + if (result != ISC_R_SUCCESS) + return result; + /* Extract and validate the type of the address. */ if (ddns_cb->address.len == 4) { ddns_cb->address_type = dns_rdatatype_a; @@ -2359,6 +2398,10 @@ ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb, const char *file, int line) unsigned char buf[256]; int buflen; + result = dns_client_lazy(); + if (result != ISC_R_SUCCESS) + return result; + /* * Try to lookup the zone in the zone cache. As with the forward * case it's okay if we don't have one, the DNS code will try to diff --git a/includes/omapip/isclib.h b/includes/omapip/isclib.h index caa388a..7f2719b 100644 --- a/includes/omapip/isclib.h +++ b/includes/omapip/isclib.h @@ -98,6 +98,8 @@ typedef struct dhcp_context { isc_timermgr_t *timermgr; #if defined (NSUPDATE) dns_client_t *dnsclient; + isc_sockaddr_t *local4_ptr; + isc_sockaddr_t *local6_ptr; #endif } dhcp_context_t; diff --git a/omapip/isclib.c b/omapip/isclib.c index 781db84..9feee09 100644 --- a/omapip/isclib.c +++ b/omapip/isclib.c @@ -225,40 +225,22 @@ dhcp_context_create(int flags, } #if defined (NSUPDATE) + /* + * Setting addresses only. + * All real work will be done later on if needed to avoid listening + * on ddns port if client/server was compiled with ddns support + * but not using it. + */ if ((flags & DHCP_CONTEXT_POST_DB) != 0) { - isc_sockaddr_t localaddr4, *localaddr4_ptr = NULL; - isc_sockaddr_t localaddr6, *localaddr6_ptr = NULL; + isc_sockaddr_t localaddr4; + isc_sockaddr_t localaddr6; if (local4 != NULL) { isc_sockaddr_fromin(&localaddr4, local4, 0); - localaddr4_ptr = &localaddr4; + dhcp_gbl_ctx.local4_ptr = &localaddr4; } if (local6 != NULL) { isc_sockaddr_fromin6(&localaddr6, local6, 0); - localaddr6_ptr = &localaddr6; - } - - result = dns_client_createx2(dhcp_gbl_ctx.mctx, - dhcp_gbl_ctx.actx, - dhcp_gbl_ctx.taskmgr, - dhcp_gbl_ctx.socketmgr, - dhcp_gbl_ctx.timermgr, - 0, - &dhcp_gbl_ctx.dnsclient, - localaddr4_ptr, - localaddr6_ptr); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * If we can't set up the servers we may not be able to - * do DDNS but we should continue to try and perform - * our basic functions and let the user sort it out. - */ - result = dhcp_dns_client_setservers(); - if (result != ISC_R_SUCCESS) { - log_error("Unable to set resolver from resolv.conf; " - "startup continuing but DDNS support " - "may be affected"); + dhcp_gbl_ctx.local6_ptr = &localaddr6; } } #endif -- 2.9.3