]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
- 'ignore client-updates;' now has behaviour that is different from
authorDavid Hankins <dhankins@isc.org>
Wed, 19 Jul 2006 20:13:57 +0000 (20:13 +0000)
committerDavid Hankins <dhankins@isc.org>
Wed, 19 Jul 2006 20:13:57 +0000 (20:13 +0000)
  '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]

RELNOTES
server/ddns.c
server/dhcpd.conf.5

index ad73dbdb1ea19916d8ed2d6da888577857f25a27..a2e377c58d2c917227830f461aed61176f625935 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -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
index 483d9a3f41f3869d9442e4ad1e65f5b8ac750cd3..787fcfbc33d7ee91203c570271663df36740acd2 100644 (file)
@@ -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;
 }
index 820f96bf7e52665c5dc5be4dde1066273c64af72..7ef0cad6c5a362bc8d89fe96f7469b5c2449a817 100644 (file)
@@ -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