]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Fixed a bug parsing ipv6 addresses in host-identifier statements. [rt16860]
authorEvan Hunt <each@isc.org>
Wed, 27 Jun 2007 18:25:15 +0000 (18:25 +0000)
committerEvan Hunt <each@isc.org>
Wed, 27 Jun 2007 18:25:15 +0000 (18:25 +0000)
RELNOTES
common/parse.c
server/confpars.c

index d018275f2a0b325b9beb0f403fe367a949d9dd60..57e691595fc40ebca578f6e897ccafdcfbce94cf 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -85,6 +85,8 @@ suggested fixes to <dhcp-users@isc.org>.
 - All binaries (client, server, relay) now change directories
   to / before going into daemon mode, so as not to hold $CWD open
 
+- Fixed a bug parsing DHCPv6 client-id's in host-identifier statements
+
                        Changes since 4.0.0-20070413
 
 - Old (expired) leases are now cleaned.
index 59297492ccdb522d9e6c48a33d8087c19ba0c0f3..f418bb358ed723a3a379bee0be2e3eaac065f2ee 100644 (file)
@@ -34,7 +34,7 @@
 
 #ifndef lint
 static char copyright[] =
-"$Id: parse.c,v 1.128 2007/06/20 10:38:55 shane Exp $ Copyright (c) 2004-2007 Internet Systems Consortium.  All rights reserved.\n";
+"$Id: parse.c,v 1.129 2007/06/27 18:25:15 each Exp $ Copyright (c) 2004-2007 Internet Systems Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -3351,7 +3351,6 @@ int parse_non_binary (expr, cfile, lose, context)
        enum expr_op opcode;
        const char *s;
        char *cptr;
-       struct executable_statement *stmt;
        int i;
        unsigned long u;
        isc_result_t status, code;
@@ -4823,62 +4822,24 @@ int parse_expression (expr, cfile, lose, context, plhs, binop)
        goto new_rhs;
 }      
 
-/* option-statement :== identifier DOT identifier <syntax> SEMI
-                     | identifier <syntax> SEMI
 
-   Option syntax is handled specially through format strings, so it
-   would be painful to come up with BNF for it.   However, it always
-   starts as above and ends in a SEMI. */
-
-int parse_option_statement (result, cfile, lookups, option, op)
-       struct executable_statement **result;
-       struct parse *cfile;
-       int lookups;
-       struct option *option;
-       enum statement_op op;
+int parse_option_data (expr, cfile, lookups, option)
+struct expression **expr;
+struct parse *cfile;
+int lookups;
+struct option *option;
 {
        const char *val;
-       enum dhcp_token token;
        const char *fmt = NULL;
-       struct expression *expr = (struct expression *)0;
        struct expression *tmp;
-       int lose;
-       struct executable_statement *stmt;
-       int ftt = 1;
-
-       token = peek_token (&val, (unsigned *)0, cfile);
-       if (token == SEMI) {
-               /* Eat the semicolon... */
-               token = next_token (&val, (unsigned *)0, cfile);
-               goto done;
-       }
-
-       if (token == EQUAL) {
-               /* Eat the equals sign. */
-               token = next_token (&val, (unsigned *)0, cfile);
-
-               /* Parse a data expression and use its value for the data. */
-               if (!parse_data_expression (&expr, cfile, &lose)) {
-                       /* In this context, we must have an executable
-                          statement, so if we found something else, it's
-                          still an error. */
-                       if (!lose) {
-                               parse_warn (cfile,
-                                           "expecting a data expression.");
-                               skip_to_semi (cfile);
-                       }
-                       return 0;
-               }
-
-               /* We got a valid expression, so use it. */
-               goto done;
-       }
+       enum dhcp_token token;
 
-       /* Parse the option data... */
        do {
-               /* Set a flag if this is an array of a simple type (i.e.,
-                  not an array of pairs of IP addresses, or something
-                  like that. */
+               /*
+                 * Set a flag if this is an array of a simple type (i.e.,
+                 * not an array of pairs of IP addresses, or something like
+                 * that.
+                 */
                int uniform = option -> format [1] == 'A';
 
              and_again:
@@ -4898,20 +4859,21 @@ int parse_option_statement (result, cfile, lookups, option, op)
                                break;
                        if (*fmt == 'o')
                                continue;
-                       tmp = expr;
-                       expr = (struct expression *)0;
-                       if (!parse_option_token (&expr, cfile, &fmt,
-                                                tmp, uniform, lookups)) {
+
+                       tmp = *expr;
+                       *expr = NULL;
+                       if (!parse_option_token(expr, cfile, &fmt, tmp,
+                                                uniform, lookups)) {
                                if (fmt [1] != 'o') {
                                        if (tmp)
                                                expression_dereference (&tmp,
                                                                        MDL);
                                        return 0;
                                }
-                               expr = tmp;
-                               tmp = (struct expression *)0;
+                               *expr = tmp;
+                               tmp = NULL;
                        }
-                       if (tmp)
+                        if (tmp)
                                expression_dereference (&tmp, MDL);
                }
                if ((*fmt == 'A') || (*fmt == 'a')) {
@@ -4934,17 +4896,75 @@ int parse_option_statement (result, cfile, lookups, option, op)
                }
        } while ((*fmt == 'A') || (*fmt == 'a'));
 
+        return 1;
+}
+
+/* option-statement :== identifier DOT identifier <syntax> SEMI
+                     | identifier <syntax> SEMI
+
+   Option syntax is handled specially through format strings, so it
+   would be painful to come up with BNF for it.   However, it always
+   starts as above and ends in a SEMI. */
+
+int parse_option_statement (result, cfile, lookups, option, op)
+       struct executable_statement **result;
+       struct parse *cfile;
+       int lookups;
+       struct option *option;
+       enum statement_op op;
+{
+       const char *val;
+       enum dhcp_token token;
+       struct expression *expr = (struct expression *)0;
+       int lose;
+       int ftt = 1;
+
+       token = peek_token (&val, (unsigned *)0, cfile);
+       if (token == SEMI) {
+               /* Eat the semicolon... */
+               token = next_token (&val, (unsigned *)0, cfile);
+               goto done;
+       }
+
+       if (token == EQUAL) {
+               /* Eat the equals sign. */
+               token = next_token (&val, (unsigned *)0, cfile);
+
+               /* Parse a data expression and use its value for the data. */
+               if (!parse_data_expression (&expr, cfile, &lose)) {
+                       /* In this context, we must have an executable
+                          statement, so if we found something else, it's
+                          still an error. */
+                       if (!lose) {
+                               parse_warn (cfile,
+                                           "expecting a data expression.");
+                               skip_to_semi (cfile);
+                       }
+                       return 0;
+               }
+
+               /* We got a valid expression, so use it. */
+               goto done;
+       }
+
+       /* Parse the option data... */
+        if (! parse_option_data(&expr, cfile, lookups, option))
+                return 0;
+
       done:
        if (!parse_semi (cfile))
                return 0;
        if (!executable_statement_allocate (result, MDL))
                log_fatal ("no memory for option statement.");
-       (*result) -> op = op;
-       if (expr && !option_cache (&(*result) -> data.option,
-                                  (struct data_string *)0, expr, option, MDL))
+
+        (*result)->op = op;
+       if (expr && !option_cache (&(*result)->data.option,
+                                  NULL, expr, option, MDL))
                log_fatal ("no memory for option cache");
+
        if (expr)
                expression_dereference (&expr, MDL);
+
        return 1;
 }
 
@@ -5010,11 +5030,12 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
                                                (const unsigned char *)val,
                                                        len, 1, 1, MDL))
                                        log_fatal ("No memory for \"%s\"", val);
-                       } else if ((*fmt) [1] != 'o') {
-                               parse_warn (cfile, "expecting string %s.",
-                                           "or hexadecimal data");
-                               skip_to_semi (cfile);
                        } else {
+                                if ((*fmt) [1] != 'o') {
+                                       parse_warn (cfile, "expecting string "
+                                                   "or hexadecimal data.");
+                                       skip_to_semi (cfile);
+                                }
                                return 0;
                        }
                }
index 383619202bc65f36fa64ea819c24974c93f5866f..90eb546ceded49ddcaa48487fd09605377fd4d36 100644 (file)
@@ -34,7 +34,7 @@
 
 #ifndef lint
 static char copyright[] =
-"$Id: confpars.c,v 1.168 2007/06/19 17:06:03 shane Exp $ Copyright (c) 2004-2007 Internet Systems Consortium.  All rights reserved.\n";
+"$Id: confpars.c,v 1.169 2007/06/27 18:25:15 each Exp $ Copyright (c) 2004-2007 Internet Systems Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
@@ -1733,8 +1733,7 @@ void parse_host_declaration (cfile, group)
        isc_result_t status;
        int known;
        struct option *option;
-       struct expression *expr;
-       const char *tmp_format;
+       struct expression *expr = NULL;
 
        name = parse_host_name (cfile);
        if (!name) {
@@ -1867,6 +1866,7 @@ void parse_host_declaration (cfile, group)
                                break;
                        continue;
                }
+
                if (token == HOST_IDENTIFIER) {
                        if (host->host_id_option != NULL) {
                                parse_warn(cfile,
@@ -1897,33 +1897,12 @@ void parse_host_declaration (cfile, group)
                                break;
                        }
 
-                       /* XXX: we're always using "lookups" */
-                       expr = NULL;
-                       tmp_format = option->format;
-                       /* 
-                        * XXX: using parse_option_token() is not ideal here,
-                        *      as it does not handle things like arrays and
-                        *      such. 
-                        */
-                       if (!parse_option_token(&expr, cfile, &tmp_format,
-                                               NULL, 1, 1)) {
-                               skip_to_rbrace(cfile, 1);
-                               option_dereference(&option, MDL);
-                               break;
-                       }
-
-                       /* I think this is guaranteed, but a check
-                          won't hurt. -Shane */
-                       if (expr->op != expr_const_data) {
-                               parse_warn(cfile, 
-                                          "options for host-identifier "
-                                          "must have a constant value");
-                               skip_to_rbrace(cfile, 1);
-                               expression_dereference(&expr, MDL);
-                               option_dereference(&option, MDL);
-                               break;
-                       }
-
+                        if (! parse_option_data(&expr, cfile, 1, option)) {
+                               skip_to_rbrace(cfile, 1);
+                               option_dereference(&option, MDL);
+                               break;
+                        }
+                        
                        if (!parse_semi(cfile)) {
                                skip_to_rbrace(cfile, 1);
                                expression_dereference(&expr, MDL);
@@ -1939,9 +1918,8 @@ void parse_host_declaration (cfile, group)
                        continue;
                }
 
-               declaration = parse_statement (cfile, host -> group,
-                                              HOST_DECL, host,
-                                              declaration);
+               declaration = parse_statement(cfile, host->group, HOST_DECL,
+                                              host, declaration);
        } while (1);
 
        if (deleted) {