mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-23 02:17:31 +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:
parent
567e85616c
commit
a396d25fba
10
RELNOTES
10
RELNOTES
@ -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
|
||||||
|
143
server/ddns.c
143
server/ddns.c
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user