]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[v4_1_esv] Fixed infinite-is-reserved and lease:flags setting via omapi
authorThomas Markwalder <tmark@isc.org>
Fri, 5 Feb 2016 14:53:12 +0000 (09:53 -0500)
committerThomas Markwalder <tmark@isc.org>
Fri, 5 Feb 2016 14:53:12 +0000 (09:53 -0500)
    Merges in rt31179.

RELNOTES
server/dhcp.c
server/mdb.c
server/omapi.c

index 777e46cb646e6a5723e6cd2cb7a7894dfe68bd51..8d879f0d1b0217ba4bc5d81612f69a4e3bd3f788 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -164,6 +164,14 @@ by Eric Young (eay@cryptsoft.com).
   a lease that includes long strings in an execute statement.
   [ISC-Bugs #40994]
 
+- The server will now correctly treat a lease as reserved when the client
+  requests an infinite lease time (i.e. OxFFFFFFFF) and "infinite-is-reserved"
+  is enabled.  Prior to this the server would halt.  In addition, corrections
+  were made to the server to allow a lease's flags field to be set via omapi.
+  Prior to this, the server, depending on the host architecture,  would
+  incorrectly parse the new flags value from the omapi message.
+  [ISC-Bugs #31179]
+
                        Changes since 4.1-ESV-R12b1
 
 - None
index 63ff6213c3b5c6792192e8bc0cbc1c6f95b21acc..9f10f6c42f6b82157572ad79b6193ec12e3bc332 100644 (file)
@@ -3,7 +3,7 @@
    DHCP Protocol engine. */
 
 /*
- * Copyright (c) 2004-2015 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 1995-2003 by Internet Software Consortium
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -2471,7 +2471,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
        memcpy (&lt -> hardware_addr.hbuf [1], packet -> raw -> chaddr,
                sizeof packet -> raw -> chaddr);
 
-       lt -> flags = lease -> flags & ~PERSISTENT_FLAGS;
+       lt->flags |= lease->flags & ~PERSISTENT_FLAGS;
 
        /* If there are statements to execute when the lease is
           committed, execute them. */
index 899aba8df937fa37117584c5266a26ae8a77be02..3301f58c44aaeae3cd5f677ee0b9f0080afc7f36 100644 (file)
@@ -3,7 +3,7 @@
    Server-specific in-memory database support. */
 
 /*
- * Copyright (c) 2011-2015 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2011-2016 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 2004-2009 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 1996-2003 by Internet Software Consortium
  *
@@ -1070,7 +1070,6 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate, from_pool)
        if (pimmediate && !commit)
                return 0;
 #endif
-
        /* If there is no sample lease, just do the move. */
        if (!lease)
                goto just_move_it;
@@ -1157,8 +1156,6 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate, from_pool)
                host_dereference (&comp -> host, MDL);
        host_reference (&comp -> host, lease -> host, MDL);
        comp -> hardware_addr = lease -> hardware_addr;
-       comp -> flags = ((lease -> flags & ~PERSISTENT_FLAGS) |
-                        (comp -> flags & ~EPHEMERAL_FLAGS));
        if (comp -> scope)
                binding_scope_dereference (&comp -> scope, MDL);
        if (lease -> scope) {
@@ -1325,6 +1322,14 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate, from_pool)
                }
        }
 
+       /* Now that we've done the flag-affected queue removal
+        * we can update the new lease's flags, if there's an
+        * existing lease */
+       if (lease) {
+               comp->flags = ((lease->flags & ~PERSISTENT_FLAGS) |
+                               (comp->flags & ~EPHEMERAL_FLAGS));
+       }
+
        /* Make the state transition. */
        if (commit || !pimmediate)
                make_binding_state_transition (comp);
index 167ba09bcb34c0d036a5182cd3b7ccadd0985d43..b7f7a53d4778473dea87397951d119e5588d3f53 100644 (file)
@@ -41,6 +41,9 @@ static isc_result_t class_lookup (omapi_object_t **,
                                  omapi_object_t *, omapi_object_t *,
                                  omapi_object_type_t *);
 
+static isc_result_t update_lease_flags(struct lease* lease,
+                                      omapi_typed_data_t *value);
+
 omapi_object_type_t *dhcp_type_lease;
 omapi_object_type_t *dhcp_type_pool;
 omapi_object_type_t *dhcp_type_class;
@@ -269,22 +272,7 @@ isc_result_t dhcp_lease_set_value  (omapi_object_t *h,
                      piaddr(lease->ip_addr), old_lease_end, lease_end);
            return ISC_R_IOERROR;
        } else if (!omapi_ds_strcmp(name, "flags")) {
-           u_int8_t oldflags;
-
-           if (value->type != omapi_datatype_data)
-               return ISC_R_INVALIDARG;
-
-           oldflags = lease->flags;
-           lease->flags = (value->u.buffer.value[0] & EPHEMERAL_FLAGS) |
-                          (lease->flags & ~EPHEMERAL_FLAGS);
-           if(oldflags == lease->flags)
-               return ISC_R_SUCCESS;
-           if (!supersede_lease(lease, NULL, 1, 1, 1, 0)) {
-               log_error("Failed to update flags for lease %s.",
-                         piaddr(lease->ip_addr));
-               return ISC_R_IOERROR;
-           }
-           return ISC_R_SUCCESS;
+           return (update_lease_flags(lease, value));
        } else if (!omapi_ds_strcmp (name, "billing-class")) {
            return ISC_R_UNCHANGED;     /* XXX carefully allow change. */
        } else if (!omapi_ds_strcmp (name, "hardware-address")) {
@@ -321,6 +309,85 @@ isc_result_t dhcp_lease_set_value  (omapi_object_t *h,
        return ISC_R_IOERROR;
 }
 
+/*
+ * \brief Updates the lease's flags to a given value
+ *
+ * In order to update the lease's flags, we make a copy of the
+ * lease, and update the copy's flags with the new value.
+ * We then use the updated copy as the second parameter to a
+ * call to supersede_lease().  This ensures that the lease
+ * moves between queues correctly.   This is critical when
+ * the RESERVED_LEASE flag is being changed.
+ *
+ * Note that only the EPHEMERAL flags are permitted to be changed.
+ *
+ * \param lease - pointer to the lease to update
+ * \param value - omapi data value containing the new flags value
+ *
+ * \return ISC_R_SUCCESS if the lease was successfully updated,
+ *  ISC_R_UNCHANGED if new value would result in no change to the
+ *  lease's flags, or an appropriate status on other errors
+ */
+static isc_result_t update_lease_flags(struct lease* lease,
+                                      omapi_typed_data_t *value)
+{
+       u_int8_t oldflags;
+       u_int8_t newflags;
+       struct lease* lupdate = NULL;
+       isc_result_t status;
+
+       /* Grab the requested flags value. We (the server) send flags
+        * out as 1-byte, so we expect clients to do the same.  However
+        * omshell, will send a network-ordered 4 byte integer if the
+        * input is "set flags = <n>", so we'll accomdate that too. */
+       if (value->u.buffer.len == 1) {
+               newflags = value->u.buffer.value[0];
+       } else {
+               unsigned long tmp;
+
+               status = omapi_get_int_value (&tmp, value);
+               if (status != ISC_R_SUCCESS) {
+                       return (status);
+               }
+
+               newflags = (u_int8_t)tmp;
+       }
+
+       /* Save off the current flags value. */
+       oldflags = lease->flags;
+
+       /* The new value must preserve all PERSISTANT_FLAGS */
+       newflags = ((lease->flags & ~EPHEMERAL_FLAGS) |
+                   (newflags & EPHEMERAL_FLAGS));
+
+       /* If there's no net change, we're done */
+       if (oldflags == newflags) {
+               return (ISC_R_UNCHANGED);
+       }
+
+       /* Make a copy of the lease. */
+       if (!lease_copy(&lupdate, lease, MDL)) {
+               return (ISC_R_FAILURE);
+       }
+
+       /* Set the copy's flags to the new value */
+       lupdate->flags = newflags;
+
+       /* Attempt to update the lease */
+       if (!supersede_lease(lease, lupdate, 1, 1, 1, 0)) {
+               log_error("Failed to update flags for lease %s.",
+                         piaddr(lease->ip_addr));
+               status = ISC_R_FAILURE;
+       } else {
+               log_debug ("lease flags changed from  %x to %x for lease %s.",
+                          oldflags, newflags, piaddr(lease->ip_addr));
+               status = ISC_R_SUCCESS;
+       }
+
+       lease_dereference(&lupdate, MDL);
+       return (status);
+}
+
 
 isc_result_t dhcp_lease_get_value (omapi_object_t *h, omapi_object_t *id,
                                   omapi_data_string_t *name,