diff options
author | David Hankins <dhankins@isc.org> | 2006-07-19 20:13:57 +0000 |
---|---|---|
committer | David Hankins <dhankins@isc.org> | 2006-07-19 20:13:57 +0000 |
commit | a396d25fba26c2534762a003b4f77199e9efbfa6 (patch) | |
tree | 53c3338a2a9269795a9a13c2c17e2963b7d8fb1f | |
parent | 567e85616ce43c5e9c223a4c767f912e200dd5b6 (diff) | |
download | isc-dhcp-a396d25fba26c2534762a003b4f77199e9efbfa6.tar.gz |
- 'ignore client-updates;' now has behaviour that is different from
'deny client-updates;'. The client's request is not truly ignored,
rather it is encouraged. Should this value be configured, the server
updates DNS as though client-updates were set to 'deny'. That is, it
enters into DNS whatever it is configured to do already, provided it is
configured to. Then it sends a response to the client that lets the
client believe it is performing client updates (which it will), probably
for a different name. In essence, this lets the client do as it will,
ignoring this aspect of their request. [ISC-Bugs #16185]
-rw-r--r-- | RELNOTES | 10 | ||||
-rw-r--r-- | server/ddns.c | 145 | ||||
-rw-r--r-- | server/dhcpd.conf.5 | 8 |
3 files changed, 131 insertions, 32 deletions
@@ -133,6 +133,16 @@ and for prodding me into improving it. increased from 16 to 128. This is intended to match Microsoft Windows DHCP Client behaviour, to increase compatibility. +- 'ignore client-updates;' now has behaviour that is different from + 'deny client-updates;'. The client's request is not truly ignored, + rather it is encouraged. Should this value be configured, the server + updates DNS as though client-updates were set to 'deny'. That is, it + enters into DNS whatever it is configured to do already, provided it is + configured to. Then it sends a response to the client that lets the + client believe it is performing client updates (which it will), probably + for a different name. In essence, this lets the client do as it will, + ignoring this aspect of their request. + Changes since 3.0.4 - A warning that host statements declared within subnet or shared-network diff --git a/server/ddns.c b/server/ddns.c index 483d9a3f..787fcfbc 100644 --- a/server/ddns.c +++ b/server/ddns.c @@ -34,7 +34,7 @@ #ifndef lint static char copyright[] = -"$Id: ddns.c,v 1.20 2006/07/19 17:14:55 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n"; +"$Id: ddns.c,v 1.21 2006/07/19 20:13:57 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -232,7 +232,7 @@ int ddns_updates (struct packet *packet, isc_result_t rcode1 = ISC_R_SUCCESS, rcode2 = ISC_R_SUCCESS; int server_updates_a = 1; struct buffer *bp = (struct buffer *)0; - int ignorep = 0; + int ignorep = 0, client_ignorep = 0; if (ddns_update_style != 2) return 0; @@ -250,13 +250,11 @@ int ddns_updates (struct packet *packet, /* If we are allowed to accept the client's update of its own A record, see if the client wants to update its own A record. */ - if (!(oc = lookup_option (&server_universe, state -> options, - SV_CLIENT_UPDATES)) || - evaluate_boolean_option_cache (&ignorep, packet, lease, - (struct client_state *)0, - packet -> options, - state -> options, - &lease -> scope, oc, MDL)) { + if (!(oc = lookup_option(&server_universe, state->options, + SV_CLIENT_UPDATES)) || + evaluate_boolean_option_cache(&client_ignorep, packet, lease, NULL, + packet->options, state->options, + &lease->scope, oc, MDL)) { /* If there's no fqdn.no-client-update or if it's nonzero, don't try to use the client-supplied XXX */ @@ -589,14 +587,101 @@ int ddns_updates (struct packet *packet, &ddns_rev_name); } - /* Set up the outgoing FQDN option if there was an incoming - FQDN option. If there's a valid FQDN option, there should - be an FQDN_ENCODED suboption, so we test the latter to - detect the presence of the former. */ noerror: - if ((oc = lookup_option (&fqdn_universe, - packet -> options, FQDN_ENCODED)) - && buffer_allocate (&bp, ddns_fwd_name.len + 5, MDL)) { + /* If we're ignoring client updates, then we tell a sort of 'white + * lie'. We've already updated the name the server wants (per the + * config written by the server admin). Now let the client do as + * it pleases with the name they supplied (if any). + * + * We only form an FQDN option this way if the client supplied an + * FQDN option that had FQDN_SERVER_UPDATE set false. + */ + if (client_ignorep && + (oc = lookup_option(&fqdn_universe, packet->options, + FQDN_SERVER_UPDATE)) && + !evaluate_boolean_option_cache(&ignorep, packet, lease, NULL, + packet->options, state->options, + &lease->scope, oc, MDL)) { + oc = lookup_option(&fqdn_universe, packet->options, FQDN_FQDN); + if (oc && evaluate_option_cache(&d1, packet, lease, NULL, + packet->options, state->options, + &global_scope, oc, MDL)) { + if (d1.len == 0 || + !buffer_allocate(&bp, d1.len + 5, MDL)) + goto badfqdn; + + /* Server pretends it is not updating. */ + bp->data[0] = 0; + if (!save_option_buffer(&fqdn_universe, state->options, + bp, &bp->data[0], 1, + &fqdn_options[FQDN_SERVER_UPDATE], + 0)) + goto badfqdn; + + /* Client is encouraged to update. */ + bp->data[1] = 0; + if (!save_option_buffer(&fqdn_universe, state->options, + bp, &bp->data[1], 1, + &fqdn_options[FQDN_NO_CLIENT_UPDATE], + 0)) + goto badfqdn; + + /* Use the encoding of client's FQDN option. */ + oc = lookup_option(&fqdn_universe, packet->options, + FQDN_ENCODED); + if (oc && evaluate_boolean_option_cache(&ignorep, + packet, lease, NULL, + packet->options, + state->options, + &lease->scope, oc, + MDL)) + bp->data[2] = 1; /* FQDN is encoded. */ + else + bp->data[2] = 0; /* FQDN is not encoded. */ + + if (!save_option_buffer(&fqdn_universe, state->options, + bp, &bp->data[2], 1, + &fqdn_options[FQDN_ENCODED], 0)) + goto badfqdn; + + /* Current FQDN drafts indicate 255 is mandatory. */ + bp->data[3] = 255; + if (!save_option_buffer(&fqdn_universe, state->options, + bp, &bp->data[3], 1, + &fqdn_options[FQDN_RCODE1], 0)) + goto badfqdn; + + bp->data[4] = 255; + if (!save_option_buffer(&fqdn_universe, state->options, + bp, &bp->data[4], 1, + &fqdn_options[FQDN_RCODE2], 0)) + goto badfqdn; + + /* Copy in the FQDN supplied by the client. Note well + * that the format of this option in the cache is going + * to be in text format. If the fqdn supplied by the + * client is encoded, it is decoded into the option + * cache when parsed out of the packet. It will be + * re-encoded when the option is assembled to be + * transmitted if the client elects that encoding. + */ + memcpy(&bp->data[5], d1.data, d1.len); + if (!save_option_buffer(&fqdn_universe, state->options, + bp, &bp->data[5], 1, + &fqdn_options[FQDN_FQDN], 0)) + goto badfqdn; + + data_string_forget(&d1, MDL); + } + /* Set up the outgoing FQDN option if there was an incoming + * FQDN option. If there's a valid FQDN option, there MUST + * be an FQDN_SERVER_UPDATES suboption, it's part of the fixed + * length head of the option contents, so we test the latter + * to detect the presence of the former. + */ + } else if ((oc = lookup_option(&fqdn_universe, packet->options, + FQDN_ENCODED)) && + buffer_allocate(&bp, ddns_fwd_name.len + 5, MDL)) { bp -> data [0] = server_updates_a; if (!save_option_buffer (&fqdn_universe, state -> options, bp, &bp -> data [0], 1, @@ -607,15 +692,12 @@ int ddns_updates (struct packet *packet, bp, &bp -> data [1], 1, FQDN_NO_CLIENT_UPDATE, 0)) goto badfqdn; + /* Do the same encoding the client did. */ - oc = lookup_option (&fqdn_universe, packet -> options, - FQDN_ENCODED); - if (oc && - evaluate_boolean_option_cache (&ignorep, packet, lease, - (struct client_state *)0, - packet -> options, - state -> options, - &lease -> scope, oc, MDL)) + if (evaluate_boolean_option_cache(&ignorep, packet, lease, + NULL, packet->options, + state->options, + &lease->scope, oc, MDL)) bp -> data [2] = 1; else bp -> data [2] = 0; @@ -649,14 +731,15 @@ int ddns_updates (struct packet *packet, /* * Final cleanup. */ - data_string_forget (&ddns_hostname, MDL); - data_string_forget (&ddns_domainname, MDL); - data_string_forget (&old_ddns_fwd_name, MDL); - data_string_forget (&ddns_fwd_name, MDL); - data_string_forget (&ddns_rev_name, MDL); - data_string_forget (&ddns_dhcid, MDL); + data_string_forget(&d1, MDL); + data_string_forget(&ddns_hostname, MDL); + data_string_forget(&ddns_domainname, MDL); + data_string_forget(&old_ddns_fwd_name, MDL); + data_string_forget(&ddns_fwd_name, MDL); + data_string_forget(&ddns_rev_name, MDL); + data_string_forget(&ddns_dhcid, MDL); if (bp) - buffer_dereference (&bp, MDL); + buffer_dereference(&bp, MDL); return result; } diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5 index 820f96bf..7ef0cad6 100644 --- a/server/dhcpd.conf.5 +++ b/server/dhcpd.conf.5 @@ -28,7 +28,7 @@ .\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see .\" ``http://www.nominum.com''. .\" -.\" $Id: dhcpd.conf.5,v 1.76 2006/07/19 17:14:55 dhankins Exp $ +.\" $Id: dhcpd.conf.5,v 1.77 2006/07/19 20:13:57 dhankins Exp $ .\" .TH dhcpd.conf 5 .SH NAME @@ -1138,6 +1138,12 @@ name in the fqdn option, the server uses only the leftmost part of the domain name - in the example above, "jschmoe" instead of "jschmoe.radish.org". .PP +Further, if the \fIignore client-updates;\fR directive is used, then +the server will in addition send a response in the DHCP packet, using +the FQDN Option, that implies to the client that it should perform its +own updates if it chooses to do so. With \fIdeny client-updates;\fR, a +response is sent which indicates the client may not perform updates. +.PP Also, if the .I use-host-decl-names configuration option is enabled, then the host declaration's |