2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-22 18:07:25 +00:00

-n master Patch for 30461 and update the auto generated files

Update the auto genrated files to add the required bind9
libraries

Fix up dhcpctl/Makefile.am to include the isccfg lib

Patch for 30461 to allow the DHCP server to find
the name server to update via the DNS
Conflicts:
This commit is contained in:
Shawn Routhier 2013-12-10 04:03:12 +00:00
parent 64fb661cc8
commit e54ff84f08
21 changed files with 847 additions and 45 deletions

View File

@ -109,6 +109,14 @@ work on other platforms. Please report any problems and suggested fixes to
man page for a description.
[ISC-Bugs #19598]
- When doing DDNS if there isn't an appropriate zone statement attempt
to find a reasoanble nameserver via a DNS resolver. This restores
some functionality that was lost in the transition to asynchronous
DDNS. Due to the lack of security and increase in fragility of the
system when using this feature we strongly recommend the use of
appropriate zone statements rather than using this functionality.
[ISC-Bugs #30461]
Changes since 4.2.5
- Address static analysis warnings.

View File

@ -4,8 +4,8 @@ dhclient_SOURCES = clparse.c dhclient.c dhc6.c \
scripts/bsdos scripts/freebsd scripts/linux scripts/macos \
scripts/netbsd scripts/nextstep scripts/openbsd \
scripts/solaris scripts/openwrt
dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
../bind/lib/libdns.a ../bind/lib/libisc.a
dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.a ../bind/lib/libirs.a \
../bind/lib/libdns.a ../bind/lib/libisccfg.a ../bind/lib/libisc.a
man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
EXTRA_DIST = $(man_MANS)

View File

@ -98,7 +98,8 @@ am_dhclient_OBJECTS = clparse.$(OBJEXT) dhclient.$(OBJEXT) \
dhc6.$(OBJEXT)
dhclient_OBJECTS = $(am_dhclient_OBJECTS)
dhclient_DEPENDENCIES = ../common/libdhcp.a ../omapip/libomapi.a \
../bind/lib/libdns.a ../bind/lib/libisc.a
../bind/lib/libirs.a ../bind/lib/libdns.a \
../bind/lib/libisccfg.a ../bind/lib/libisc.a
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@ -294,8 +295,8 @@ dhclient_SOURCES = clparse.c dhclient.c dhc6.c \
scripts/netbsd scripts/nextstep scripts/openbsd \
scripts/solaris scripts/openwrt
dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
../bind/lib/libdns.a ../bind/lib/libisc.a
dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.a ../bind/lib/libirs.a \
../bind/lib/libdns.a ../bind/lib/libisccfg.a ../bind/lib/libisc.a
man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
EXTRA_DIST = $(man_MANS)

View File

@ -157,10 +157,123 @@ typedef struct dhcp_ddns_rdata {
} dhcp_ddns_data_t;
#if defined (NSUPDATE)
#if defined (DNS_ZONE_LOOKUP)
/*
* The structure used to find a nameserver if there wasn't a zone entry.
* Currently we assume we won't have many of these outstanding at any
* time so we go with a simple linked list.
* In use find_zone_start() will fill in the oname with the name
* requested by the DDNS code. zname will point to it and be
* advanced as labels are removed. If the DNS client code returns
* a set of name servers eventp and rdataset will be set. Then
* the code will walk through the nameservers in namelist and
* find addresses that are stored in addrs and addrs6.
*/
typedef struct dhcp_ddns_ns {
struct dhcp_ddns_ns *next;
struct data_string oname; /* the original name for DDNS */
char *zname; /* a pointer into the original name for
the zone we are checking */
dns_clientresevent_t *eventp; /* pointer to the event that provided the
namelist, we can't free the eventp
until we free the namelist */
dns_name_t *ns_name; /* current name server we are examining */
dns_rdataset_t *rdataset;
dns_rdatatype_t rdtype; /* type of address we want */
struct in_addr addrs[DHCP_MAXNS]; /* space for v4 addresses */
struct in6_addr addrs6[DHCP_MAXNS]; /* space for v6 addresses */
int num_addrs;
int num_addrs6;
int ttl;
void *transaction; /* transaction id for DNS calls */
} dhcp_ddns_ns_t;
/*
* The list of DDNS names for which we are attempting to find a name server.
* This list is used for finding the name server, it doesn't include the
* information necessary to do the DDNS request after finding a name server.
* The code attempts to minimize duplicate requests by examining the list
* to see if we are already trying to find a substring of the new request.
* For example imagine the first request is "a.b.c.d.e." and the server has
* already discarded the first two lables and is trying "c.d.e.". If the
* next request is for "x.y.c.d.e." the code assumes the in progress
* request is sufficient and doesn't add a new request for the second name.
* If the next request was for "x.y.z.d.e." the code doesn't assume they
* will use the same nameserver and starts a second request.
* This strategy will not eliminate all duplicates but is simple and
* should be sufficient.
*/
dhcp_ddns_ns_t *dns_outstanding_ns = NULL;
/*
* Routines to manipulate the list of outstanding searches
*
* add_to_ns_queue() - adds the given control block to the queue
*
* remove_from_ns_queue() - removes the given control block from
* the queue
*
* find_in_ns_queue() compares the name from the given control
* block with the control blocks in the queue. It returns
* success if a matching entry is found. In order to match
* the entry already on the queue must be shorter than the
* incoming name must match the ending substring of the name.
*/
void
add_to_ns_queue(dhcp_ddns_ns_t *ns_cb)
{
ns_cb->next = dns_outstanding_ns;
dns_outstanding_ns = ns_cb;
}
void
remove_from_ns_queue(dhcp_ddns_ns_t *ns_cb)
{
dhcp_ddns_ns_t **foo;
foo = &dns_outstanding_ns;
while (*foo) {
if (*foo == ns_cb) {
*foo = ns_cb->next;
break;
}
foo = &((*foo)->next);
}
ns_cb->next = NULL;
}
isc_result_t
find_in_ns_queue(dhcp_ddns_ns_t *ns_cb)
{
dhcp_ddns_ns_t *temp_cb;
int in_len, temp_len;
in_len = strlen(ns_cb->zname);
for(temp_cb = dns_outstanding_ns;
temp_cb != NULL;
temp_cb = temp_cb->next) {
temp_len = strlen(temp_cb->zname);
if (temp_len > in_len)
continue;
if (strcmp(temp_cb->zname,
ns_cb->zname + (in_len - temp_len)) == 0)
return(ISC_R_SUCCESS);
}
return(ISC_R_NOTFOUND);
}
void cache_found_zone (dhcp_ddns_ns_t *);
#endif
void ddns_interlude(isc_task_t *, isc_event_t *);
#if defined (TRACING)
/*
* Code to support tracing DDNS packets. We trace packets going to and
@ -437,6 +550,8 @@ trace_ddns_init()
#define ddns_update dns_client_startupdate
#endif /* TRACING */
#define zone_resolve dns_client_startresolve
/*
* Code to allocate and free a dddns control block. This block is used
* to pass and track the information associated with a DDNS update request.
@ -548,6 +663,21 @@ void tkey_free (ns_tsig_key **key)
}
#endif
isc_result_t remove_dns_zone (struct dns_zone *zone)
{
struct dns_zone *tz = NULL;
if (dns_zone_hash) {
dns_zone_hash_lookup(&tz, dns_zone_hash, zone->name, 0, MDL);
if (tz != NULL) {
dns_zone_hash_delete(dns_zone_hash, tz->name, 0, MDL);
dns_zone_dereference(&tz, MDL);
}
}
return (ISC_R_SUCCESS);
}
isc_result_t enter_dns_zone (struct dns_zone *zone)
{
struct dns_zone *tz = (struct dns_zone *)0;
@ -594,7 +724,11 @@ isc_result_t dns_zone_lookup (struct dns_zone **zone, const char *name)
}
if (!dns_zone_hash_lookup (zone, dns_zone_hash, name, 0, MDL))
status = ISC_R_NOTFOUND;
else
else if ((*zone)->timeout && (*zone)->timeout < cur_time) {
dns_zone_hash_delete(dns_zone_hash, (*zone)->name, 0, MDL);
dns_zone_dereference(zone, MDL);
status = ISC_R_NOTFOUND;
} else
status = ISC_R_SUCCESS;
if (tname)
@ -654,6 +788,456 @@ int dns_zone_dereference (ptr, file, line)
}
#if defined (NSUPDATE)
#if defined (DNS_ZONE_LOOKUP)
/* Helper function to copy the address from an rdataset to
* the nameserver control block. Mostly to avoid really long
* lines in the nested for loops
*/
void
zone_addr_to_ns(dhcp_ddns_ns_t *ns_cb,
dns_rdataset_t *rdataset)
{
dns_rdata_t rdata;
dns_rdata_in_a_t a;
dns_rdata_in_aaaa_t aaaa;
dns_rdata_init(&rdata);
dns_rdataset_current(rdataset, &rdata);
switch (rdataset->type) {
case dns_rdatatype_a:
(void) dns_rdata_tostruct(&rdata, &a, NULL);
memcpy(&ns_cb->addrs[ns_cb->num_addrs], &a.in_addr, 4);
ns_cb->num_addrs++;
dns_rdata_freestruct(&a);
break;
case dns_rdatatype_aaaa:
(void) dns_rdata_tostruct(&rdata, &aaaa, NULL);
memcpy(&ns_cb->addrs6[ns_cb->num_addrs6], &aaaa.in6_addr, 16);
ns_cb->num_addrs6++;
dns_rdata_freestruct(&aaaa);
break;
default:
break;
}
if ((ns_cb->ttl == 0) || (ns_cb->ttl > rdataset->ttl))
ns_cb->ttl = rdataset->ttl;
}
/*
* The following three routines co-operate to find the addresses of
* the nameservers to use for a zone if we don't have a zone statement.
* We strongly suggest the use of a zone statement to avoid problmes
* and to allow for the use of TSIG and therefore better security, but
* include this functionality for those that don't want such statements.
*
* find_zone_start(ddns_cb, direction)
* This is the first of the routines, it is called from the rest of
* the ddns code when we have received a request for DDNS for a name
* and don't have a zone entry that would cover that name. The name
* is in the ddns_cb as specified by the direction (forward or reverse).
* The start function pulls the name out and constructs the name server
* block then starts the process by calling the DNS client code.
*
* find_zone_ns(taskp, eventp)
* This is the second step of the process. The DNS client code will
* call this when it has gotten a response or timed out. If the response
* doesn't have a list of nameservers we remove another label from the
* zone name and try again. If the response does include a list of
* nameservers we start walking through the list attempting to get
* addresses for the nameservers.
*
* find_zone_addrs(taskp, eventp)
* This is the third step of the process. In find_zone_ns we got
* a list of nameserves and started walking through them. This continues
* the walk and if we get back any addresses it adds them to our list.
* When we get enough addresses or run out of nameservers we construct
* a zone entry and insert it into the zone hash for the rest of the
* DDNS code to use.
*/
void
find_zone_addrs(isc_task_t *taskp,
isc_event_t *eventp)
{
dns_clientresevent_t *ddns_event = (dns_clientresevent_t *)eventp;
dhcp_ddns_ns_t *ns_cb = (dhcp_ddns_ns_t *)eventp->ev_arg;
dns_name_t *ns_name = NULL;
dns_rdataset_t *rdataset;
isc_result_t result;
dns_name_t *name;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_ns_t ns;
/* the transaction is done, get rid of the tag */
dns_client_destroyrestrans(&ns_cb->transaction);
/* If we succeeded we try and extract the addresses, if we can
* and we have enough we are done. If we didn't succeed or
* we don't have enough addresses afterwards we drop through
* and try the next item on the list.
*/
if (ddns_event->result == ISC_R_SUCCESS) {
for (name = ISC_LIST_HEAD(ddns_event->answerlist);
name != NULL;
name = ISC_LIST_NEXT(name, link)) {
for (rdataset = ISC_LIST_HEAD(name->list);
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link)) {
for (result = dns_rdataset_first(rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(rdataset)) {
/* add address to cb */
zone_addr_to_ns(ns_cb, rdataset);
/* We are done if we have
* enough addresses
*/
if (ns_cb->num_addrs +
ns_cb->num_addrs6 >= DHCP_MAXNS)
goto done;
}
}
}
}
/* We need more addresses.
* We restart the loop we were in before.
*/
for (ns_name = ns_cb->ns_name;
ns_name != NULL;
ns_name = ISC_LIST_NEXT(ns_name, link)) {
if (ns_name == ns_cb->ns_name) {
/* first time through, use saved state */
rdataset = ns_cb->rdataset;
} else {
rdataset = ISC_LIST_HEAD(ns_name->list);
}
for (;
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link)) {
if (rdataset->type != dns_rdatatype_ns)
continue;
dns_rdata_init(&rdata);
if (rdataset == ns_cb->rdataset) {
/* first time through use the saved state */
if (ns_cb->rdtype == dns_rdatatype_a) {
ns_cb->rdtype = dns_rdatatype_aaaa;
} else {
ns_cb->rdtype = dns_rdatatype_a;
if (dns_rdataset_next(rdataset) !=
ISC_R_SUCCESS)
continue;
}
} else {
if ((!dns_rdataset_isassociated(rdataset)) ||
(dns_rdataset_first(rdataset) !=
ISC_R_SUCCESS))
continue;
}
dns_rdataset_current(rdataset, &rdata);
if (dns_rdata_tostruct(&rdata, &ns, NULL) !=
ISC_R_SUCCESS)
continue;
/* Save our current state */
ns_cb->ns_name = ns_name;
ns_cb->rdataset = rdataset;
/* And call out to DNS */
result = zone_resolve(dhcp_gbl_ctx.dnsclient, &ns.name,
dns_rdataclass_in,
ns_cb->rdtype,
DNS_CLIENTRESOPT_NODNSSEC,
dhcp_gbl_ctx.task,
find_zone_addrs,
(void *)ns_cb,
&ns_cb->transaction);
/* do we need to clean this? */
dns_rdata_freestruct(&ns);
if (result == ISC_R_SUCCESS)
/* we have started the next step, cleanup
* the structures associated with this call
* but leave the cb for the next round
*/
goto cleanup;
log_error("find_zone_ns: unable to continue "
"resolve: %s %s",
ns_cb->zname,
isc_result_totext(result));
/* The call to start a resolve transaction failed,
* should we try to continue with any other names?
* For now let's not, but let's use whatever we
* may already have.
*/
goto done;
}
}
done:
/* we've either gotten our max number of addresses or
* run out of nameservers to try. Convert the cb into
* a zone and insert it into the zone hash. Then
* we need to clean up the saved state.
*/
if ((ns_cb->num_addrs != 0) ||
(ns_cb->num_addrs6 != 0))
cache_found_zone(ns_cb);
dns_client_freeresanswer(dhcp_gbl_ctx.dnsclient,
&ns_cb->eventp->answerlist);
isc_event_free((isc_event_t **)&ns_cb->eventp);
remove_from_ns_queue(ns_cb);
data_string_forget(&ns_cb->oname, MDL);
dfree(ns_cb, MDL);
cleanup:
/* cleanup any of the new state information */
dns_client_freeresanswer(dhcp_gbl_ctx.dnsclient,
&ddns_event->answerlist);
isc_event_free(&eventp);
return;
}
/*
* Routine to continue the process of finding a nameserver via the DNS
* This is routine is called when we are still trying to get a list
* of nameservers to process.
*/
void
find_zone_ns(isc_task_t *taskp,
isc_event_t *eventp)
{
dns_clientresevent_t *ddns_event = (dns_clientresevent_t *)eventp;
dhcp_ddns_ns_t *ns_cb = (dhcp_ddns_ns_t *)eventp->ev_arg;
dns_fixedname_t zname0;
dns_name_t *zname = NULL, *ns_name = NULL;
dns_rdataset_t *rdataset;
isc_result_t result;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_ns_t ns;
/* the transaction is done, get rid of the tag */
dns_client_destroyrestrans(&ns_cb->transaction);
if (ddns_event->result != ISC_R_SUCCESS) {
/* We didn't find any nameservers, try again */
/* Remove a label and continue */
ns_cb->zname = strchr(ns_cb->zname, '.');
if ((ns_cb->zname == NULL) ||
(ns_cb->zname[1] == 0)) {
/* No more labels, all done */
goto cleanup;
}
ns_cb->zname++;
/* Create a DNS version of the zone name and call the
* resolver code */
if (((result = dhcp_isc_name((unsigned char *)ns_cb->zname,
&zname0, &zname))
!= ISC_R_SUCCESS) ||
((result = zone_resolve(dhcp_gbl_ctx.dnsclient,
zname, dns_rdataclass_in,
dns_rdatatype_ns,
DNS_CLIENTRESOPT_NODNSSEC,
dhcp_gbl_ctx.task,
find_zone_ns,
(void *)ns_cb,
&ns_cb->transaction))
!= ISC_R_SUCCESS)) {
log_error("find_zone_ns: Unable to build "
"name or start resolve: %s %s",
ns_cb->zname,
isc_result_totext(result));
goto cleanup;
}
/* we have successfully started the next iteration
* of this step, clean up from the call and continue */
dns_client_freeresanswer(dhcp_gbl_ctx.dnsclient,
&ddns_event->answerlist);
isc_event_free(&eventp);
return;
}
/* We did get a set of nameservers, save the information and
* start trying to get addresses
*/
ns_cb->eventp = ddns_event;
for (ns_name = ISC_LIST_HEAD(ddns_event->answerlist);
ns_name != NULL;
ns_name = ISC_LIST_NEXT(ns_name, link)) {
for (rdataset = ISC_LIST_HEAD(ns_name->list);
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link)) {
if (rdataset->type != dns_rdatatype_ns)
continue;
if ((!dns_rdataset_isassociated(rdataset)) ||
(dns_rdataset_first(rdataset) !=
ISC_R_SUCCESS))
continue;
dns_rdataset_current(rdataset, &rdata);
if (dns_rdata_tostruct(&rdata, &ns, NULL) !=
ISC_R_SUCCESS)
continue;
/* Save our current state */
ns_cb->ns_name = ns_name;
ns_cb->rdataset = rdataset;
/* And call out to DNS */
result = zone_resolve(dhcp_gbl_ctx.dnsclient, &ns.name,
dns_rdataclass_in,
ns_cb->rdtype,
DNS_CLIENTRESOPT_NODNSSEC,
dhcp_gbl_ctx.task,
find_zone_addrs,
(void *)ns_cb,
&ns_cb->transaction);
/* do we need to clean this? */
dns_rdata_freestruct(&ns);
if (result == ISC_R_SUCCESS)
/* We have successfully started the next step
* we don't cleanup the eventp block as we are
* still using it.
*/
return;
log_error("find_zone_ns: unable to continue "
"resolve: %s %s",
ns_cb->zname,
isc_result_totext(result));
/* The call to start a resolve transaction failed,
* should we try to continue with any other names?
* For now let's not
*/
goto cleanup;
}
}
cleanup:
/* When we add a queue to manage the DDNS
* requests we will need to remove any that
* were waiting for this resolution */
dns_client_freeresanswer(dhcp_gbl_ctx.dnsclient,
&ddns_event->answerlist);
isc_event_free(&eventp);
remove_from_ns_queue(ns_cb);
data_string_forget(&ns_cb->oname, MDL);
dfree(ns_cb, MDL);
return;
}
/*
* Start the process of finding nameservers via the DNS because
* we don't have a zone entry already.
* We construct a control block and fill in the DDNS name. As
* the process continues we shall move the zname pointer to
* indicate which labels we are still using. The rest of
* the control block will be filled in as we continue processing.
*/
isc_result_t
find_zone_start(dhcp_ddns_cb_t *ddns_cb, int direction)
{
isc_result_t status = ISC_R_NOTFOUND;
dhcp_ddns_ns_t *ns_cb;
dns_fixedname_t zname0;
dns_name_t *zname = NULL;
/*
* We don't validate np as that was already done in find_cached_zone()
*/
/* Allocate the control block for this request */
ns_cb = dmalloc(sizeof(*ns_cb), MDL);
if (ns_cb == NULL) {
log_error("find_zone_start: unable to allocate cb");
return(ISC_R_FAILURE);
}
ns_cb->rdtype = dns_rdatatype_a;
/* Copy the data string so the NS lookup is independent of the DDNS */
if (direction == FIND_FORWARD) {
data_string_copy(&ns_cb->oname, &ddns_cb->fwd_name, MDL);
} else {
data_string_copy(&ns_cb->oname, &ddns_cb->rev_name, MDL);
}
ns_cb->zname = (char *)ns_cb->oname.data;
/*
* Check the dns_outstanding_ns queue to see if we are
* already processing something that would cover this name
*/
if (find_in_ns_queue(ns_cb) == ISC_R_SUCCESS) {
data_string_forget(&ns_cb->oname, MDL);
dfree(ns_cb, MDL);
return (ISC_R_SUCCESS);
}
/* Create a DNS version of the zone name and call the
* resolver code */
if (((status = dhcp_isc_name((unsigned char *)ns_cb->zname,
&zname0, &zname))
!= ISC_R_SUCCESS) ||
((status = zone_resolve(dhcp_gbl_ctx.dnsclient,
zname, dns_rdataclass_in,
dns_rdatatype_ns,
DNS_CLIENTRESOPT_NODNSSEC,
dhcp_gbl_ctx.task,
find_zone_ns,
(void *)ns_cb,
&ns_cb->transaction))
!= ISC_R_SUCCESS)) {
log_error("find_zone_start: Unable to build "
"name or start resolve: %s %s",
ns_cb->zname,
isc_result_totext(status));
/* We failed to start the process, clean up */
data_string_forget(&ns_cb->oname, MDL);
dfree(ns_cb, MDL);
} else {
/* We started the process, attach the control block
* to the queue */
add_to_ns_queue(ns_cb);
}
return (status);
}
#endif
isc_result_t
find_cached_zone(dhcp_ddns_cb_t *ddns_cb, int direction)
{
@ -693,10 +1277,13 @@ find_cached_zone(dhcp_ddns_cb_t *ddns_cb, int direction)
if (status != ISC_R_SUCCESS)
return (status);
/* Make sure the zone is valid. */
if (zone->timeout && zone->timeout < cur_time) {
/* Make sure the zone is valid, we've already gotten
* rid of expired dynamic zones. Check to see if
* we repudiated this zone. If so give up.
*/
if ((zone->flags & DNS_ZONE_INACTIVE) != 0) {
dns_zone_dereference(&zone, MDL);
return (ISC_R_CANCELED);
return (ISC_R_FAILURE);
}
/* Make sure the zone name will fit. */
@ -809,22 +1396,98 @@ void forget_zone (struct dns_zone **zone)
void repudiate_zone (struct dns_zone **zone)
{
/* XXX Currently we're not differentiating between a cached
XXX zone and a zone that's been repudiated, which means
XXX that if we reap cached zones, we blow away repudiated
XXX zones. This isn't a big problem since we're not yet
XXX caching zones... :'} */
/* verify that we have a pointer at least */
if ((zone == NULL) || (*zone == NULL)) {
log_info("Null argument to repudiate zone");
return;
}
(*zone) -> timeout = cur_time - 1;
(*zone)->flags |= DNS_ZONE_INACTIVE;
dns_zone_dereference(zone, MDL);
}
#if defined (DNS_ZONE_LOOKUP)
void cache_found_zone(dhcp_ddns_ns_t *ns_cb)
{
struct dns_zone *zone = NULL;
int len, remove_zone = 0;
/* See if there's already such a zone. */
if (dns_zone_lookup(&zone, ns_cb->zname) == ISC_R_SUCCESS) {
/* If it's not a dynamic zone, leave it alone. */
if (zone->timeout == 0)
return;
/* Remove any old addresses in case they've changed */
if (zone->primary)
option_cache_dereference(&zone->primary, MDL);
if (zone->primary6)
option_cache_dereference(&zone->primary6, MDL);
/* Set the flag to remove the zone from the hash if
we have problems */
remove_zone = 1;
} else if (dns_zone_allocate(&zone, MDL) == 0) {
return;
} else {
/* We've just allocated the zone, now we need
* to allocate space for the name and addresses
*/
/* allocate space for the name */
len = strlen(ns_cb->zname);
zone->name = dmalloc(len + 2, MDL);
if (zone->name == NULL) {
goto cleanup;
}
/* Copy the name and add a trailing '.' if necessary */
strcpy(zone->name, ns_cb->zname);
if (zone->name[len-1] != '.') {
zone->name[len] = '.';
zone->name[len+1] = 0;
}
}
zone->timeout = cur_time + ns_cb->ttl;
if (ns_cb->num_addrs != 0) {
len = ns_cb->num_addrs * sizeof(struct in_addr);
if ((!option_cache_allocate(&zone->primary, MDL)) ||
(!buffer_allocate(&zone->primary->data.buffer,
len, MDL))) {
if (remove_zone == 1)
remove_dns_zone(zone);
goto cleanup;
}
memcpy(zone->primary->data.buffer->data, ns_cb->addrs, len);
zone->primary->data.data =
&zone->primary->data.buffer->data[0];
zone->primary->data.len = len;
}
if (ns_cb->num_addrs6 != 0) {
len = ns_cb->num_addrs6 * sizeof(struct in6_addr);
if ((!option_cache_allocate(&zone->primary6, MDL)) ||
(!buffer_allocate(&zone->primary6->data.buffer,
len, MDL))) {
if (remove_zone == 1)
remove_dns_zone(zone);
goto cleanup;
}
memcpy(zone->primary6->data.buffer->data, ns_cb->addrs6, len);
zone->primary6->data.data =
&zone->primary6->data.buffer->data[0];
zone->primary6->data.len = len;
}
enter_dns_zone(zone);
cleanup:
dns_zone_dereference(&zone, MDL);
return;
}
#endif
/*!
* \brief Create an id for a client
*
@ -1513,6 +2176,28 @@ ddns_modify_fwd(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
if (ddns_cb->zone == NULL) {
result = find_cached_zone(ddns_cb, FIND_FORWARD);
#if defined (DNS_ZONE_LOOKUP)
if (result == ISC_R_NOTFOUND) {
/*
* We didn't find a cached zone, see if we can
* can find a nameserver and create a zone.
*/
if (find_zone_start(ddns_cb, FIND_FORWARD)
== ISC_R_SUCCESS) {
/*
* We have started the process to find a zone
* queue the ddns_cb for processing after we
* create the zone
*/
/* sar - not yet implemented, currently we just
* arrange for things to get cleaned up
*/
goto cleanup;
}
}
#endif
if (result != ISC_R_SUCCESS)
goto cleanup;
}
/*
@ -1685,6 +2370,30 @@ ddns_modify_ptr(dhcp_ddns_cb_t *ddns_cb, const char *file, int line)
* have a pre-existing zone.
*/
result = find_cached_zone(ddns_cb, FIND_REVERSE);
#if defined (DNS_ZONE_LOOKUP)
if (result == ISC_R_NOTFOUND) {
/*
* We didn't find a cached zone, see if we can
* can find a nameserver and create a zone.
*/
if (find_zone_start(ddns_cb, FIND_REVERSE) == ISC_R_SUCCESS) {
/*
* We have started the process to find a zone
* queue the ddns_cb for processing after we
* create the zone
*/
/* sar - not yet implemented, currently we just
* arrange for things to get cleaned up
*/
goto cleanup;
}
}
#endif
if (result != ISC_R_SUCCESS)
goto cleanup;
if ((result == ISC_R_SUCCESS) &&
!(ISC_LIST_EMPTY(ddns_cb->zone_server_list))) {
/* Set up the zone name for use by DNS */

View File

@ -13,8 +13,8 @@ ATF_TESTS += alloc_unittest dns_unittest
alloc_unittest_SOURCES = test_alloc.c $(top_srcdir)/tests/t_api_dhcp.c
alloc_unittest_LDADD = $(ATF_LDFLAGS)
alloc_unittest_LDADD += ../libdhcp.a \
../../omapip/libomapi.a ../../bind/lib/libdns.a \
../../bind/lib/libisc.a
../../omapip/libomapi.a ../../bind/lib/libirs.a \
../../bind/lib/libdns.a ../bind/lib/libisccfg.a ../../bind/lib/libisc.a
dns_unittest_SOURCES = dns_unittest.c $(top_srcdir)/tests/t_api_dhcp.c
dns_unittest_LDADD = $(ATF_LDFLAGS)

View File

@ -101,7 +101,8 @@ alloc_unittest_OBJECTS = $(am_alloc_unittest_OBJECTS)
am__DEPENDENCIES_1 =
@HAVE_ATF_TRUE@alloc_unittest_DEPENDENCIES = $(am__DEPENDENCIES_1) \
@HAVE_ATF_TRUE@ ../libdhcp.a ../../omapip/libomapi.a \
@HAVE_ATF_TRUE@ ../../bind/lib/libdns.a ../../bind/lib/libisc.a
@HAVE_ATF_TRUE@ ../../bind/lib/libirs.a ../../bind/lib/libdns.a \
@HAVE_ATF_TRUE@ ../bind/lib/libisccfg.a ../../bind/lib/libisc.a
am__dns_unittest_SOURCES_DIST = dns_unittest.c \
$(top_srcdir)/tests/t_api_dhcp.c
@HAVE_ATF_TRUE@am_dns_unittest_OBJECTS = dns_unittest.$(OBJEXT) \
@ -320,7 +321,8 @@ EXTRA_DIST = Atffile
ATF_TESTS = $(am__append_1)
@HAVE_ATF_TRUE@alloc_unittest_SOURCES = test_alloc.c $(top_srcdir)/tests/t_api_dhcp.c
@HAVE_ATF_TRUE@alloc_unittest_LDADD = $(ATF_LDFLAGS) ../libdhcp.a \
@HAVE_ATF_TRUE@ ../../omapip/libomapi.a ../../bind/lib/libdns.a \
@HAVE_ATF_TRUE@ ../../omapip/libomapi.a ../../bind/lib/libirs.a \
@HAVE_ATF_TRUE@ ../../bind/lib/libdns.a ../bind/lib/libisccfg.a \
@HAVE_ATF_TRUE@ ../../bind/lib/libisc.a
@HAVE_ATF_TRUE@dns_unittest_SOURCES = dns_unittest.c $(top_srcdir)/tests/t_api_dhcp.c
@HAVE_ATF_TRUE@dns_unittest_LDADD = $(ATF_LDFLAGS) ../libdhcp.a \

View File

@ -6,10 +6,12 @@ EXTRA_DIST = $(man_MANS)
omshell_SOURCES = omshell.c
omshell_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \
../bind/lib/libdns.a ../bind/lib/libisc.a
../bind/lib/libirs.a ../bind/lib/libdns.a \
../bind/lib/libisccfg.a ../bind/lib/libisc.a
libdhcpctl_a_SOURCES = dhcpctl.c callback.c remote.c
cltest_SOURCES = cltest.c
cltest_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \
../bind/lib/libdns.a ../bind/lib/libisc.a
../bind/lib/libirs.a ../bind/lib/libdns.a \
../bind/lib/libisccfg.a ../bind/lib/libisc.a

View File

@ -137,11 +137,13 @@ PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
am_cltest_OBJECTS = cltest.$(OBJEXT)
cltest_OBJECTS = $(am_cltest_OBJECTS)
cltest_DEPENDENCIES = libdhcpctl.a ../common/libdhcp.a \
../omapip/libomapi.a ../bind/lib/libdns.a ../bind/lib/libisc.a
../omapip/libomapi.a ../bind/lib/libirs.a ../bind/lib/libdns.a \
../bind/lib/libisccfg.a ../bind/lib/libisc.a
am_omshell_OBJECTS = omshell.$(OBJEXT)
omshell_OBJECTS = $(am_omshell_OBJECTS)
omshell_DEPENDENCIES = libdhcpctl.a ../common/libdhcp.a \
../omapip/libomapi.a ../bind/lib/libdns.a ../bind/lib/libisc.a
../omapip/libomapi.a ../bind/lib/libirs.a ../bind/lib/libdns.a \
../bind/lib/libisccfg.a ../bind/lib/libisc.a
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@ -309,12 +311,14 @@ man_MANS = omshell.1 dhcpctl.3
EXTRA_DIST = $(man_MANS)
omshell_SOURCES = omshell.c
omshell_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \
../bind/lib/libdns.a ../bind/lib/libisc.a
../bind/lib/libirs.a ../bind/lib/libdns.a \
../bind/lib/libisccfg.a ../bind/lib/libisc.a
libdhcpctl_a_SOURCES = dhcpctl.c callback.c remote.c
cltest_SOURCES = cltest.c
cltest_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \
../bind/lib/libdns.a ../bind/lib/libisc.a
../bind/lib/libirs.a ../bind/lib/libdns.a \
../bind/lib/libisccfg.a ../bind/lib/libisc.a
all: all-am

View File

@ -1371,6 +1371,8 @@ struct dns_query {
int backoff; /* Current backoff, in seconds. */
};
#define DNS_ZONE_ACTIVE 0
#define DNS_ZONE_INACTIVE 1
struct dns_zone {
int refcnt;
TIME timeout;
@ -1380,6 +1382,7 @@ struct dns_zone {
struct option_cache *primary6;
struct option_cache *secondary6;
struct auth_key *key;
u_int16_t flags;
};
struct icmp_state {

View File

@ -61,6 +61,8 @@
#include <isc/heap.h>
#include <isc/random.h>
#include <irs/resconf.h>
#include <dns/client.h>
#include <dns/fixedname.h>
#include <dns/keyvalues.h>

View File

@ -117,6 +117,10 @@
#define NSUPDATE
/* Define this if you want to enable the DHCP server attempting to
find a nameserver to use for DDNS updates. */
#define DNS_ZONE_LOOKUP
/* Define this if you want the dhcpd.pid file to go somewhere other than
the default (which varies from system to system, but is usually either
/etc or /var/run. */

View File

@ -10,5 +10,6 @@ man_MANS = omapi.3
EXTRA_DIST = $(man_MANS)
svtest_SOURCES = test.c
svtest_LDADD = libomapi.a ../bind/lib/libdns.a ../bind/lib/libisc.a
svtest_LDADD = libomapi.a ../bind/lib/libirs.a ../bind/lib/libdns.a \
../bind/lib/libisccfg.a ../bind/lib/libisc.a

View File

@ -140,7 +140,8 @@ libomapi_a_OBJECTS = $(am_libomapi_a_OBJECTS)
PROGRAMS = $(noinst_PROGRAMS)
am_svtest_OBJECTS = test.$(OBJEXT)
svtest_OBJECTS = $(am_svtest_OBJECTS)
svtest_DEPENDENCIES = libomapi.a ../bind/lib/libdns.a \
svtest_DEPENDENCIES = libomapi.a ../bind/lib/libirs.a \
../bind/lib/libdns.a ../bind/lib/libisccfg.a \
../bind/lib/libisc.a
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@ -311,7 +312,9 @@ libomapi_a_SOURCES = protocol.c buffer.c alloc.c result.c connection.c \
man_MANS = omapi.3
EXTRA_DIST = $(man_MANS)
svtest_SOURCES = test.c
svtest_LDADD = libomapi.a ../bind/lib/libdns.a ../bind/lib/libisc.a
svtest_LDADD = libomapi.a ../bind/lib/libirs.a ../bind/lib/libdns.a \
../bind/lib/libisccfg.a ../bind/lib/libisc.a
all: all-am
.SUFFIXES:

View File

@ -33,6 +33,57 @@
dhcp_context_t dhcp_gbl_ctx;
int shutdown_signal = 0;
#if defined (NSUPDATE)
/* This routine will open up the /etc/resolv.conf file and
* send any nameservers it finds to the DNS client code.
* It may be moved to be part of the dns client code instead
* of being in the DHCP code
*/
isc_result_t
dhcp_dns_client_setservers(void)
{
isc_result_t result;
irs_resconf_t *resconf = NULL;
isc_sockaddrlist_t *nameservers;
isc_sockaddr_t *sa;
result = irs_resconf_load(dhcp_gbl_ctx.mctx, _PATH_RESOLV_CONF,
&resconf);
if (result != ISC_R_SUCCESS) {
log_error("irs_resconf_load failed: %d.", result);
return (result);
}
nameservers = irs_resconf_getnameservers(resconf);
/* Initialize port numbers */
for (sa = ISC_LIST_HEAD(*nameservers);
sa != NULL;
sa = ISC_LIST_NEXT(sa, link)) {
switch (sa->type.sa.sa_family) {
case AF_INET:
sa->type.sin.sin_port = htons(NS_DEFAULTPORT);
break;
case AF_INET6:
sa->type.sin6.sin6_port = htons(NS_DEFAULTPORT);
break;
default:
break;
}
}
result = dns_client_setservers(dhcp_gbl_ctx.dnsclient,
dns_rdataclass_in,
NULL, nameservers);
if (result != ISC_R_SUCCESS) {
log_error("dns_client_setservers failed: %d.",
result);
}
return (result);
}
#endif
void
isclib_cleanup(void)
{
@ -142,6 +193,11 @@ dhcp_context_create(void) {
&dhcp_gbl_ctx.dnsclient);
if (result != ISC_R_SUCCESS)
goto cleanup;
result = dhcp_dns_client_setservers();
if (result != ISC_R_SUCCESS)
goto cleanup;
#else
/* The dst library is inited as part of dns_lib_init, we don't
* need it if NSUPDATE is enabled */

View File

@ -3,7 +3,8 @@ AM_CPPFLAGS = -DLOCALSTATEDIR='"@localstatedir@"'
sbin_PROGRAMS = dhcrelay
dhcrelay_SOURCES = dhcrelay.c
dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
../bind/lib/libdns.a ../bind/lib/libisc.a
../bind/lib/libirs.a ../bind/lib/libdns.a \
../bind/lib/libisccfg.a ../bind/lib/libisc.a
man_MANS = dhcrelay.8
EXTRA_DIST = $(man_MANS)

View File

@ -95,7 +95,8 @@ PROGRAMS = $(sbin_PROGRAMS)
am_dhcrelay_OBJECTS = dhcrelay.$(OBJEXT)
dhcrelay_OBJECTS = $(am_dhcrelay_OBJECTS)
dhcrelay_DEPENDENCIES = ../common/libdhcp.a ../omapip/libomapi.a \
../bind/lib/libdns.a ../bind/lib/libisc.a
../bind/lib/libirs.a ../bind/lib/libdns.a \
../bind/lib/libisccfg.a ../bind/lib/libisc.a
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@ -286,7 +287,8 @@ top_srcdir = @top_srcdir@
AM_CPPFLAGS = -DLOCALSTATEDIR='"@localstatedir@"'
dhcrelay_SOURCES = dhcrelay.c
dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
../bind/lib/libdns.a ../bind/lib/libisc.a
../bind/lib/libirs.a ../bind/lib/libdns.a \
../bind/lib/libisccfg.a ../bind/lib/libisc.a
man_MANS = dhcrelay.8
EXTRA_DIST = $(man_MANS)

View File

@ -14,8 +14,8 @@ dhcpd_SOURCES = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \
dhcpd_CFLAGS = $(LDAP_CFLAGS)
dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
../dhcpctl/libdhcpctl.a ../bind/lib/libdns.a \
../bind/lib/libisc.a
../dhcpctl/libdhcpctl.a ../bind/lib/libirs.a \
../bind/lib/libdns.a ../bind/lib/libisccfg.a ../bind/lib/libisc.a
man_MANS = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5
EXTRA_DIST = $(man_MANS)

View File

@ -105,7 +105,8 @@ am_dhcpd_OBJECTS = dhcpd-dhcpd.$(OBJEXT) dhcpd-dhcp.$(OBJEXT) \
dhcpd-ldap_casa.$(OBJEXT)
dhcpd_OBJECTS = $(am_dhcpd_OBJECTS)
dhcpd_DEPENDENCIES = ../common/libdhcp.a ../omapip/libomapi.a \
../dhcpctl/libdhcpctl.a ../bind/lib/libdns.a \
../dhcpctl/libdhcpctl.a ../bind/lib/libirs.a \
../bind/lib/libdns.a ../bind/lib/libisccfg.a \
../bind/lib/libisc.a
dhcpd_LINK = $(CCLD) $(dhcpd_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
@ -358,8 +359,8 @@ dhcpd_SOURCES = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \
dhcpd_CFLAGS = $(LDAP_CFLAGS)
dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
../dhcpctl/libdhcpctl.a ../bind/lib/libdns.a \
../bind/lib/libisc.a
../dhcpctl/libdhcpctl.a ../bind/lib/libirs.a \
../bind/lib/libdns.a ../bind/lib/libisccfg.a ../bind/lib/libisc.a
man_MANS = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5
EXTRA_DIST = $(man_MANS)

View File

@ -18,7 +18,8 @@ DHCPSRC = ../dhcp.c ../bootp.c ../confpars.c ../db.c ../class.c \
../ldap.c ../ldap_casa.c ../dhcpd.c
DHCPLIBS = $(top_builddir)/common/libdhcp.a $(top_builddir)/omapip/libomapi.a \
$(top_builddir)/dhcpctl/libdhcpctl.a $(top_builddir)/bind/lib/libdns.a \
$(top_builddir)/dhcpctl/libdhcpctl.a $(top_builddir)/bind/lib/libirs.a \
$(top_builddir)/bind/lib/libdns.a $(top_builddir/bind/lib/libisccfg.a \
$(top_builddir)/bind/lib/libisc.a
ATF_TESTS =

View File

@ -565,7 +565,8 @@ DHCPSRC = ../dhcp.c ../bootp.c ../confpars.c ../db.c ../class.c \
../ldap.c ../ldap_casa.c ../dhcpd.c
DHCPLIBS = $(top_builddir)/common/libdhcp.a $(top_builddir)/omapip/libomapi.a \
$(top_builddir)/dhcpctl/libdhcpctl.a $(top_builddir)/bind/lib/libdns.a \
$(top_builddir)/dhcpctl/libdhcpctl.a $(top_builddir)/bind/lib/libirs.a \
$(top_builddir)/bind/lib/libdns.a $(top_builddir/bind/lib/libisccfg.a \
$(top_builddir)/bind/lib/libisc.a
ATF_TESTS = $(am__append_1)

View File

@ -58,6 +58,7 @@ case $# in
### For ease of use, this records the sticky tag of versions
### released with each point release.
###
4.2.6b1) BINDTAG=v9_8_6 ;;
4.2.5b1|4.2.5rc1) BINDTAG=v9_8_4_P1 ;;
4.2.4rc2|4.2.4) BINDTAG=v9_8_3 ;;
4.2.4b1|4.2.4rc1) BINDTAG=v9_8_2 ;;