2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-23 10:28:08 +00:00

- '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]
This commit is contained in:
David Hankins 2006-07-19 20:13:57 +00:00
parent 567e85616c
commit a396d25fba
3 changed files with 131 additions and 32 deletions

View File

@ -133,6 +133,16 @@ and for prodding me into improving it.
increased from 16 to 128. This is intended to match Microsoft Windows increased from 16 to 128. This is intended to match Microsoft Windows
DHCP Client behaviour, to increase compatibility. 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 Changes since 3.0.4
- A warning that host statements declared within subnet or shared-network - A warning that host statements declared within subnet or shared-network

View File

@ -34,7 +34,7 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@ -232,7 +232,7 @@ int ddns_updates (struct packet *packet,
isc_result_t rcode1 = ISC_R_SUCCESS, rcode2 = ISC_R_SUCCESS; isc_result_t rcode1 = ISC_R_SUCCESS, rcode2 = ISC_R_SUCCESS;
int server_updates_a = 1; int server_updates_a = 1;
struct buffer *bp = (struct buffer *)0; struct buffer *bp = (struct buffer *)0;
int ignorep = 0; int ignorep = 0, client_ignorep = 0;
if (ddns_update_style != 2) if (ddns_update_style != 2)
return 0; 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 /* 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. */ record, see if the client wants to update its own A record. */
if (!(oc = lookup_option (&server_universe, state -> options, if (!(oc = lookup_option(&server_universe, state->options,
SV_CLIENT_UPDATES)) || SV_CLIENT_UPDATES)) ||
evaluate_boolean_option_cache (&ignorep, packet, lease, evaluate_boolean_option_cache(&client_ignorep, packet, lease, NULL,
(struct client_state *)0, packet->options, state->options,
packet -> options, &lease->scope, oc, MDL)) {
state -> options,
&lease -> scope, oc, MDL)) {
/* If there's no fqdn.no-client-update or if it's /* If there's no fqdn.no-client-update or if it's
nonzero, don't try to use the client-supplied nonzero, don't try to use the client-supplied
XXX */ XXX */
@ -589,14 +587,101 @@ int ddns_updates (struct packet *packet,
&ddns_rev_name); &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: noerror:
if ((oc = lookup_option (&fqdn_universe, /* If we're ignoring client updates, then we tell a sort of 'white
packet -> options, FQDN_ENCODED)) * lie'. We've already updated the name the server wants (per the
&& buffer_allocate (&bp, ddns_fwd_name.len + 5, MDL)) { * 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; bp -> data [0] = server_updates_a;
if (!save_option_buffer (&fqdn_universe, state -> options, if (!save_option_buffer (&fqdn_universe, state -> options,
bp, &bp -> data [0], 1, bp, &bp -> data [0], 1,
@ -607,15 +692,12 @@ int ddns_updates (struct packet *packet,
bp, &bp -> data [1], 1, bp, &bp -> data [1], 1,
FQDN_NO_CLIENT_UPDATE, 0)) FQDN_NO_CLIENT_UPDATE, 0))
goto badfqdn; goto badfqdn;
/* Do the same encoding the client did. */ /* Do the same encoding the client did. */
oc = lookup_option (&fqdn_universe, packet -> options, if (evaluate_boolean_option_cache(&ignorep, packet, lease,
FQDN_ENCODED); NULL, packet->options,
if (oc && state->options,
evaluate_boolean_option_cache (&ignorep, packet, lease, &lease->scope, oc, MDL))
(struct client_state *)0,
packet -> options,
state -> options,
&lease -> scope, oc, MDL))
bp -> data [2] = 1; bp -> data [2] = 1;
else else
bp -> data [2] = 0; bp -> data [2] = 0;
@ -649,14 +731,15 @@ int ddns_updates (struct packet *packet,
/* /*
* Final cleanup. * Final cleanup.
*/ */
data_string_forget (&ddns_hostname, MDL); data_string_forget(&d1, MDL);
data_string_forget (&ddns_domainname, MDL); data_string_forget(&ddns_hostname, MDL);
data_string_forget (&old_ddns_fwd_name, MDL); data_string_forget(&ddns_domainname, MDL);
data_string_forget (&ddns_fwd_name, MDL); data_string_forget(&old_ddns_fwd_name, MDL);
data_string_forget (&ddns_rev_name, MDL); data_string_forget(&ddns_fwd_name, MDL);
data_string_forget (&ddns_dhcid, MDL); data_string_forget(&ddns_rev_name, MDL);
data_string_forget(&ddns_dhcid, MDL);
if (bp) if (bp)
buffer_dereference (&bp, MDL); buffer_dereference(&bp, MDL);
return result; return result;
} }

View File

@ -28,7 +28,7 @@
.\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see .\" see ``http://www.vix.com''. To learn more about Nominum, Inc., see
.\" ``http://www.nominum.com''. .\" ``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 .TH dhcpd.conf 5
.SH NAME .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 domain name - in the example above, "jschmoe" instead of
"jschmoe.radish.org". "jschmoe.radish.org".
.PP .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 Also, if the
.I use-host-decl-names .I use-host-decl-names
configuration option is enabled, then the host declaration's configuration option is enabled, then the host declaration's