]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
-n [master]
authorShawn Routhier <sar@isc.org>
Tue, 27 Aug 2013 20:40:47 +0000 (13:40 -0700)
committerShawn Routhier <sar@isc.org>
Tue, 27 Aug 2013 20:40:47 +0000 (13:40 -0700)
    [rt27912]
    Add code to suppor on {commit expiry release} statements for DHCPv6.
    There are several pieces to this change
    1) Add space in the iasubopt structure to hold the statement pointers
    2) Update the execute code to fill in the structures as necessary
    3) Execute the statements when appropriate
    Many of the changes in the non-v6 code are to pass the v6 structures
    around to the execute code.

19 files changed:
RELNOTES
client/dhc6.c
client/dhclient.c
common/execute.c
common/tree.c
includes/dhcpd.h
server/bootp.c
server/class.c
server/confpars.c
server/db.c
server/ddns.c
server/dhcp.c
server/dhcpd.c
server/dhcpleasequery.c
server/dhcpv6.c
server/ldap.c
server/mdb.c
server/mdb6.c
server/omapi.c

index 04a16b2c496e687b788752f2b5a38a3603c1fb97..dabff9e62a3d91aca2fcf7ec1028e0a41f3da997 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -69,6 +69,9 @@ work on other platforms. Please report any problems and suggested fixes to
   supported by ISC; however it may be useful to some users.
   [ISC-Bugs #20680]
 
+- Add support in v6 for on-commit, on-expire and on-release.
+  [ISC-Bugs #27912
+
                        Changes since 4.2.5
 
 - Address static analysis warnings.
index 8974e7a6afc385cc20bee62a9ad60566d2a3d75b..33397183e3acb04750dea30c8a4580423d090095 100644 (file)
@@ -1,7 +1,7 @@
 /* dhc6.c - DHCPv6 client routines. */
 
 /*
- * Copyright (c) 2012 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2012-2013 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 2006-2010 by Internet Systems Consortium, Inc. ("ISC")
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -4947,7 +4947,7 @@ make_client6_options(struct client_state *client, struct option_state **op,
                                            lease ? lease->options : NULL,
                                            *op, &global_scope,
                                            client->config->on_transmission,
-                                           NULL);
+                                           NULL, NULL);
 
        /* Rapid-commit is only for SOLICITs. */
        if (message != DHCPV6_SOLICIT)
index aac8084490168fb15cd85a946b1e8f8266a00d65..6bb677f5a6b08e07ffb62a578277d3ccc19768ac 100644 (file)
@@ -1727,13 +1727,10 @@ struct client_lease *packet_to_lease (packet, client)
                }
        }
 
-       execute_statements_in_scope ((struct binding_value **)0,
-                                    (struct packet *)packet,
-                                    (struct lease *)0, client,
-                                    lease -> options, lease -> options,
-                                    &global_scope,
-                                    client -> config -> on_receipt,
-                                    (struct group *)0);
+       execute_statements_in_scope(NULL, (struct packet *)packet, NULL,
+                                   client, lease->options, lease->options,
+                                   &global_scope, client->config->on_receipt,
+                                   NULL, NULL);
 
        return lease;
 }
@@ -2377,14 +2374,12 @@ make_client_options(struct client_state *client, struct client_lease *lease,
        }
 
        /* Run statements that need to be run on transmission. */
-       if (client -> config -> on_transmission)
-               execute_statements_in_scope
-                       ((struct binding_value **)0,
-                        (struct packet *)0, (struct lease *)0, client,
-                        (lease ? lease -> options : (struct option_state *)0),
-                        *op, &global_scope,
-                        client -> config -> on_transmission,
-                        (struct group *)0);
+       if (client->config->on_transmission)
+               execute_statements_in_scope(NULL, NULL, NULL, client,
+                                           (lease ? lease->options : NULL),
+                                           *op, &global_scope,
+                                           client->config->on_transmission,
+                                           NULL, NULL);
 }
 
 void make_discover (client, lease)
index d4c8066d4d4d9759e27cb39e97b0221b5d3b8b47..6b0d16d131d1ff806bcf6e42e965883c5f187b35 100644 (file)
@@ -39,7 +39,8 @@
 #include <sys/wait.h>
 
 int execute_statements (result, packet, lease, client_state,
-                       in_options, out_options, scope, statements)
+                       in_options, out_options, scope, statements,
+                       on_star)
        struct binding_value **result;
        struct packet *packet;
        struct lease *lease;
@@ -48,6 +49,7 @@ int execute_statements (result, packet, lease, client_state,
        struct option_state *out_options;
        struct binding_scope **scope;
        struct executable_statement *statements;
+       struct on_star *on_star;
 {
        struct executable_statement *r, *e, *next;
        int rc;
@@ -59,14 +61,14 @@ int execute_statements (result, packet, lease, client_state,
        if (!statements)
                return 1;
 
-       r = (struct executable_statement *)0;
-       next = (struct executable_statement *)0;
-       e = (struct executable_statement *)0;
+       r = NULL;
+       next = NULL;
+       e = NULL;
        executable_statement_reference (&r, statements, MDL);
        while (r && !(result && *result)) {
-               if (r -> next)
-                       executable_statement_reference (&next, r -> next, MDL);
-               switch (r -> op) {
+               if (r->next)
+                       executable_statement_reference (&next, r->next, MDL);
+               switch (r->op) {
                      case statements_statement:
 #if defined (DEBUG_EXPRESSIONS)
                        log_debug ("exec: statements");
@@ -74,7 +76,8 @@ int execute_statements (result, packet, lease, client_state,
                        status = execute_statements (result, packet, lease,
                                                     client_state, in_options,
                                                     out_options, scope,
-                                                    r -> data.statements);
+                                                    r->data.statements,
+                                                    on_star);
 #if defined (DEBUG_EXPRESSIONS)
                        log_debug ("exec: statements returns %d", status);
 #endif
@@ -83,42 +86,50 @@ int execute_statements (result, packet, lease, client_state,
                        break;
 
                      case on_statement:
-                       if (lease) {
-                           if (r -> data.on.evtypes & ON_EXPIRY) {
+                       /*
+                        * if we haven't been passed an on_star block but
+                        * do have a lease, use the one from the lease
+                        * This handles the previous v4 calls.
+                        */
+                       if ((on_star == NULL) && (lease != NULL))
+                           on_star = &lease->on_star;
+
+                       if (on_star != NULL) {
+                           if (r->data.on.evtypes & ON_EXPIRY) {
 #if defined (DEBUG_EXPRESSIONS)
                                    log_debug ("exec: on expiry");
 #endif
-                               if (lease -> on_expiry)
+                               if (on_star->on_expiry)
                                        executable_statement_dereference
-                                               (&lease -> on_expiry, MDL);
-                               if (r -> data.on.statements)
+                                               (&on_star->on_expiry, MDL);
+                               if (r->data.on.statements)
                                        executable_statement_reference
-                                               (&lease -> on_expiry,
-                                                r -> data.on.statements, MDL);
+                                               (&on_star->on_expiry,
+                                                r->data.on.statements, MDL);
                            }
-                           if (r -> data.on.evtypes & ON_RELEASE) {
+                           if (r->data.on.evtypes & ON_RELEASE) {
 #if defined (DEBUG_EXPRESSIONS)
                                    log_debug ("exec: on release");
 #endif
-                               if (lease -> on_release)
+                               if (on_star->on_release)
                                        executable_statement_dereference
-                                               (&lease -> on_release, MDL);
-                               if (r -> data.on.statements)
+                                               (&on_star->on_release, MDL);
+                               if (r->data.on.statements)
                                        executable_statement_reference
-                                               (&lease -> on_release,
-                                                r -> data.on.statements, MDL);
+                                               (&on_star->on_release,
+                                                r->data.on.statements, MDL);
                            }
-                           if (r -> data.on.evtypes & ON_COMMIT) {
+                           if (r->data.on.evtypes & ON_COMMIT) {
 #if defined (DEBUG_EXPRESSIONS)
                                    log_debug ("exec: on commit");
 #endif
-                               if (lease -> on_commit)
+                               if (on_star->on_commit)
                                        executable_statement_dereference
-                                               (&lease -> on_commit, MDL);
-                               if (r -> data.on.statements)
+                                               (&on_star->on_commit, MDL);
+                               if (r->data.on.statements)
                                        executable_statement_reference
-                                               (&lease -> on_commit,
-                                                r -> data.on.statements, MDL);
+                                               (&on_star->on_commit,
+                                                r->data.on.statements, MDL);
                            }
                        }
                        break;
@@ -130,15 +141,16 @@ int execute_statements (result, packet, lease, client_state,
                        status = (find_matching_case
                                  (&e, packet, lease, client_state,
                                   in_options, out_options, scope,
-                                  r -> data.s_switch.expr,
-                                  r -> data.s_switch.statements));
+                                  r->data.s_switch.expr,
+                                  r->data.s_switch.statements));
 #if defined (DEBUG_EXPRESSIONS)
                        log_debug ("exec: switch: case %lx", (unsigned long)e);
 #endif
                        if (status) {
                                if (!(execute_statements
                                      (result, packet, lease, client_state,
-                                      in_options, out_options, scope, e))) {
+                                      in_options, out_options, scope, e,
+                                      on_star))) {
                                        executable_statement_dereference
                                                (&e, MDL);
                                        return 0;
@@ -156,7 +168,7 @@ int execute_statements (result, packet, lease, client_state,
                        status = (evaluate_boolean_expression
                                  (&rc, packet,
                                   lease, client_state, in_options,
-                                  out_options, scope, r -> data.ie.expr));
+                                  out_options, scope, r->data.ie.expr));
                        
 #if defined (DEBUG_EXPRESSIONS)
                        log_debug ("exec: if %s", (status
@@ -169,15 +181,15 @@ int execute_statements (result, packet, lease, client_state,
                        if (!execute_statements
                            (result, packet, lease, client_state,
                             in_options, out_options, scope,
-                            rc ? r -> data.ie.tc : r -> data.ie.fc))
+                            rc ? r->data.ie.tc : r->data.ie.fc,
+                            on_star))
                                return 0;
                        break;
 
                      case eval_statement:
                        status = evaluate_expression
-                               ((struct binding_value **)0,
-                                packet, lease, client_state, in_options,
-                                out_options, scope, r -> data.eval, MDL);
+                               (NULL, packet, lease, client_state, in_options,
+                                out_options, scope, r->data.eval, MDL);
 #if defined (DEBUG_EXPRESSIONS)
                        log_debug ("exec: evaluate: %s",
                                   (status ? "succeeded" : "failed"));
@@ -281,11 +293,11 @@ int execute_statements (result, packet, lease, client_state,
 
                      case add_statement:
 #if defined (DEBUG_EXPRESSIONS)
-                       log_debug ("exec: add %s", (r -> data.add -> name
-                                              ? r -> data.add -> name
+                       log_debug ("exec: add %s", (r->data.add->name
+                                              ? r->data.add->name
                                               : "<unnamed class>"));
 #endif
-                       classify (packet, r -> data.add);
+                       classify (packet, r->data.add);
                        break;
 
                      case break_statement:
@@ -298,35 +310,35 @@ int execute_statements (result, packet, lease, client_state,
                      case send_option_statement:
 #if defined (DEBUG_EXPRESSIONS)
                        log_debug ("exec: %s option %s.%s",
-                             (r -> op == supersede_option_statement
+                             (r->op == supersede_option_statement
                               ? "supersede" : "send"),
-                             r -> data.option -> option -> universe -> name,
-                             r -> data.option -> option -> name);
+                             r->data.option->option->universe->name,
+                             r->data.option->option->name);
                        goto option_statement;
 #endif
                      case default_option_statement:
 #if defined (DEBUG_EXPRESSIONS)
                        log_debug ("exec: default option %s.%s",
-                             r -> data.option -> option -> universe -> name,
-                             r -> data.option -> option -> name);
+                             r->data.option->option->universe->name,
+                             r->data.option->option->name);
                        goto option_statement;
 #endif
                      case append_option_statement:
 #if defined (DEBUG_EXPRESSIONS)
                        log_debug ("exec: append option %s.%s",
-                             r -> data.option -> option -> universe -> name,
-                             r -> data.option -> option -> name);
+                             r->data.option->option->universe->name,
+                             r->data.option->option->name);
                        goto option_statement;
 #endif
                      case prepend_option_statement:
 #if defined (DEBUG_EXPRESSIONS)
                        log_debug ("exec: prepend option %s.%s",
-                             r -> data.option -> option -> universe -> name,
-                             r -> data.option -> option -> name);
+                             r->data.option->option->universe->name,
+                             r->data.option->option->name);
                      option_statement:
 #endif
-                       set_option (r -> data.option -> option -> universe,
-                                   out_options, r -> data.option, r -> op);
+                       set_option (r->data.option->option->universe,
+                                   out_options, r->data.option, r->op);
                        break;
 
                      case set_statement:
@@ -407,16 +419,16 @@ int execute_statements (result, packet, lease, client_state,
                      case unset_statement:
                        if (!scope || !*scope)
                                break;
-                       binding = find_binding (*scope, r -> data.unset);
+                       binding = find_binding (*scope, r->data.unset);
                        if (binding) {
-                               if (binding -> value)
+                               if (binding->value)
                                        binding_value_dereference
-                                               (&binding -> value, MDL);
+                                               (&binding->value, MDL);
                                status = 1;
                        } else
                                status = 0;
 #if defined (DEBUG_EXPRESSIONS)
-                       log_debug ("exec: unset %s: %s", r -> data.unset,
+                       log_debug ("exec: unset %s: %s", r->data.unset,
                                   (status ? "found" : "not found"));
 #else
                        POST(status);
@@ -482,10 +494,9 @@ int execute_statements (result, packet, lease, client_state,
                                        binding_scope_reference(&ns->outer,
                                                                *scope, MDL);
                                execute_statements
-                                     (result, packet, lease,
-                                      client_state,
+                                     (result, packet, lease, client_state,
                                       in_options, out_options,
-                                      &ns, e->data.let.statements);
+                                      &ns, e->data.let.statements, on_star);
                        }
                        if (ns)
                                binding_scope_dereference(&ns, MDL);
@@ -496,15 +507,14 @@ int execute_statements (result, packet, lease, client_state,
                        status = (evaluate_data_expression
                                  (&ds, packet,
                                   lease, client_state, in_options,
-                                  out_options, scope, r -> data.log.expr,
-                                  MDL));
+                                  out_options, scope, r->data.log.expr, MDL));
                        
 #if defined (DEBUG_EXPRESSIONS)
                        log_debug ("exec: log");
 #endif
 
                        if (status) {
-                               switch (r -> data.log.priority) {
+                               switch (r->data.log.priority) {
                                case log_priority_fatal:
                                        log_fatal ("%.*s", (int)ds.len,
                                                ds.data);
@@ -550,7 +560,7 @@ int execute_statements (result, packet, lease, client_state,
 
 void execute_statements_in_scope (result, packet,
                                  lease, client_state, in_options, out_options,
-                                 scope, group, limiting_group)
+                                 scope, group, limiting_group, on_star)
        struct binding_value **result;
        struct packet *packet;
        struct lease *lease;
@@ -560,6 +570,7 @@ void execute_statements_in_scope (result, packet,
        struct binding_scope **scope;
        struct group *group;
        struct group *limiting_group;
+       struct on_star *on_star;
 {
        struct group *limit;
 
@@ -599,9 +610,10 @@ void execute_statements_in_scope (result, packet,
                execute_statements_in_scope (result, packet,
                                             lease, client_state,
                                             in_options, out_options, scope,
-                                            group -> next, limiting_group);
+                                            group->next, limiting_group,
+                                            on_star);
        execute_statements (result, packet, lease, client_state, in_options,
-                           out_options, scope, group -> statements);
+                           out_options, scope, group->statements, on_star);
 }
 
 /* Dereference or free any subexpressions of a statement being freed. */
@@ -1033,14 +1045,14 @@ int find_matching_case (struct executable_statement **ep,
                                sub = (evaluate_data_expression
                                       (&cd, packet, lease, client_state,
                                        in_options, out_options,
-                                       scope, s -> data.c_case, MDL));
+                                       scope, s->data.c_case, MDL));
                                if (sub && cd.len == ds.len &&
                                    !memcmp (cd.data, ds.data, cd.len))
                                {
                                        data_string_forget (&cd, MDL);
                                        data_string_forget (&ds, MDL);
                                        executable_statement_reference
-                                               (ep, s -> next, MDL);
+                                               (ep, s->next, MDL);
                                        return 1;
                                }
                                data_string_forget (&cd, MDL);
@@ -1056,15 +1068,15 @@ int find_matching_case (struct executable_statement **ep,
                                                      scope, expr);
 
                if (status) {
-                   for (s = stmt; s; s = s -> next) {
+                   for (s = stmt; s; s = s->next) {
                        if (s -> op == case_statement) {
                                sub = (evaluate_numeric_expression
                                       (&c, packet, lease, client_state,
                                        in_options, out_options,
-                                       scope, s -> data.c_case));
+                                       scope, s->data.c_case));
                                if (sub && n == c) {
                                        executable_statement_reference
-                                               (ep, s -> next, MDL);
+                                               (ep, s->next, MDL);
                                        return 1;
                                }
                        }
@@ -1074,11 +1086,11 @@ int find_matching_case (struct executable_statement **ep,
 
        /* If we didn't find a matching case statement, look for a default
           statement and return the statement following it. */
-       for (s = stmt; s; s = s -> next)
-               if (s -> op == default_statement)
+       for (s = stmt; s; s = s->next)
+               if (s->op == default_statement)
                        break;
        if (s) {
-               executable_statement_reference (ep, s -> next, MDL);
+               executable_statement_reference (ep, s->next, MDL);
                return 1;
        }
        return 0;
@@ -1093,17 +1105,17 @@ int executable_statement_foreach (struct executable_statement *stmt,
        struct executable_statement *foo;
        int ok = 0;
 
-       for (foo = stmt; foo; foo = foo -> next) {
+       for (foo = stmt; foo; foo = foo->next) {
            if ((*callback) (foo, vp, condp) != 0)
                ok = 1;
-           switch (foo -> op) {
+           switch (foo->op) {
              case null_statement:
                break;
              case if_statement:
-               if (executable_statement_foreach (foo -> data.ie.tc,
+               if (executable_statement_foreach (foo->data.ie.tc,
                                                  callback, vp, 1))
                        ok = 1;
-               if (executable_statement_foreach (foo -> data.ie.fc,
+               if (executable_statement_foreach (foo->data.ie.fc,
                                                  callback, vp, 1))
                        ok = 1;
                break;
@@ -1125,17 +1137,17 @@ int executable_statement_foreach (struct executable_statement *stmt,
                break;
              case statements_statement:
                if ((executable_statement_foreach
-                    (foo -> data.statements, callback, vp, condp)))
+                    (foo->data.statements, callback, vp, condp)))
                        ok = 1;
                break;
              case on_statement:
                if ((executable_statement_foreach
-                    (foo -> data.on.statements, callback, vp, 1)))
+                    (foo->data.on.statements, callback, vp, 1)))
                        ok = 1;
                break;
              case switch_statement:
                if ((executable_statement_foreach
-                    (foo -> data.s_switch.statements, callback, vp, 1)))
+                    (foo->data.s_switch.statements, callback, vp, 1)))
                        ok = 1;
                break;
              case case_statement:
@@ -1148,7 +1160,7 @@ int executable_statement_foreach (struct executable_statement *stmt,
                break;
              case let_statement:
                if ((executable_statement_foreach
-                    (foo -> data.let.statements, callback, vp, 0)))
+                    (foo->data.let.statements, callback, vp, 0)))
                        ok = 1;
                break;
              case define_statement:
index b9a88b9f55179ccee4f11e7e4483a0bdda7c42c2..33c5630dbb4cbe8ea6d9529e779e83f1787711e4 100644 (file)
@@ -618,7 +618,7 @@ int evaluate_expression (result, packet, lease, client_state,
                status = (execute_statements
                          (&bv, packet,
                           lease, client_state, in_options, cfg_options, &ns,
-                          binding -> value -> value.fundef -> statements));
+                          binding->value->value.fundef->statements, NULL));
                binding_scope_dereference (&ns, MDL);
 
                if (!bv)
index 4c5cef0c9b5c457cdbd746e66f8e009d056a1380..0e96d5b396e89ccfc04edf4e911b3b8ac2f688a0 100644 (file)
@@ -497,6 +497,16 @@ typedef u_int8_t binding_state_t;
 /* FTS_LAST is the highest value that is valid for a lease binding state. */
 #define FTS_LAST FTS_BACKUP
 
+/*
+ * A block for the on statements so we can share the structure
+ * between v4 and v6
+ */
+struct on_star {
+       struct executable_statement *on_expiry;
+       struct executable_statement *on_commit;
+       struct executable_statement *on_release;
+};
+
 /* A dhcp lease declaration structure. */
 struct lease {
        OMAPI_OBJECT_PREAMBLE;
@@ -513,9 +523,8 @@ struct lease {
        struct class *billing_class;
        struct option_chain_head *agent_options;
 
-       struct executable_statement *on_expiry;
-       struct executable_statement *on_commit;
-       struct executable_statement *on_release;
+       /* insert the structure directly */
+       struct on_star on_star;
 
        unsigned char *uid;
        unsigned short uid_len;
@@ -1503,6 +1512,8 @@ struct iasubopt {
         */
        struct dhcp_ddns_cb *ddns_cb;
 
+       /* space for the on * executable statements */
+       struct on_star on_star;
 };
 
 struct ia_xx {
@@ -2079,7 +2090,8 @@ int evaluate_data_expression (struct data_string *,
                              struct option_state *,
                              struct option_state *,
                              struct binding_scope **,
-                             struct expression *, const char *, int);
+                             struct expression *,
+                             const char *, int);
 int evaluate_numeric_expression (unsigned long *, struct packet *,
                                 struct lease *, struct client_state *,
                                 struct option_state *, struct option_state *,
@@ -2944,14 +2956,16 @@ int execute_statements (struct binding_value **result,
                        struct client_state *,
                        struct option_state *, struct option_state *,
                        struct binding_scope **,
-                       struct executable_statement *);
+                       struct executable_statement *,
+                       struct on_star *);
 void execute_statements_in_scope (struct binding_value **result,
                                  struct packet *, struct lease *,
                                  struct client_state *,
                                  struct option_state *,
                                  struct option_state *,
                                  struct binding_scope **,
-                                 struct group *, struct group *);
+                                 struct group *, struct group *,
+                                 struct on_star *);
 int executable_statement_dereference (struct executable_statement **,
                                      const char *, int);
 void write_statements (FILE *, struct executable_statement *, int);
index f0b787c166e91c63c77a564802769ba49a6a89d8..a0508ce43ca096a324d3cab4cf1efd53c3c9d4ee 100644 (file)
@@ -3,7 +3,7 @@
    BOOTP Protocol support. */
 
 /*
- * Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2009,2012-2013 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 2004,2005,2007 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 1995-2003 by Internet Software Consortium
  *
@@ -160,28 +160,26 @@ void bootp (packet)
        option_state_allocate (&options, MDL);
 
        /* Execute the subnet statements. */
-       execute_statements_in_scope ((struct binding_value **)0,
-                                    packet, lease, (struct client_state *)0,
-                                    packet -> options, options,
-                                    &lease -> scope, lease -> subnet -> group,
-                                    (struct group *)0);
+       execute_statements_in_scope (NULL, packet, lease, NULL,
+                                    packet->options, options,
+                                    &lease->scope, lease->subnet->group,
+                                    NULL, NULL);
 
        /* Execute statements from class scopes. */
        for (i = packet -> class_count; i > 0; i--) {
-               execute_statements_in_scope
-                       ((struct binding_value **)0,
-                        packet, lease, (struct client_state *)0,
-                        packet -> options, options,
-                        &lease -> scope, packet -> classes [i - 1] -> group,
-                        lease -> subnet -> group);
+               execute_statements_in_scope(NULL, packet, lease, NULL,
+                                           packet->options, options,
+                                           &lease->scope,
+                                           packet->classes[i - 1]->group,
+                                           lease->subnet->group, NULL);
        }
 
        /* Execute the host statements. */
        if (hp != NULL) {
                execute_statements_in_scope (NULL, packet, lease, NULL,
                                             packet->options, options,
-                                            &lease->scope,
-                                            hp->group, lease->subnet->group);
+                                            &lease->scope, hp->group,
+                                            lease->subnet->group, NULL);
        }
        
        /* Drop the request if it's not allowed for this client. */
@@ -340,10 +338,9 @@ void bootp (packet)
        }
 
        /* Execute the commit statements, if there are any. */
-       execute_statements ((struct binding_value **)0,
-                           packet, lease, (struct client_state *)0,
-                           packet -> options,
-                           options, &lease -> scope, lease -> on_commit);
+       execute_statements (NULL, packet, lease, NULL, packet->options,
+                           options, &lease->scope, lease->on_star.on_commit,
+                           NULL);
 
        /* We're done with the option state. */
        option_state_dereference (&options, MDL);
index b8eac87ceff90115a3724f6b3a063f492f2729ae..7bfb6b7e627f219d1cd4011c7c9ef3f160d1bf9f 100644 (file)
@@ -3,7 +3,7 @@
    Handling for client classes. */
 
 /*
- * Copyright (c) 2009,2012 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2009,2012-2013 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 1998-2003 by Internet Software Consortium
  *
@@ -69,10 +69,8 @@ void classification_setup ()
 void classify_client (packet)
        struct packet *packet;
 {
-       execute_statements ((struct binding_value **)0, packet,
-                           (struct lease *)0, (struct client_state *)0,
-                           packet -> options, (struct option_state *)0,
-                           &global_scope, default_classification_rules);
+       execute_statements (NULL, packet, NULL, NULL, packet->options, NULL,
+                           &global_scope, default_classification_rules, NULL);
 }
 
 int check_collection (packet, lease, collection)
index 97b42c84c1d29006ce7cbd190015da2b42b28220..3cd35a03b04928a42a94bd33d136eca16b375576 100644 (file)
@@ -3248,19 +3248,19 @@ int parse_lease_declaration (struct lease **lp, struct parse *cfile)
                                return 0;
                        }
                        seenbit = 0;
-                       if ((on -> data.on.evtypes & ON_EXPIRY) &&
-                           on -> data.on.statements) {
+                       if ((on->data.on.evtypes & ON_EXPIRY) &&
+                           on->data.on.statements) {
                                seenbit |= 16384;
                                executable_statement_reference
-                                       (&lease -> on_expiry,
-                                        on -> data.on.statements, MDL);
+                                       (&lease->on_star.on_expiry,
+                                        on->data.on.statements, MDL);
                        }
-                       if ((on -> data.on.evtypes & ON_RELEASE) &&
-                           on -> data.on.statements) {
+                       if ((on->data.on.evtypes & ON_RELEASE) &&
+                           on->data.on.statements) {
                                seenbit |= 32768;
                                executable_statement_reference
-                                       (&lease -> on_release,
-                                        on -> data.on.statements, MDL);
+                                       (&lease->on_star.on_release,
+                                        on->data.on.statements, MDL);
                        }
                        executable_statement_dereference (&on, MDL);
                        break;
@@ -3400,31 +3400,31 @@ int parse_lease_declaration (struct lease **lp, struct parse *cfile)
 
        /* If no binding state is specified, make one up. */
        if (!(seenmask & 256)) {
-               if (lease -> ends > cur_time ||
-                   lease -> on_expiry || lease -> on_release)
-                       lease -> binding_state = FTS_ACTIVE;
+               if (lease->ends > cur_time ||
+                   lease->on_star.on_expiry || lease->on_star.on_release)
+                       lease->binding_state = FTS_ACTIVE;
 #if defined (FAILOVER_PROTOCOL)
-               else if (lease -> pool && lease -> pool -> failover_peer)
-                       lease -> binding_state = FTS_EXPIRED;
+               else if (lease->pool && lease->pool->failover_peer)
+                       lease->binding_state = FTS_EXPIRED;
 #endif
                else
-                       lease -> binding_state = FTS_FREE;
-               if (lease -> binding_state == FTS_ACTIVE) {
+                       lease->binding_state = FTS_FREE;
+               if (lease->binding_state == FTS_ACTIVE) {
 #if defined (FAILOVER_PROTOCOL)
-                       if (lease -> pool && lease -> pool -> failover_peer)
-                               lease -> next_binding_state = FTS_EXPIRED;
+                       if (lease->pool && lease->pool->failover_peer)
+                               lease->next_binding_state = FTS_EXPIRED;
                        else
 #endif
-                               lease -> next_binding_state = FTS_FREE;
+                               lease->next_binding_state = FTS_FREE;
                } else
-                       lease -> next_binding_state = lease -> binding_state;
+                       lease->next_binding_state = lease->binding_state;
 
                /* The most conservative rewind state implies no rewind. */
                lease->rewind_binding_state = lease->binding_state;
        }
 
        if (!(seenmask & 65536))
-               lease -> tstp = lease -> ends;
+               lease->tstp = lease->ends;
 
        lease_reference (lp, lease, MDL);
        lease_dereference (&lease, MDL);
@@ -4146,9 +4146,11 @@ parse_ia_na_declaration(struct parse *cfile) {
        struct ipv6_pool *pool;
        char addr_buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
        isc_boolean_t newbinding;
-       struct binding_scope *scope=NULL;
+       struct binding_scope *scope = NULL;
        struct binding *bnd;
-       struct binding_value *nv=NULL;
+       struct binding_value *nv = NULL;
+       struct executable_statement *on_star[2] = {NULL, NULL};
+       int lose, i;
 
         if (local_family != AF_INET6) {
                 parse_warn(cfile, "IA_NA is only supported in DHCPv6 mode.");
@@ -4409,6 +4411,41 @@ parse_ia_na_declaration(struct parse *cfile) {
                                parse_semi(cfile);
                                break;
 
+                             case ON:
+                               lose = 0;
+                               /*
+                                * Depending on the user config we may
+                                * have one or two on statements.  We
+                                * need to save information about both
+                                * of them until we allocate the
+                                * iasubopt to hold them.
+                                */
+                               if (on_star[0] == NULL) {
+                                       if (!parse_on_statement (&on_star[0],
+                                                                cfile,
+                                                                &lose)) {
+                                               parse_warn(cfile,
+                                                          "corrupt lease "
+                                                          "file; bad ON "
+                                                          "statement");
+                                               skip_to_rbrace (cfile, 1);
+                                               return;
+                                       }
+                               } else {
+                                       if (!parse_on_statement (&on_star[1],
+                                                                cfile,
+                                                                &lose)) {
+                                               parse_warn(cfile,
+                                                          "corrupt lease "
+                                                          "file; bad ON "
+                                                          "statement");
+                                               skip_to_rbrace (cfile, 1);
+                                               return;
+                                       }
+                               }
+
+                               break;
+                         
                              default:
                                parse_warn(cfile, "corrupt lease file; "
                                                  "expecting ia_na contents, "
@@ -4446,6 +4483,30 @@ parse_ia_na_declaration(struct parse *cfile) {
                        binding_scope_dereference(&scope, MDL);
                }
 
+               /*
+                * Check on both on statements.  Because of how we write the
+                * lease file we know which is which if we have two but it's
+                * easier to write the code to be independent.  We do assume
+                * that the statements won't overlap.
+                */
+               for (i = 0;
+                    (i < 2) && on_star[i] != NULL ;
+                    i++) {
+                       if ((on_star[i]->data.on.evtypes & ON_EXPIRY) &&
+                           on_star[i]->data.on.statements) {
+                               executable_statement_reference
+                                       (&iaaddr->on_star.on_expiry,
+                                        on_star[i]->data.on.statements, MDL);
+                       }
+                       if ((on_star[i]->data.on.evtypes & ON_RELEASE) &&
+                           on_star[i]->data.on.statements) {
+                               executable_statement_reference
+                                       (&iaaddr->on_star.on_release,
+                                        on_star[i]->data.on.statements, MDL);
+                       }
+                       executable_statement_dereference (&on_star[i], MDL);
+               }
+                       
                /* find the pool this address is in */
                pool = NULL;
                if (find_ipv6_pool(&pool, D6O_IA_NA,
@@ -4527,9 +4588,11 @@ parse_ia_ta_declaration(struct parse *cfile) {
        struct ipv6_pool *pool;
        char addr_buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
        isc_boolean_t newbinding;
-       struct binding_scope *scope=NULL;
+       struct binding_scope *scope = NULL;
        struct binding *bnd;
-       struct binding_value *nv=NULL;
+       struct binding_value *nv = NULL;
+       struct executable_statement *on_star[2] = {NULL, NULL};
+       int lose, i;
 
         if (local_family != AF_INET6) {
                 parse_warn(cfile, "IA_TA is only supported in DHCPv6 mode.");
@@ -4790,6 +4853,41 @@ parse_ia_ta_declaration(struct parse *cfile) {
                                parse_semi(cfile);
                                break;
 
+                             case ON:
+                               lose = 0;
+                               /*
+                                * Depending on the user config we may
+                                * have one or two on statements.  We
+                                * need to save information about both
+                                * of them until we allocate the
+                                * iasubopt to hold them.
+                                */
+                               if (on_star[0] == NULL) {
+                                       if (!parse_on_statement (&on_star[0],
+                                                                cfile,
+                                                                &lose)) {
+                                               parse_warn(cfile,
+                                                          "corrupt lease "
+                                                          "file; bad ON "
+                                                          "statement");
+                                               skip_to_rbrace (cfile, 1);
+                                               return;
+                                       }
+                               } else {
+                                       if (!parse_on_statement (&on_star[1],
+                                                                cfile,
+                                                                &lose)) {
+                                               parse_warn(cfile,
+                                                          "corrupt lease "
+                                                          "file; bad ON "
+                                                          "statement");
+                                               skip_to_rbrace (cfile, 1);
+                                               return;
+                                       }
+                               }
+                                       
+                               break;
+                         
                              default:
                                parse_warn(cfile, "corrupt lease file; "
                                                  "expecting ia_ta contents, "
@@ -4827,6 +4925,30 @@ parse_ia_ta_declaration(struct parse *cfile) {
                        binding_scope_dereference(&scope, MDL);
                }
 
+               /*
+                * Check on both on statements.  Because of how we write the
+                * lease file we know which is which if we have two but it's
+                * easier to write the code to be independent.  We do assume
+                * that the statements won't overlap.
+                */
+               for (i = 0;
+                    (i < 2) && on_star[i] != NULL ;
+                    i++) {
+                       if ((on_star[i]->data.on.evtypes & ON_EXPIRY) &&
+                           on_star[i]->data.on.statements) {
+                               executable_statement_reference
+                                       (&iaaddr->on_star.on_expiry,
+                                        on_star[i]->data.on.statements, MDL);
+                       }
+                       if ((on_star[i]->data.on.evtypes & ON_RELEASE) &&
+                           on_star[i]->data.on.statements) {
+                               executable_statement_reference
+                                       (&iaaddr->on_star.on_release,
+                                        on_star[i]->data.on.statements, MDL);
+                       }
+                       executable_statement_dereference (&on_star[i], MDL);
+               }
+                       
                /* find the pool this address is in */
                pool = NULL;
                if (find_ipv6_pool(&pool, D6O_IA_TA,
@@ -4909,9 +5031,11 @@ parse_ia_pd_declaration(struct parse *cfile) {
        struct ipv6_pool *pool;
        char addr_buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
        isc_boolean_t newbinding;
-       struct binding_scope *scope=NULL;
+       struct binding_scope *scope = NULL;
        struct binding *bnd;
-       struct binding_value *nv=NULL;
+       struct binding_value *nv = NULL;
+       struct executable_statement *on_star[2] = {NULL, NULL};
+       int lose, i;
 
         if (local_family != AF_INET6) {
                 parse_warn(cfile, "IA_PD is only supported in DHCPv6 mode.");
@@ -5172,6 +5296,41 @@ parse_ia_pd_declaration(struct parse *cfile) {
                                parse_semi(cfile);
                                break;
 
+                             case ON:
+                               lose = 0;
+                               /*
+                                * Depending on the user config we may
+                                * have one or two on statements.  We
+                                * need to save information about both
+                                * of them until we allocate the
+                                * iasubopt to hold them.
+                                */
+                               if (on_star[0] == NULL) {
+                                       if (!parse_on_statement (&on_star[0],
+                                                                cfile,
+                                                                &lose)) {
+                                               parse_warn(cfile,
+                                                          "corrupt lease "
+                                                          "file; bad ON "
+                                                          "statement");
+                                               skip_to_rbrace (cfile, 1);
+                                               return;
+                                       }
+                               } else {
+                                       if (!parse_on_statement (&on_star[1],
+                                                                cfile,
+                                                                &lose)) {
+                                               parse_warn(cfile,
+                                                          "corrupt lease "
+                                                          "file; bad ON "
+                                                          "statement");
+                                               skip_to_rbrace (cfile, 1);
+                                               return;
+                                       }
+                               }
+
+                               break;
+                         
                              default:
                                parse_warn(cfile, "corrupt lease file; "
                                                  "expecting ia_pd contents, "
@@ -5209,6 +5368,30 @@ parse_ia_pd_declaration(struct parse *cfile) {
                        binding_scope_dereference(&scope, MDL);
                }
 
+               /*
+                * Check on both on statements.  Because of how we write the
+                * lease file we know which is which if we have two but it's
+                * easier to write the code to be independent.  We do assume
+                * that the statements won't overlap.
+                */
+               for (i = 0;
+                    (i < 2) && on_star[i] != NULL ;
+                    i++) {
+                       if ((on_star[i]->data.on.evtypes & ON_EXPIRY) &&
+                           on_star[i]->data.on.statements) {
+                               executable_statement_reference
+                                       (&iapref->on_star.on_expiry,
+                                        on_star[i]->data.on.statements, MDL);
+                       }
+                       if ((on_star[i]->data.on.evtypes & ON_RELEASE) &&
+                           on_star[i]->data.on.statements) {
+                               executable_statement_reference
+                                       (&iapref->on_star.on_release,
+                                        on_star[i]->data.on.statements, MDL);
+                       }
+                       executable_statement_dereference (&on_star[i], MDL);
+               }
+                       
                /* find the pool this address is in */
                pool = NULL;
                if (find_ipv6_pool(&pool, D6O_IA_PD,
index de18529352231111d8c096df4b84e34c459e72a9..94abfbde7c3226ba01541bb4227d27036273efac 100644 (file)
@@ -3,7 +3,8 @@
    Persistent database management routines for DHCPD... */
 
 /*
- * Copyright (c) 2004-2010,2012 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2012,2013 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2010 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
@@ -264,21 +265,22 @@ int write_lease (lease)
                } else
                        ++errors;
        }
-       if (lease -> on_expiry) {
+       if (lease->on_star.on_expiry) {
                errno = 0;
                fprintf (db_file, "\n  on expiry%s {",
-                        lease -> on_expiry == lease -> on_release
+                        lease->on_star.on_expiry == lease->on_star.on_release
                         ? " or release" : "");
-               write_statements (db_file, lease -> on_expiry, 4);
+               write_statements (db_file, lease->on_star.on_expiry, 4);
                /* XXX */
                fprintf (db_file, "\n  }");
                if (errno)
                        ++errors;
        }
-       if (lease -> on_release && lease -> on_release != lease -> on_expiry) {
+       if (lease->on_star.on_release &&
+           lease->on_star.on_release != lease->on_star.on_expiry) {
                errno = 0;
                fprintf (db_file, "\n  on release {");
-               write_statements (db_file, lease -> on_release, 4);
+               write_statements (db_file, lease->on_star.on_release, 4);
                /* XXX */
                fprintf (db_file, "\n  }");
                if (errno)
@@ -642,6 +644,29 @@ write_ia(const struct ia_xx *ia) {
                                
                }
 
+               if (iasubopt->on_star.on_expiry) {
+                       if (fprintf(db_file, "\n    on expiry%s {",
+                                   iasubopt->on_star.on_expiry ==
+                                   iasubopt->on_star.on_release
+                                   ? " or release" : "") < 0)
+                               goto error_exit;
+                       write_statements(db_file,
+                                        iasubopt->on_star.on_expiry, 6);
+                       if (fprintf(db_file, "\n    }") < 0) 
+                               goto error_exit;
+               }
+
+               if (iasubopt->on_star.on_release &&
+                   iasubopt->on_star.on_release !=
+                   iasubopt->on_star.on_expiry) {
+                       if (fprintf(db_file, "\n    on release {") < 0)
+                               goto error_exit;
+                       write_statements(db_file,
+                                        iasubopt->on_star.on_release, 6);
+                       if (fprintf(db_file, "\n    }") < 0)
+                               goto error_exit;
+               }
+
                if (fprintf(db_file, "\n  }\n") < 0)
                         goto error_exit;
        }
index 80418721a461352cedbd2308767aebacdb064119..74021fcd7915df332c9ef7e10c5f1fe64c579072 100644 (file)
@@ -4,7 +4,7 @@
 
 /*
  * 
- * Copyright (c) 2009-2012 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2009-2013 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 2000-2003 by Internet Software Consortium
  *
@@ -275,16 +275,20 @@ ddns_updates(struct packet *packet, struct lease *lease, struct lease *old,
                           So if the expiry and release events look like
                           they're the same, run them.   This should delete
                           the old DDNS data. */
-                       if (old -> on_expiry == old -> on_release) {
+                       if (old->on_star.on_expiry ==
+                           old->on_star.on_release) {
                                execute_statements(NULL, NULL, lease, NULL,
                                                   NULL, NULL, scope,
-                                                  old->on_expiry);
-                               if (old -> on_expiry)
+                                                  old->on_star.on_expiry,
+                                                  NULL);
+                               if (old->on_star.on_expiry)
                                        executable_statement_dereference
-                                               (&old -> on_expiry, MDL);
-                               if (old -> on_release)
+                                               (&old->on_star.on_expiry,
+                                                MDL);
+                               if (old->on_star.on_release)
                                        executable_statement_dereference
-                                               (&old -> on_release, MDL);
+                                               (&old->on_star.on_release,
+                                                MDL);
                                /* Now, install the DDNS data the new way. */
                                goto in;
                        }
index 81095521a0ee183248b4c449533767de4d72a878..29ab510946dd772a4b7f85e56f898aa46a7a1764 100644 (file)
@@ -907,21 +907,18 @@ void dhcpdecline (packet, ms_nulltp)
 
        /* Execute statements in scope starting with the subnet scope. */
        if (lease)
-               execute_statements_in_scope ((struct binding_value **)0,
-                                            packet, (struct lease *)0,
-                                            (struct client_state *)0,
-                                            packet -> options, options,
-                                            &global_scope,
-                                            lease -> subnet -> group,
-                                            (struct group *)0);
+               execute_statements_in_scope(NULL, packet, NULL, NULL,
+                                           packet->options, options,
+                                           &global_scope,
+                                           lease->subnet->group,
+                                           NULL, NULL);
 
        /* Execute statements in the class scopes. */
        for (i = packet -> class_count; i > 0; i--) {
                execute_statements_in_scope
-                       ((struct binding_value **)0, packet, (struct lease *)0,
-                        (struct client_state *)0, packet -> options, options,
-                        &global_scope, packet -> classes [i - 1] -> group,
-                        lease ? lease -> subnet -> group : (struct group *)0);
+                       (NULL, packet, NULL, NULL, packet->options, options,
+                        &global_scope, packet->classes[i - 1]->group,
+                        lease ? lease->subnet->group : NULL, NULL);
        }
 
        /* Drop the request if dhcpdeclines are being ignored. */
@@ -1082,20 +1079,19 @@ void dhcpinform (packet, ms_nulltp)
 
        /* Execute statements in scope starting with the subnet scope. */
        if (subnet)
-               execute_statements_in_scope ((struct binding_value **)0,
-                                            packet, (struct lease *)0,
-                                            (struct client_state *)0,
-                                            packet -> options, options,
-                                            &global_scope, subnet -> group,
-                                            (struct group *)0);
+               execute_statements_in_scope (NULL, packet, NULL, NULL,
+                                            packet->options, options,
+                                            &global_scope, subnet->group,
+                                            NULL, NULL);
 
        /* Execute statements in the class scopes. */
        for (i = packet -> class_count; i > 0; i--) {
-               execute_statements_in_scope
-                       ((struct binding_value **)0, packet, (struct lease *)0,
-                        (struct client_state *)0, packet -> options, options,
-                        &global_scope, packet -> classes [i - 1] -> group,
-                        subnet ? subnet -> group : (struct group *)0);
+               execute_statements_in_scope(NULL, packet, NULL, NULL,
+                                           packet->options, options,
+                                           &global_scope,
+                                           packet->classes[i - 1]->group,
+                                           subnet ? subnet->group : NULL,
+                                           NULL);
        }
 
        /* Figure out the filename. */
@@ -1604,47 +1600,45 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
           REQUEST our offer, it will expire in 2 minutes, overriding the
           expire time in the currently in force lease.  We want the expire
           events to be executed at that point. */
-       if (lease -> ends <= cur_time && offer != DHCPOFFER) {
+       if (lease->ends <= cur_time && offer != DHCPOFFER) {
                /* Get rid of any old expiry or release statements - by
                   executing the statements below, we will be inserting new
                   ones if there are any to insert. */
-               if (lease -> on_expiry)
-                       executable_statement_dereference (&lease -> on_expiry,
-                                                         MDL);
-               if (lease -> on_commit)
-                       executable_statement_dereference (&lease -> on_commit,
-                                                         MDL);
-               if (lease -> on_release)
-                       executable_statement_dereference (&lease -> on_release,
-                                                         MDL);
+               if (lease->on_star.on_expiry)
+                       executable_statement_dereference
+                               (&lease->on_star.on_expiry, MDL);
+               if (lease->on_star.on_commit)
+                       executable_statement_dereference
+                               (&lease->on_star.on_commit, MDL);
+               if (lease->on_star.on_release)
+                       executable_statement_dereference
+                               (&lease->on_star.on_release, MDL);
        }
 
        /* Execute statements in scope starting with the subnet scope. */
-       execute_statements_in_scope ((struct binding_value **)0,
-                                    packet, lease, (struct client_state *)0,
-                                    packet -> options,
-                                    state -> options, &lease -> scope,
-                                    lease -> subnet -> group,
-                                    (struct group *)0);
+       execute_statements_in_scope (NULL, packet, lease,
+                                    NULL, packet->options,
+                                    state->options, &lease->scope,
+                                    lease->subnet->group, NULL, NULL);
 
        /* If the lease is from a pool, run the pool scope. */
-       if (lease -> pool)
-               (execute_statements_in_scope
-                ((struct binding_value **)0, packet, lease,
-                 (struct client_state *)0, packet -> options,
-                 state -> options, &lease -> scope, lease -> pool -> group,
-                 lease -> pool -> shared_network -> group));
+       if (lease->pool)
+               (execute_statements_in_scope(NULL, packet, lease, NULL,
+                                            packet->options, state->options,
+                                            &lease->scope, lease->pool->group,
+                                            lease->pool->
+                                               shared_network->group,
+                                            NULL));
 
        /* Execute statements from class scopes. */
        for (i = packet -> class_count; i > 0; i--) {
-               execute_statements_in_scope
-                       ((struct binding_value **)0,
-                        packet, lease, (struct client_state *)0,
-                        packet -> options, state -> options,
-                        &lease -> scope, packet -> classes [i - 1] -> group,
-                        (lease -> pool
-                         ? lease -> pool -> group
-                         : lease -> subnet -> group));
+               execute_statements_in_scope(NULL, packet, lease, NULL,
+                                           packet->options, state->options,
+                                           &lease->scope,
+                                           packet->classes[i - 1]->group,
+                                           (lease->pool ? lease->pool->group
+                                            : lease->subnet->group),
+                                           NULL);
        }
 
        /* See if the client is only supposed to have one lease at a time,
@@ -1829,7 +1823,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
                                host_dereference(&hp, MDL);
                }
                if (!host) {
-                       find_hosts_by_option(&hp, packet, packet->options, MDL);
+                       find_hosts_by_option(&hp, packet,
+                                            packet->options, MDL);
                        for (h = hp; h; h = h -> n_ipaddr) {
                                if (!h -> fixed_addr)
                                        break;
@@ -1844,15 +1839,13 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
        /* If we have a host_decl structure, run the options associated
           with its group.  Whether the host decl struct is old or not. */
        if (host)
-               execute_statements_in_scope ((struct binding_value **)0,
-                                            packet, lease,
-                                            (struct client_state *)0,
-                                            packet -> options,
-                                            state -> options, &lease -> scope,
-                                            host -> group,
-                                            (lease -> pool
-                                             ? lease -> pool -> group
-                                             : lease -> subnet -> group));
+               execute_statements_in_scope (NULL, packet, lease, NULL,
+                                            packet->options, state->options,
+                                            &lease->scope, host->group,
+                                            (lease->pool
+                                             ? lease->pool->group
+                                             : lease->subnet->group),
+                                            NULL);
 
        /* Drop the request if it's not allowed for this client.   By
           default, unknown clients are allowed. */
@@ -2485,15 +2478,13 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
 
        /* If there are statements to execute when the lease is
           committed, execute them. */
-       if (lease -> on_commit && (!offer || offer == DHCPACK)) {
-               execute_statements ((struct binding_value **)0,
-                                   packet, lt, (struct client_state *)0,
-                                   packet -> options,
-                                   state -> options, &lt -> scope,
-                                   lease -> on_commit);
-               if (lease -> on_commit)
-                       executable_statement_dereference (&lease -> on_commit,
-                                                         MDL);
+       if (lease->on_star.on_commit && (!offer || offer == DHCPACK)) {
+               execute_statements (NULL, packet, lt, NULL, packet->options,
+                                   state->options, &lt->scope,
+                                   lease->on_star.on_commit, NULL);
+               if (lease->on_star.on_commit)
+                       executable_statement_dereference
+                               (&lease->on_star.on_commit, MDL);
        }
 
 #ifdef NSUPDATE
@@ -4593,13 +4584,13 @@ setup_server_source_address(struct in_addr *from,
                                        packet->options, sid_options,
                                        &global_scope,
                                        packet->shared_network->subnets->group,
-                                       NULL);
+                                       NULL, NULL);
                } else {
                        execute_statements_in_scope(NULL, packet, NULL, NULL,
                                        packet->options, sid_options,
                                        &global_scope,
                                        packet->shared_network->group,
-                                       NULL);
+                                       NULL, NULL);
                }
 
                /* do the pool if there is one */
@@ -4608,7 +4599,8 @@ setup_server_source_address(struct in_addr *from,
                                        packet->options, sid_options,
                                        &global_scope,
                                        packet->shared_network->pools->group,
-                                       packet->shared_network->group);
+                                       packet->shared_network->group,
+                                       NULL);
                }
 
                /* currently we don't bother with classes or hosts as
index 365a3d25a6d2a612a9436b3b18f201deed1bb11a..b5e11e5f67128ec8d0bb5ce4fd937d33c050c000 100644 (file)
@@ -883,14 +883,9 @@ void postconf_initialization (int quiet)
        /* Now try to get the lease file name. */
        option_state_allocate (&options, MDL);
 
-       execute_statements_in_scope ((struct binding_value **)0,
-                                    (struct packet *)0,
-                                    (struct lease *)0,
-                                    (struct client_state *)0,
-                                    (struct option_state *)0,
-                                    options, &global_scope,
-                                    root_group,
-                                    (struct group *)0);
+       execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL,
+                                   options, &global_scope, root_group,
+                                   NULL, NULL);
        memset (&db, 0, sizeof db);
        oc = lookup_option (&server_universe, options, SV_LEASE_FILE_NAME);
        if (oc &&
index 848611b997240de9db900f23bd36d91169bd28b5..0766b849983dedcafbb03f7848ae8fa33a74bfc2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2012 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2011-2013 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (C) 2006-2007,2009 by Internet Systems Consortium, Inc. ("ISC")
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -204,26 +204,16 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
                return;
        }
 
-       execute_statements_in_scope(NULL,
-                                   packet,
-                                   NULL,
-                                   NULL,
-                                   packet->options,
-                                   options,
-                                   &global_scope,
-                                   relay_group,
-                                   NULL);
+       execute_statements_in_scope(NULL, packet, NULL, NULL, packet->options,
+                                   options, &global_scope, relay_group,
+                                   NULL, NULL);
 
        for (i=packet->class_count-1; i>=0; i--) {
-               execute_statements_in_scope(NULL,
-                                           packet,
-                                           NULL,
-                                           NULL,
-                                           packet->options,
-                                           options,
+               execute_statements_in_scope(NULL, packet, NULL, NULL,
+                                           packet->options, options,
                                            &global_scope,
                                            packet->classes[i]->group,
-                                           relay_group);
+                                           relay_group, NULL);
        }
 
        /* 
@@ -1093,7 +1083,7 @@ dhcpv6_leasequery(struct data_string *reply_ret, struct packet *packet) {
        }
        execute_statements_in_scope(NULL, lq.packet, NULL, NULL,
                                    lq.packet->options, lq.reply_opts,
-                                   &global_scope, root_group, NULL);
+                                   &global_scope, root_group, NULL, NULL);
 
        lq.buf.reply.msg_type = DHCPV6_LEASEQUERY_REPLY;
 
index 210ec2dfeb0aad8079b6d6397e2bd18c228eece6..b47825f04b4d60ce786e4899cb381f3aa2567b23 100644 (file)
@@ -81,6 +81,9 @@ struct reply_state {
        /* Index into the data field that has been consumed. */
        unsigned cursor;
 
+       /* Space for the on commit statements for a fixed host */
+       struct on_star on_star;
+
        union reply_buffer {
                unsigned char data[65536];
                struct dhcpv6_packet reply;
@@ -230,7 +233,8 @@ set_server_duid_from_option(void) {
        }
 
        execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL,
-                                   opt_state, &global_scope, root_group, NULL);
+                                   opt_state, &global_scope, root_group,
+                                   NULL, NULL);
 
        oc = lookup_option(&dhcpv6_universe, opt_state, D6O_SERVERID);
        if (oc == NULL) {
@@ -820,7 +824,7 @@ start_reply(struct packet *packet,
        }
        execute_statements_in_scope(NULL, packet, NULL, NULL,
                                    packet->options, *opt_state,
-                                   &global_scope, root_group, NULL);
+                                   &global_scope, root_group, NULL, NULL);
 
        /*
         * A small bit of special handling for Solicit messages.
@@ -1405,16 +1409,18 @@ lease_to_client(struct data_string *reply_ret,
                execute_statements_in_scope(NULL, reply.packet, NULL, NULL,
                                            reply.packet->options,
                                            reply.opt_state, &global_scope,
-                                           reply.shared->group, root_group);
+                                           reply.shared->group, root_group,
+                                           NULL);
 
                /* Bring in any configuration from a host record. */
                if (reply.host != NULL)
-                       execute_statements_in_scope(NULL, reply.packet, NULL,
-                                                   NULL, reply.packet->options,
+                       execute_statements_in_scope(NULL, reply.packet,
+                                                   NULL, NULL,
+                                                   reply.packet->options,
                                                    reply.opt_state,
                                                    &global_scope,
                                                    reply.host->group,
-                                                   reply.shared->group);
+                                                   reply.shared->group, NULL);
        }
 
        /*
@@ -1841,6 +1847,19 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
                        renew_lease6(tmp->ipv6_pool, tmp);
                        schedule_lease_timeout(tmp->ipv6_pool);
 
+                       /* If we have anything to do on commit do it now */
+                       if (tmp->on_star.on_commit != NULL) {
+                               execute_statements(NULL, reply->packet,
+                                                  NULL, NULL, 
+                                                  reply->packet->options,
+                                                  reply->opt_state,
+                                                  &reply->lease->scope,
+                                                  tmp->on_star.on_commit,
+                                                  &tmp->on_star);
+                               executable_statement_dereference
+                                       (&tmp->on_star.on_commit, MDL);
+                       }
+
 #if defined (NSUPDATE)
                        /*
                         * Perform ddns updates.
@@ -1878,6 +1897,20 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
                write_ia(reply->ia);
        }
 
+       /*
+        * If this would be a hard binding for a static lease
+        * run any commit statements that we have
+        */
+       if ((status != ISC_R_CANCELED) && reply->static_lease &&
+           (reply->buf.reply.msg_type == DHCPV6_REPLY) &&
+           (reply->on_star.on_commit != NULL)) {
+               execute_statements(NULL, reply->packet, NULL, NULL, 
+                                  reply->packet->options, reply->opt_state,
+                                  NULL, reply->on_star.on_commit, NULL);
+               executable_statement_dereference
+                       (&reply->on_star.on_commit, MDL);
+       }
+
       cleanup:
        if (packet_ia != NULL)
                option_state_dereference(&packet_ia, MDL);
@@ -1897,6 +1930,12 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
                data_string_forget(&reply->fixed, MDL);
        if (reply->subnet != NULL)
                subnet_dereference(&reply->subnet, MDL);
+       if (reply->on_star.on_expiry != NULL)
+               executable_statement_dereference
+                       (&reply->on_star.on_expiry, MDL);
+       if (reply->on_star.on_release != NULL)
+               executable_statement_dereference
+                       (&reply->on_star.on_release, MDL);
 
        /*
         * ISC_R_CANCELED is a status code used by the addr processing to
@@ -2499,6 +2538,19 @@ reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) {
                        renew_lease6(tmp->ipv6_pool, tmp);
                        schedule_lease_timeout(tmp->ipv6_pool);
 
+                       /* If we have anything to do on commit do it now */
+                       if (tmp->on_star.on_commit != NULL) {
+                               execute_statements(NULL, reply->packet,
+                                                  NULL, NULL, 
+                                                  reply->packet->options,
+                                                  reply->opt_state,
+                                                  &reply->lease->scope,
+                                                  tmp->on_star.on_commit,
+                                                  &tmp->on_star);
+                               executable_statement_dereference
+                                       (&tmp->on_star.on_commit, MDL);
+                       }
+
 #if defined (NSUPDATE)
                        /*
                         * Perform ddns updates.
@@ -2832,10 +2884,38 @@ reply_process_is_addressed(struct reply_state *reply,
        isc_result_t status = ISC_R_SUCCESS;
        struct data_string data;
        struct option_cache *oc;
+       struct option_state *tmp_options = NULL;
+       struct on_star *on_star;
 
        /* Initialize values we will cleanup. */
        memset(&data, 0, sizeof(data));
 
+       /*
+        * Find the proper on_star block to use.  We use the
+        * one in the lease if we have a lease or the one in
+        * the reply if we don't have a lease because this is
+        * a static instance
+        */
+       if (reply->lease) {
+               on_star = &reply->lease->on_star;
+       } else {
+               on_star = &reply->on_star;
+       }
+
+       /*
+        * Bring in the root configuration.  We only do this to bring
+        * in the on * statements, as we didn't have the lease available
+        * we did it the first time.
+        */
+       option_state_allocate(&tmp_options, MDL);
+       execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
+                                   reply->packet->options, tmp_options,
+                                   &global_scope, root_group, NULL,
+                                   on_star);
+       if (tmp_options != NULL) {
+               option_state_dereference(&tmp_options, MDL);
+       }
+
        /*
         * Bring configured options into the root packet level cache - start
         * with the lease's closest enclosing group (passed in by the caller
@@ -2843,7 +2923,7 @@ reply_process_is_addressed(struct reply_state *reply,
         */
        execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                                    reply->packet->options, reply->opt_state,
-                                   scope, group, root_group);
+                                   scope, group, root_group, on_star);
 
        /*
         * If there is a host record, over-ride with values configured there,
@@ -2854,7 +2934,8 @@ reply_process_is_addressed(struct reply_state *reply,
                execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                                            reply->packet->options,
                                            reply->opt_state, scope,
-                                           reply->host->group, group);
+                                           reply->host->group, group,
+                                           on_star);
 
        /* Determine valid lifetime. */
        if (reply->client_valid == 0)
@@ -2960,7 +3041,7 @@ reply_process_is_addressed(struct reply_state *reply,
        /* Bring a copy of the relevant options into the IA scope. */
        execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                                    reply->packet->options, reply->reply_ia,
-                                   scope, group, root_group);
+                                   scope, group, root_group, NULL);
 
        /*
         * And bring in host record configuration, if any, but not to overlap
@@ -2970,7 +3051,7 @@ reply_process_is_addressed(struct reply_state *reply,
                execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                                            reply->packet->options,
                                            reply->reply_ia, scope,
-                                           reply->host->group, group);
+                                           reply->host->group, group, NULL);
 
       cleanup:
        if (data.data != NULL)
@@ -3368,6 +3449,19 @@ reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia) {
                        /* Commit 'hard' bindings. */
                        renew_lease6(tmp->ipv6_pool, tmp);
                        schedule_lease_timeout(tmp->ipv6_pool);
+
+                       /* If we have anything to do on commit do it now */
+                       if (tmp->on_star.on_commit != NULL) {
+                               execute_statements(NULL, reply->packet,
+                                                  NULL, NULL, 
+                                                  reply->packet->options,
+                                                  reply->opt_state,
+                                                  &reply->lease->scope,
+                                                  tmp->on_star.on_commit,
+                                                  &tmp->on_star);
+                               executable_statement_dereference
+                                       (&tmp->on_star.on_commit, MDL);
+                       }
                }
 
                /* Remove any old ia from the hash. */
@@ -3388,6 +3482,20 @@ reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia) {
                write_ia(reply->ia);
        }
 
+       /*
+        * If this would be a hard binding for a static lease
+        * run any commit statements that we have
+        */
+       if ((status != ISC_R_CANCELED) && reply->static_prefixes != 0 &&
+           (reply->buf.reply.msg_type == DHCPV6_REPLY) &&
+           (reply->on_star.on_commit != NULL)) {
+               execute_statements(NULL, reply->packet, NULL, NULL, 
+                                  reply->packet->options, reply->opt_state,
+                                  NULL, reply->on_star.on_commit, NULL);
+               executable_statement_dereference
+                       (&reply->on_star.on_commit, MDL);
+       }
+
       cleanup:
        if (packet_ia != NULL)
                option_state_dereference(&packet_ia, MDL);
@@ -3403,6 +3511,12 @@ reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia) {
                ia_dereference(&reply->old_ia, MDL);
        if (reply->lease != NULL)
                iasubopt_dereference(&reply->lease, MDL);
+       if (reply->on_star.on_expiry != NULL)
+               executable_statement_dereference
+                       (&reply->on_star.on_expiry, MDL);
+       if (reply->on_star.on_release != NULL)
+               executable_statement_dereference
+                       (&reply->on_star.on_release, MDL);
 
        /*
         * ISC_R_CANCELED is a status code used by the prefix processing to
@@ -3833,10 +3947,38 @@ reply_process_is_prefixed(struct reply_state *reply,
        isc_result_t status = ISC_R_SUCCESS;
        struct data_string data;
        struct option_cache *oc;
+       struct option_state *tmp_options = NULL;
+       struct on_star *on_star;
 
        /* Initialize values we will cleanup. */
        memset(&data, 0, sizeof(data));
 
+       /*
+        * Find the proper on_star block to use.  We use the
+        * one in the lease if we have a lease or the one in
+        * the reply if we don't have a lease because this is
+        * a static instance
+        */
+       if (reply->lease) {
+               on_star = &reply->lease->on_star;
+       } else {
+               on_star = &reply->on_star;
+       }
+
+       /*
+        * Bring in the root configuration.  We only do this to bring
+        * in the on * statements, as we didn't have the lease available
+        * we we did it the first time.
+        */
+       option_state_allocate(&tmp_options, MDL);
+       execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
+                                   reply->packet->options, tmp_options,
+                                   &global_scope, root_group, NULL,
+                                   on_star);
+       if (tmp_options != NULL) {
+               option_state_dereference(&tmp_options, MDL);
+       }
+
        /*
         * Bring configured options into the root packet level cache - start
         * with the lease's closest enclosing group (passed in by the caller
@@ -3844,7 +3986,7 @@ reply_process_is_prefixed(struct reply_state *reply,
         */
        execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                                    reply->packet->options, reply->opt_state,
-                                   scope, group, root_group);
+                                   scope, group, root_group, on_star);
 
        /*
         * If there is a host record, over-ride with values configured there,
@@ -3855,7 +3997,8 @@ reply_process_is_prefixed(struct reply_state *reply,
                execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                                            reply->packet->options,
                                            reply->opt_state, scope,
-                                           reply->host->group, group);
+                                           reply->host->group, group,
+                                           on_star);
 
        /* Determine valid lifetime. */
        if (reply->client_valid == 0)
@@ -3946,7 +4089,7 @@ reply_process_is_prefixed(struct reply_state *reply,
        /* Bring a copy of the relevant options into the IA_PD scope. */
        execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                                    reply->packet->options, reply->reply_ia,
-                                   scope, group, root_group);
+                                   scope, group, root_group, NULL);
 
        /*
         * And bring in host record configuration, if any, but not to overlap
@@ -3956,7 +4099,7 @@ reply_process_is_prefixed(struct reply_state *reply,
                execute_statements_in_scope(NULL, reply->packet, NULL, NULL,
                                            reply->packet->options,
                                            reply->reply_ia, scope,
-                                           reply->host->group, group);
+                                           reply->host->group, group, NULL);
 
       cleanup:
        if (data.data != NULL)
@@ -4683,7 +4826,7 @@ iterate_over_ia_na(struct data_string *reply_ret,
        }
        execute_statements_in_scope(NULL, packet, NULL, NULL, 
                                    packet->options, opt_state, 
-                                   &global_scope, root_group, NULL);
+                                   &global_scope, root_group, NULL, NULL);
 
        /* 
         * RFC 3315, section 18.2.7 tells us which options to include.
@@ -5197,7 +5340,7 @@ iterate_over_ia_pd(struct data_string *reply_ret,
        }
        execute_statements_in_scope(NULL, packet, NULL, NULL, 
                                    packet->options, opt_state, 
-                                   &global_scope, root_group, NULL);
+                                   &global_scope, root_group, NULL, NULL);
 
        /*
         * Loop through the IA_PD reported by the client, and deal with
index 8a7d695537285141f36c06f0526161971f1cd107..efbc8744cb1c2ac43a28cc8908fea92fe0a78051 100644 (file)
@@ -628,10 +628,9 @@ ldap_start (void)
       options = NULL;
       option_state_allocate (&options, MDL);
 
-      execute_statements_in_scope ((struct binding_value **) NULL,
-                 (struct packet *) NULL, (struct lease *) NULL,
-                 (struct client_state *) NULL, (struct option_state *) NULL,
-                 options, &global_scope, root_group, (struct group *) NULL);
+      execute_statements_in_scope (NULL, NULL, NULL, NULL, NULL
+                                  options, &global_scope, root_group,
+                                  NULL, NULL);
 
       ldap_server = _do_lookup_dhcp_string_option (options, SV_LDAP_SERVER);
       ldap_dhcp_server_cn = _do_lookup_dhcp_string_option (options,
index 4793f4ac027ac661e79177c154c6fb8905224d74..53bf34dcd2c55e86d80e3be7a89cee6055a4162b 100644 (file)
@@ -1191,28 +1191,29 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate)
        comp -> client_hostname = lease -> client_hostname;
        lease -> client_hostname = (char *)0;
 
-       if (lease -> on_expiry) {
-               if (comp -> on_expiry)
-                       executable_statement_dereference (&comp -> on_expiry,
-                                                         MDL);
-               executable_statement_reference (&comp -> on_expiry,
-                                               lease -> on_expiry,
+       if (lease->on_star.on_expiry) {
+               if (comp->on_star.on_expiry)
+                       executable_statement_dereference
+                               (&comp->on_star.on_expiry, MDL);
+               executable_statement_reference (&comp->on_star.on_expiry,
+                                               lease->on_star.on_expiry,
                                                MDL);
        }
-       if (lease -> on_commit) {
-               if (comp -> on_commit)
-                       executable_statement_dereference (&comp -> on_commit,
-                                                         MDL);
-               executable_statement_reference (&comp -> on_commit,
-                                               lease -> on_commit,
+       if (lease->on_star.on_commit) {
+               if (comp->on_star.on_commit)
+                       executable_statement_dereference
+                               (&comp->on_star.on_commit, MDL);
+               executable_statement_reference (&comp->on_star.on_commit,
+                                               lease->on_star.on_commit,
                                                MDL);
        }
-       if (lease -> on_release) {
-               if (comp -> on_release)
-                       executable_statement_dereference (&comp -> on_release,
-                                                         MDL);
-               executable_statement_reference (&comp -> on_release,
-                                               lease -> on_release, MDL);
+       if (lease->on_star.on_release) {
+               if (comp->on_star.on_release)
+                       executable_statement_dereference
+                               (&comp->on_star.on_release, MDL);
+               executable_statement_reference (&comp->on_star.on_release,
+                                               lease->on_star.on_release,
+                                               MDL);
        }
 
        /* Record the lease in the uid hash if necessary. */
@@ -1455,23 +1456,21 @@ void make_binding_state_transition (struct lease *lease)
 #if defined (NSUPDATE)
                (void) ddns_removals(lease, NULL, NULL, ISC_TRUE);
 #endif
-               if (lease -> on_expiry) {
-                       execute_statements ((struct binding_value **)0,
-                                           (struct packet *)0, lease,
-                                           (struct client_state *)0,
-                                           (struct option_state *)0,
-                                           (struct option_state *)0, /* XXX */
-                                           &lease -> scope,
-                                           lease -> on_expiry);
-                       if (lease -> on_expiry)
+               if (lease->on_star.on_expiry) {
+                       execute_statements(NULL, NULL, lease,
+                                          NULL, NULL, NULL,
+                                          &lease->scope,
+                                          lease->on_star.on_expiry,
+                                          NULL);
+                       if (lease->on_star.on_expiry)
                                executable_statement_dereference
-                                       (&lease -> on_expiry, MDL);
+                                       (&lease->on_star.on_expiry, MDL);
                }
                
                /* No sense releasing a lease after it's expired. */
-               if (lease -> on_release)
-                       executable_statement_dereference (&lease -> on_release,
-                                                         MDL);
+               if (lease->on_star.on_release)
+                       executable_statement_dereference
+                               (&lease->on_star.on_release, MDL);
                /* Get rid of client-specific bindings that are only
                   correct when the lease is active. */
                if (lease -> billing_class)
@@ -1521,22 +1520,20 @@ void make_binding_state_transition (struct lease *lease)
                 */
                (void) ddns_removals(lease, NULL, NULL, ISC_TRUE);
 #endif
-               if (lease -> on_release) {
-                       execute_statements ((struct binding_value **)0,
-                                           (struct packet *)0, lease,
-                                           (struct client_state *)0,
-                                           (struct option_state *)0,
-                                           (struct option_state *)0, /* XXX */
-                                           &lease -> scope,
-                                           lease -> on_release);
-                       executable_statement_dereference (&lease -> on_release,
-                                                         MDL);
+               if (lease->on_star.on_release) {
+                       execute_statements(NULL, NULL, lease,
+                                          NULL, NULL, NULL,
+                                          &lease->scope,
+                                          lease->on_star.on_release,
+                                          NULL);
+                       executable_statement_dereference
+                               (&lease->on_star.on_release, MDL);
                }
                
                /* A released lease can't expire. */
-               if (lease -> on_expiry)
-                       executable_statement_dereference (&lease -> on_expiry,
-                                                         MDL);
+               if (lease->on_star.on_expiry)
+                       executable_statement_dereference
+                               (&lease->on_star.on_expiry, MDL);
 
                /* Get rid of client-specific bindings that are only
                   correct when the lease is active. */
@@ -1656,17 +1653,17 @@ int lease_copy (struct lease **lp,
        class_reference (&lt -> billing_class,
                         lease -> billing_class, file, line);
        lt -> hardware_addr = lease -> hardware_addr;
-       if (lease -> on_expiry)
-               executable_statement_reference (&lt -> on_expiry,
-                                               lease -> on_expiry,
+       if (lease->on_star.on_expiry)
+               executable_statement_reference (&lt->on_star.on_expiry,
+                                               lease->on_star.on_expiry,
                                                file, line);
-       if (lease -> on_commit)
-               executable_statement_reference (&lt -> on_commit,
-                                               lease -> on_commit,
+       if (lease->on_star.on_commit)
+               executable_statement_reference (&lt->on_star.on_commit,
+                                               lease->on_star.on_commit,
                                                file, line);
-       if (lease -> on_release)
-               executable_statement_reference (&lt -> on_release,
-                                               lease -> on_release,
+       if (lease->on_star.on_release)
+               executable_statement_reference (&lt->on_star.on_release,
+                                               lease->on_star.on_release,
                                                file, line);
        lt->flags = lease->flags;
        lt->tstp = lease->tstp;
@@ -1691,31 +1688,31 @@ void release_lease (lease, packet)
 #if defined (NSUPDATE)
        (void) ddns_removals(lease, NULL, NULL, ISC_FALSE);
 #endif
-       if (lease -> on_release) {
-               execute_statements ((struct binding_value **)0,
-                                   packet, lease, (struct client_state *)0,
-                                   packet -> options,
-                                   (struct option_state *)0, /* XXX */
-                                   &lease -> scope, lease -> on_release);
-               if (lease -> on_release)
-                       executable_statement_dereference (&lease -> on_release,
-                                                         MDL);
+       if (lease->on_star.on_release) {
+               execute_statements (NULL, packet, lease,
+                                   NULL, packet->options,
+                                   NULL, &lease->scope,
+                                   lease->on_star.on_release, NULL);
+               if (lease->on_star.on_release)
+                       executable_statement_dereference
+                               (&lease->on_star.on_release, MDL);
        }
 
        /* We do either the on_release or the on_expiry events, but
           not both (it's possible that they could be the same,
           in any case). */
-       if (lease -> on_expiry)
-               executable_statement_dereference (&lease -> on_expiry, MDL);
+       if (lease->on_star.on_expiry)
+               executable_statement_dereference
+                       (&lease->on_star.on_expiry, MDL);
 
        if (lease -> binding_state != FTS_FREE &&
            lease -> binding_state != FTS_BACKUP &&
            lease -> binding_state != FTS_RELEASED &&
            lease -> binding_state != FTS_EXPIRED &&
            lease -> binding_state != FTS_RESET) {
-               if (lease -> on_commit)
-                       executable_statement_dereference (&lease -> on_commit,
-                                                         MDL);
+               if (lease->on_star.on_commit)
+                       executable_statement_dereference
+                               (&lease->on_star.on_commit, MDL);
 
                /* Blow away any bindings. */
                if (lease -> scope)
index 0e76264cda66ec4492fe8a381e1f2c18746f4be7..b98db42889d5fd68068d75aecb2b23345fd2ff02 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2012 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2007-2013 by Internet Systems Consortium, Inc. ("ISC")
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -197,6 +197,20 @@ iasubopt_dereference(struct iasubopt **iasubopt, const char *file, int line) {
                if (tmp->scope != NULL) {
                        binding_scope_dereference(&tmp->scope, file, line);
                }
+
+               if (tmp->on_star.on_expiry != NULL) {
+                       executable_statement_dereference
+                               (&tmp->on_star.on_expiry, MDL);
+               }
+               if (tmp->on_star.on_commit != NULL) {
+                       executable_statement_dereference
+                               (&tmp->on_star.on_commit, MDL);
+               }
+               if (tmp->on_star.on_release != NULL) {
+                       executable_statement_dereference
+                               (&tmp->on_star.on_release, MDL);
+               }
+
                dfree(tmp, file, line);
        }
 
@@ -1309,6 +1323,38 @@ move_lease_to_inactive(struct ipv6_pool *pool, struct iasubopt *lease,
        old_heap_index = lease->heap_index;
        insert_result = isc_heap_insert(pool->inactive_timeouts, lease);
        if (insert_result == ISC_R_SUCCESS) {
+               /*
+                * Handle expire and release statements
+                * To get here we must be active and have done a commit so
+                * we should run the proper statements if they exist, though
+                * that will change when we remove the inactive heap.
+                * In addition we get rid of the references for both as we
+                * can only do one (expire or release) on a lease
+                */
+               if (lease->on_star.on_expiry != NULL) {
+                       if (state == FTS_EXPIRED) {
+                               execute_statements(NULL, NULL, NULL,
+                                                  NULL, NULL, NULL,
+                                                  &lease->scope,
+                                                  lease->on_star.on_expiry,
+                                                  &lease->on_star);
+                       }
+                       executable_statement_dereference
+                               (&lease->on_star.on_expiry, MDL);
+               }
+
+               if (lease->on_star.on_release != NULL) {
+                       if (state == FTS_RELEASED) {
+                               execute_statements(NULL, NULL, NULL,
+                                                  NULL, NULL, NULL,
+                                                  &lease->scope,
+                                                  lease->on_star.on_release,
+                                                  &lease->on_star);
+                       }
+                       executable_statement_dereference
+                               (&lease->on_star.on_release, MDL);
+               }
+
 #if defined (NSUPDATE)
                /* Process events upon expiration. */
                if (pool->pool_type != D6O_IA_PD) {
index 3ecf6a776cdf7a901b226321b931dc24f9702447..7e17ed5534828558571bbb7771d52de840bb126f 100644 (file)
@@ -408,71 +408,71 @@ isc_result_t dhcp_lease_destroy (omapi_object_t *h, const char *file, int line)
 {
        struct lease *lease;
 
-       if (h -> type != dhcp_type_lease)
+       if (h->type != dhcp_type_lease)
                return DHCP_R_INVALIDARG;
        lease = (struct lease *)h;
 
-       if (lease -> uid)
+       if (lease-> uid)
                uid_hash_delete (lease);
        hw_hash_delete (lease);
 
-       if (lease -> on_release)
-               executable_statement_dereference (&lease -> on_release,
+       if (lease->on_star.on_release)
+               executable_statement_dereference (&lease->on_star.on_release,
                                                  file, line);
-       if (lease -> on_expiry)
-               executable_statement_dereference (&lease -> on_expiry,
+       if (lease->on_star.on_expiry)
+               executable_statement_dereference (&lease->on_star.on_expiry,
                                                  file, line);
-       if (lease -> on_commit)
-               executable_statement_dereference (&lease -> on_commit,
+       if (lease->on_star.on_commit)
+               executable_statement_dereference (&lease->on_star.on_commit,
                                                  file, line);
-       if (lease -> scope)
-               binding_scope_dereference (&lease -> scope, file, line);
+       if (lease->scope)
+               binding_scope_dereference (&lease->scope, file, line);
 
-       if (lease -> agent_options)
-               option_chain_head_dereference (&lease -> agent_options,
+       if (lease->agent_options)
+               option_chain_head_dereference (&lease->agent_options,
                                               file, line);
-       if (lease -> uid && lease -> uid != lease -> uid_buf) {
-               dfree (lease -> uid, MDL);
-               lease -> uid = &lease -> uid_buf [0];
-               lease -> uid_len = 0;
+       if (lease->uid && lease->uid != lease->uid_buf) {
+               dfree (lease->uid, MDL);
+               lease->uid = &lease->uid_buf [0];
+               lease->uid_len = 0;
        }
 
-       if (lease -> client_hostname) {
-               dfree (lease -> client_hostname, MDL);
-               lease -> client_hostname = (char *)0;
+       if (lease->client_hostname) {
+               dfree (lease->client_hostname, MDL);
+               lease->client_hostname = (char *)0;
        }
 
-       if (lease -> host)
-               host_dereference (&lease -> host, file, line);
-       if (lease -> subnet)
-               subnet_dereference (&lease -> subnet, file, line);
-       if (lease -> pool)
-               pool_dereference (&lease -> pool, file, line);
+       if (lease->host)
+               host_dereference (&lease->host, file, line);
+       if (lease->subnet)
+               subnet_dereference (&lease->subnet, file, line);
+       if (lease->pool)
+               pool_dereference (&lease->pool, file, line);
 
-       if (lease -> state) {
-               free_lease_state (lease -> state, file, line);
-               lease -> state = (struct lease_state *)0;
+       if (lease->state) {
+               free_lease_state (lease->state, file, line);
+               lease->state = (struct lease_state *)0;
 
                cancel_timeout (lease_ping_timeout, lease);
                --outstanding_pings; /* XXX */
        }
 
-       if (lease -> billing_class)
+       if (lease->billing_class)
                class_dereference
-                       (&lease -> billing_class, file, line);
+                       (&lease->billing_class, file, line);
 
 #if defined (DEBUG_MEMORY_LEAKAGE) || \
                defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
        /* XXX we should never be destroying a lease with a next
           XXX pointer except on exit... */
-       if (lease -> next)
-               lease_dereference (&lease -> next, file, line);
-       if (lease -> n_hw)
-               lease_dereference (&lease -> n_hw, file, line);
-       if (lease -> n_uid)
-               lease_dereference (&lease -> n_uid, file, line);
-       if (lease -> next_pending)
-               lease_dereference (&lease -> next_pending, file, line);
+       if (lease->next)
+               lease_dereference (&lease->next, file, line);
+       if (lease->n_hw)
+               lease_dereference (&lease->n_hw, file, line);
+       if (lease->n_uid)
+               lease_dereference (&lease->n_uid, file, line);
+       if (lease->next_pending)
+               lease_dereference (&lease->next_pending, file, line);
 #endif
 
        return ISC_R_SUCCESS;