mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-09-03 07:45:20 +00:00
Fixed a bug parsing ipv6 addresses in host-identifier statements. [rt16860]
This commit is contained in:
2
RELNOTES
2
RELNOTES
@@ -85,6 +85,8 @@ suggested fixes to <dhcp-users@isc.org>.
|
|||||||
- All binaries (client, server, relay) now change directories
|
- All binaries (client, server, relay) now change directories
|
||||||
to / before going into daemon mode, so as not to hold $CWD open
|
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
|
Changes since 4.0.0-20070413
|
||||||
|
|
||||||
- Old (expired) leases are now cleaned.
|
- Old (expired) leases are now cleaned.
|
||||||
|
161
common/parse.c
161
common/parse.c
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char copyright[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -3351,7 +3351,6 @@ int parse_non_binary (expr, cfile, lose, context)
|
|||||||
enum expr_op opcode;
|
enum expr_op opcode;
|
||||||
const char *s;
|
const char *s;
|
||||||
char *cptr;
|
char *cptr;
|
||||||
struct executable_statement *stmt;
|
|
||||||
int i;
|
int i;
|
||||||
unsigned long u;
|
unsigned long u;
|
||||||
isc_result_t status, code;
|
isc_result_t status, code;
|
||||||
@@ -4823,6 +4822,83 @@ int parse_expression (expr, cfile, lose, context, plhs, binop)
|
|||||||
goto new_rhs;
|
goto new_rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int parse_option_data (expr, cfile, lookups, option)
|
||||||
|
struct expression **expr;
|
||||||
|
struct parse *cfile;
|
||||||
|
int lookups;
|
||||||
|
struct option *option;
|
||||||
|
{
|
||||||
|
const char *val;
|
||||||
|
const char *fmt = NULL;
|
||||||
|
struct expression *tmp;
|
||||||
|
enum dhcp_token token;
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
int uniform = option -> format [1] == 'A';
|
||||||
|
|
||||||
|
and_again:
|
||||||
|
/* Set fmt to start of format for 'A' and one char back
|
||||||
|
* for 'a'.
|
||||||
|
*/
|
||||||
|
if ((fmt != NULL) && (fmt != option->format) && (*fmt == 'a'))
|
||||||
|
fmt -= 1;
|
||||||
|
else if ((fmt == NULL) || (*fmt == 'A'))
|
||||||
|
fmt = option->format;
|
||||||
|
|
||||||
|
/* 'a' means always uniform */
|
||||||
|
uniform |= (fmt [1] == 'a');
|
||||||
|
|
||||||
|
for ( ; *fmt; fmt++) {
|
||||||
|
if ((*fmt == 'A') || (*fmt == 'a'))
|
||||||
|
break;
|
||||||
|
if (*fmt == 'o')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
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 = NULL;
|
||||||
|
}
|
||||||
|
if (tmp)
|
||||||
|
expression_dereference (&tmp, MDL);
|
||||||
|
}
|
||||||
|
if ((*fmt == 'A') || (*fmt == 'a')) {
|
||||||
|
token = peek_token (&val, (unsigned *)0, cfile);
|
||||||
|
/* Comma means: continue with next element in array */
|
||||||
|
if (token == COMMA) {
|
||||||
|
token = next_token (&val,
|
||||||
|
(unsigned *)0, cfile);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* no comma: end of array.
|
||||||
|
'A' or end of string means: leave the loop */
|
||||||
|
if ((*fmt == 'A') || (fmt[1] == '\0'))
|
||||||
|
break;
|
||||||
|
/* 'a' means: go on with next char */
|
||||||
|
if (*fmt == 'a') {
|
||||||
|
fmt++;
|
||||||
|
goto and_again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while ((*fmt == 'A') || (*fmt == 'a'));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* option-statement :== identifier DOT identifier <syntax> SEMI
|
/* option-statement :== identifier DOT identifier <syntax> SEMI
|
||||||
| identifier <syntax> SEMI
|
| identifier <syntax> SEMI
|
||||||
|
|
||||||
@@ -4839,11 +4915,8 @@ int parse_option_statement (result, cfile, lookups, option, op)
|
|||||||
{
|
{
|
||||||
const char *val;
|
const char *val;
|
||||||
enum dhcp_token token;
|
enum dhcp_token token;
|
||||||
const char *fmt = NULL;
|
|
||||||
struct expression *expr = (struct expression *)0;
|
struct expression *expr = (struct expression *)0;
|
||||||
struct expression *tmp;
|
|
||||||
int lose;
|
int lose;
|
||||||
struct executable_statement *stmt;
|
|
||||||
int ftt = 1;
|
int ftt = 1;
|
||||||
|
|
||||||
token = peek_token (&val, (unsigned *)0, cfile);
|
token = peek_token (&val, (unsigned *)0, cfile);
|
||||||
@@ -4875,76 +4948,23 @@ int parse_option_statement (result, cfile, lookups, option, op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parse the option data... */
|
/* Parse the option data... */
|
||||||
do {
|
if (! parse_option_data(&expr, cfile, lookups, option))
|
||||||
/* Set a flag if this is an array of a simple type (i.e.,
|
return 0;
|
||||||
not an array of pairs of IP addresses, or something
|
|
||||||
like that. */
|
|
||||||
int uniform = option -> format [1] == 'A';
|
|
||||||
|
|
||||||
and_again:
|
|
||||||
/* Set fmt to start of format for 'A' and one char back
|
|
||||||
* for 'a'.
|
|
||||||
*/
|
|
||||||
if ((fmt != NULL) && (fmt != option->format) && (*fmt == 'a'))
|
|
||||||
fmt -= 1;
|
|
||||||
else if ((fmt == NULL) || (*fmt == 'A'))
|
|
||||||
fmt = option->format;
|
|
||||||
|
|
||||||
/* 'a' means always uniform */
|
|
||||||
uniform |= (fmt [1] == 'a');
|
|
||||||
|
|
||||||
for ( ; *fmt; fmt++) {
|
|
||||||
if ((*fmt == 'A') || (*fmt == 'a'))
|
|
||||||
break;
|
|
||||||
if (*fmt == 'o')
|
|
||||||
continue;
|
|
||||||
tmp = expr;
|
|
||||||
expr = (struct expression *)0;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
if (tmp)
|
|
||||||
expression_dereference (&tmp, MDL);
|
|
||||||
}
|
|
||||||
if ((*fmt == 'A') || (*fmt == 'a')) {
|
|
||||||
token = peek_token (&val, (unsigned *)0, cfile);
|
|
||||||
/* Comma means: continue with next element in array */
|
|
||||||
if (token == COMMA) {
|
|
||||||
token = next_token (&val,
|
|
||||||
(unsigned *)0, cfile);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* no comma: end of array.
|
|
||||||
'A' or end of string means: leave the loop */
|
|
||||||
if ((*fmt == 'A') || (fmt[1] == '\0'))
|
|
||||||
break;
|
|
||||||
/* 'a' means: go on with next char */
|
|
||||||
if (*fmt == 'a') {
|
|
||||||
fmt++;
|
|
||||||
goto and_again;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while ((*fmt == 'A') || (*fmt == 'a'));
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (!parse_semi (cfile))
|
if (!parse_semi (cfile))
|
||||||
return 0;
|
return 0;
|
||||||
if (!executable_statement_allocate (result, MDL))
|
if (!executable_statement_allocate (result, MDL))
|
||||||
log_fatal ("no memory for option statement.");
|
log_fatal ("no memory for option statement.");
|
||||||
(*result) -> op = op;
|
|
||||||
if (expr && !option_cache (&(*result) -> data.option,
|
(*result)->op = op;
|
||||||
(struct data_string *)0, expr, option, MDL))
|
if (expr && !option_cache (&(*result)->data.option,
|
||||||
|
NULL, expr, option, MDL))
|
||||||
log_fatal ("no memory for option cache");
|
log_fatal ("no memory for option cache");
|
||||||
|
|
||||||
if (expr)
|
if (expr)
|
||||||
expression_dereference (&expr, MDL);
|
expression_dereference (&expr, MDL);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5010,11 +5030,12 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
|
|||||||
(const unsigned char *)val,
|
(const unsigned char *)val,
|
||||||
len, 1, 1, MDL))
|
len, 1, 1, MDL))
|
||||||
log_fatal ("No memory for \"%s\"", val);
|
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 {
|
} else {
|
||||||
|
if ((*fmt) [1] != 'o') {
|
||||||
|
parse_warn (cfile, "expecting string "
|
||||||
|
"or hexadecimal data.");
|
||||||
|
skip_to_semi (cfile);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char copyright[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
@@ -1733,8 +1733,7 @@ void parse_host_declaration (cfile, group)
|
|||||||
isc_result_t status;
|
isc_result_t status;
|
||||||
int known;
|
int known;
|
||||||
struct option *option;
|
struct option *option;
|
||||||
struct expression *expr;
|
struct expression *expr = NULL;
|
||||||
const char *tmp_format;
|
|
||||||
|
|
||||||
name = parse_host_name (cfile);
|
name = parse_host_name (cfile);
|
||||||
if (!name) {
|
if (!name) {
|
||||||
@@ -1867,6 +1866,7 @@ void parse_host_declaration (cfile, group)
|
|||||||
break;
|
break;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token == HOST_IDENTIFIER) {
|
if (token == HOST_IDENTIFIER) {
|
||||||
if (host->host_id_option != NULL) {
|
if (host->host_id_option != NULL) {
|
||||||
parse_warn(cfile,
|
parse_warn(cfile,
|
||||||
@@ -1897,33 +1897,12 @@ void parse_host_declaration (cfile, group)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: we're always using "lookups" */
|
if (! parse_option_data(&expr, cfile, 1, option)) {
|
||||||
expr = NULL;
|
skip_to_rbrace(cfile, 1);
|
||||||
tmp_format = option->format;
|
option_dereference(&option, MDL);
|
||||||
/*
|
break;
|
||||||
* 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_semi(cfile)) {
|
if (!parse_semi(cfile)) {
|
||||||
skip_to_rbrace(cfile, 1);
|
skip_to_rbrace(cfile, 1);
|
||||||
expression_dereference(&expr, MDL);
|
expression_dereference(&expr, MDL);
|
||||||
@@ -1939,9 +1918,8 @@ void parse_host_declaration (cfile, group)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
declaration = parse_statement (cfile, host -> group,
|
declaration = parse_statement(cfile, host->group, HOST_DECL,
|
||||||
HOST_DECL, host,
|
host, declaration);
|
||||||
declaration);
|
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
|
Reference in New Issue
Block a user