#ifndef lint
static char copyright[] =
-"$Id: confpars.c,v 1.95 2000/01/08 01:43:52 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
+"$Id: confpars.c,v 1.96 2000/01/25 01:38:17 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
int declaration = 0;
int status;
- /* Set up the initial dhcp option universe. */
- initialize_common_option_spaces ();
- initialize_server_option_spaces ();
-
- root_group.authoritative = 0;
-
if ((file = open (path_dhcpd_conf, O_RDONLY)) < 0)
log_fatal ("Can't open %s: %m", path_dhcpd_conf);
enter_lease (lease);
if (lease -> on_expiry)
executable_statement_dereference
- (&lease -> on_expiry,
- "read_leases");
+ (&lease -> on_expiry, MDL);
if (lease -> on_commit)
executable_statement_dereference
- (&lease -> on_commit,
- "read_leases");
+ (&lease -> on_commit, MDL);
if (lease -> on_release)
executable_statement_dereference
- (&lease -> on_release,
- "read_leases");
+ (&lease -> on_release, MDL);
} else
parse_warn (cfile,
"possibly corrupt lease file");
if (parse_auth_key (&key_id, cfile)) {
if (type == HOST_DECL)
data_string_copy (&host_decl -> auth_key_id,
- &key_id, "parse_statement");
- data_string_forget (&key_id, "parse_statement");
+ &key_id, MDL);
+ data_string_forget (&key_id, MDL);
}
break;
case HOST:
/* Otherwise, cons up a fake shared network structure
and populate it with the lone subnet... */
- share = new_shared_network ("parse_statement");
+ share = new_shared_network (MDL);
if (!share)
log_fatal ("No memory for shared subnet");
- share -> group = clone_group (group, "parse_statement:subnet");
+ share -> group = clone_group (group, MDL);
share -> group -> shared_network = share;
parse_subnet_declaration (cfile, share);
/* Make the shared network name from network number. */
n = piaddr (share -> subnets -> net);
- t = malloc (strlen (n) + 1);
+ t = dmalloc (strlen (n) + 1, MDL);
if (!t)
log_fatal ("no memory for subnet name");
strcpy (t, n);
else {
parse_warn (cfile, "fixed-address parameter not %s",
"allowed here.");
- option_cache_dereference (&cache, "parse_statement");
+ option_cache_dereference (&cache, MDL);
}
break;
if (type != ROOT_GROUP) {
parse_warn (cfile,
"option space definitions %s",
- " may not be scoped.");
+ "may not be scoped.");
skip_to_semi (cfile);
- free_option (option, "parse_statement");
+ free_option (option, MDL);
break;
}
parse_option_space_decl (cfile);
"option definitions%s",
" may not be scoped.");
skip_to_semi (cfile);
- free_option (option,
- "parse_statement");
+ free_option (option, MDL);
break;
}
next_token (&val, cfile);
if (!parse_option_code_definition (cfile,
option))
- free_option (option,
- "parse_statement");
+ free_option (option, MDL);
return declaration;
}
option -> universe -> name,
option -> name);
skip_to_semi (cfile);
- free_option (option, "parse_statement");
+ free_option (option, MDL);
return declaration;
}
if (ep -> refcnt > 1) /* XXX */
multi = 1;
if (!multi) {
- executable_statement_reference
- (&ep -> next, et, "parse_statement");
+ executable_statement_reference (&ep -> next,
+ et, MDL);
return declaration;
}
current group statements first and the new
statement in the next pointer. */
ep = (struct executable_statement *)0;
- if (!executable_statement_allocate
- (&ep, "parse_statement"))
+ if (!executable_statement_allocate (&ep, MDL))
log_fatal ("No memory for statements.");
ep -> op = statements_statement;
- executable_statement_reference
- (&ep -> data.statements,
- group -> statements, "parse_statement");
- executable_statement_reference
- (&ep -> next, et, "parse_statement");
- executable_statement_dereference
- (&group -> statements, "parse_statement");
- executable_statement_reference
- (&group -> statements, ep, "parse_statements");
+ executable_statement_reference (&ep -> data.statements,
+ group -> statements,
+ MDL);
+ executable_statement_reference (&ep -> next, et, MDL);
+ executable_statement_dereference (&group -> statements,
+ MDL);
+ executable_statement_reference (&group -> statements,
+ ep, MDL);
} else
- executable_statement_reference
- (&group -> statements, et, "parse_statements");
+ executable_statement_reference (&group -> statements,
+ et, MDL);
return declaration;
}
token = next_token (&val, cfile);
if (is_identifier (token) || token == STRING) {
- name = dmalloc (strlen (val) + 1, "peer name");
+ name = dmalloc (strlen (val) + 1, MDL);
if (!name)
log_fatal ("no memory for peer name %s", name);
strcpy (name, val);
token = next_token (&val, cfile);
if (token == SEMI) {
- dfree (name, "peer name");
+ dfree (name, MDL);
if (type != SHARED_NET_DECL)
parse_warn (cfile, "failover peer reference not %s",
"in shared-network declaration");
option_cache (&peer -> address,
(struct data_string *)0, expr,
(struct option *)0);
- expression_dereference (&expr,
- "parse_failover_peer");
+ expression_dereference (&expr, MDL);
break;
case PORT:
token = next_token (&val, cfile);
}
parse_semi (cfile);
make_hba:
- peer -> hba = dmalloc (32, "parse_failover_peer");
+ peer -> hba = dmalloc (32, MDL);
if (!peer -> hba) {
- dfree (peer -> name, "parse_failover_peer");
- dfree (peer, "parse_failover_peer");
+ dfree (peer -> name, MDL);
+ dfree (peer, MDL);
}
memcpy (peer -> hba, hba, 32);
break;
struct permit **permit_head;
int declaration = 0;
- pool = new_pool ("parse_pool_statement");
+ pool = new_pool (MDL);
if (!pool)
log_fatal ("no memory for pool.");
- pool -> group = clone_group (group, "parse_pool_statement");
+ pool -> group = clone_group (group, MDL);
if (type == SUBNET_DECL)
pool -> shared_network = group -> subnet -> shared_network;
&pool -> failover_peer,
(omapi_object_t *)
pool -> shared_network -> failover_peer,
- "parse_pool_statement");
+ MDL);
#endif
if (!parse_lbrace (cfile))
if (pool -> failover_peer)
omapi_object_dereference
((omapi_object_t **)
- &pool -> failover_peer,
- "parse_pool_statement");
+ &pool -> failover_peer, MDL);
/* XXX Flag error if there's no failover peer? */
#endif
break;
case ALLOW:
permit_head = &pool -> permit_list;
get_permit:
- permit = new_permit ("parse_pool_statement");
+ permit = new_permit (MDL);
if (!permit)
log_fatal ("no memory for permit");
next_token (&val, cfile);
parse_warn (cfile,
"expecting \"clients\"");
skip_to_semi (cfile);
- free_permit (permit,
- "parse_pool_statement");
+ free_permit (permit, MDL);
continue;
}
break;
parse_warn (cfile,
"expecting \"bootp\"");
skip_to_semi (cfile);
- free_permit (permit,
- "parse_pool_statement");
+ free_permit (permit, MDL);
continue;
}
goto get_clients;
if (next_token (&val, cfile) != OF) {
parse_warn (cfile, "expecting \"of\"");
skip_to_semi (cfile);
- free_permit (permit,
- "parse_pool_statement");
+ free_permit (permit, MDL);
continue;
}
if (next_token (&val, cfile) != STRING) {
parse_warn (cfile,
"expecting class name.");
skip_to_semi (cfile);
- free_permit (permit,
- "parse_pool_statement");
+ free_permit (permit, MDL);
continue;
}
permit -> type = permit_class;
name = (char *)0;
}
- host = (struct host_decl *)dmalloc (sizeof (struct host_decl),
- "parse_host_declaration");
+ host = (struct host_decl *)dmalloc (sizeof (struct host_decl), MDL);
if (!host)
log_fatal ("can't allocate host decl struct %s.", name);
memset (host, 0, sizeof *host);
host -> name = name;
- host -> group = clone_group (group, "parse_host_declaration");
+ host -> group = clone_group (group, MDL);
if (!parse_lbrace (cfile))
return;
if (host -> named_group)
omapi_object_dereference
((omapi_object_t **)
- &host -> named_group,
- "parse_host_declaration");
+ &host -> named_group, MDL);
omapi_object_reference
((omapi_object_t **)
&host -> named_group,
- (omapi_object_t *)go,
- "parse_host_declaration");
+ (omapi_object_t *)go, MDL);
}
if (!parse_semi (cfile))
break;
unsigned len;
token = next_token (&val, cfile);
- data_string_forget (&host -> client_identifier,
- "parse_host_declaration");
+ data_string_forget (&host -> client_identifier, MDL);
/* See if it's a string or a cshl. */
token = peek_token (&val, cfile);
}
if (!buffer_allocate
(&host -> client_identifier.buffer,
- len + host -> client_identifier.terminated,
- "parse_host_declaration"))
+ len + host -> client_identifier.terminated, MDL))
log_fatal ("no memory for uid for host %s.",
host -> name);
host -> client_identifier.data =
memcpy (host -> client_identifier.buffer -> data, s,
len + host -> client_identifier.terminated);
if (t)
- dfree (t, "parse_host_declaration");
+ dfree (t, MDL);
if (!parse_semi (cfile))
break;
if (hp) {
delete_host (hp, 0);
}
- dfree (host -> name, "parse_host_declaration");
+ dfree (host -> name, MDL);
if (host -> group)
- free_group (host -> group, "parse_host_declaration");
- dfree (host, "parse_host_declaration");
+ free_group (host -> group, MDL);
+ dfree (host, MDL);
} else {
if (host -> named_group && host -> named_group -> group) {
if (host -> group -> statements ||
host -> group -> next =
host -> named_group -> group;
else {
- dfree (host -> group,
- "parse_host_declaration");
+ dfree (host -> group, MDL);
host -> group = host -> named_group -> group;
}
}
if (type == 0 || type == 1) {
data.len = strlen (val);
data.buffer = (struct buffer *)0;
- if (!buffer_allocate (&data.buffer,
- data.len + 1, "parse_class_declaration"))
+ if (!buffer_allocate (&data.buffer, data.len + 1, MDL))
log_fatal ("no memoy for class name.");
data.data = &data.buffer -> data [0];
data.terminated = 1;
name = type ? "implicit-vendor-class" : "implicit-user-class";
} else if (type == 2) {
char *tname;
- if (!(tname = dmalloc (strlen (val) + 1,
- "parse_class_declaration")))
+ if (!(tname = dmalloc (strlen (val) + 1, MDL)))
log_fatal ("No memory for class name %s.", val);
strcpy (tname, val);
name = tname;
token = next_token (&val, cfile);
data.len = strlen (val);
data.buffer = (struct buffer *)0;
- if (!buffer_allocate (&data.buffer, data.len + 1,
- "parse_class_declaration"))
+ if (!buffer_allocate (&data.buffer, data.len + 1, MDL))
return (struct class *)0;
data.terminated = 1;
data.data = &data.buffer -> data [0];
/* If we didn't find an existing class, allocate a new one. */
if (!class) {
/* Allocate the class structure... */
- class = (struct class *)dmalloc (sizeof (struct class),
- "parse_class_declaration");
+ class = (struct class *)dmalloc (sizeof (struct class), MDL);
if (!class)
log_fatal ("No memory for class %s.", val);
memset (class, 0, sizeof *class);
if (class -> lease_limit) {
class -> billed_leases =
dmalloc (class -> lease_limit *
- sizeof (struct lease *),
- "parse_class_declaration");
+ sizeof (struct lease *), MDL);
if (!class -> billed_leases)
log_fatal ("no memory for billing");
memset (class -> billed_leases, 0,
(class -> lease_limit *
sizeof class -> billed_leases));
}
- data_string_copy (&class -> hash_string, &data,
- "parse_class_declaration");
+ data_string_copy (&class -> hash_string, &data, MDL);
if (!pc -> hash)
pc -> hash = new_hash ();
add_hash (pc -> hash,
(unsigned char *)class);
} else {
class -> group =
- clone_group (group, "parse_class_declaration");
+ clone_group (group, MDL);
}
/* If this is an implicit vendor or user class, add a
if (type == 0 || type == 1) {
stmt = ((struct executable_statement *)
dmalloc (sizeof (struct executable_statement),
- "implicit user/vendor class"));
+ MDL));
if (!stmt)
log_fatal ("no memory for class statement.");
memset (stmt, 0, sizeof *stmt);
stmt -> op = supersede_option_statement;
if (option_cache_allocate (&stmt -> data.option,
- "parse_class_statement")) {
+ MDL)) {
stmt -> data.option -> data = data;
stmt -> data.option -> option =
dhcp_universe.options
}
if (type == 0 || type == 1 || type == 3)
- data_string_forget (&data, "parse_class_declaration");
+ data_string_forget (&data, MDL);
/* Spawned classes don't have their own settings. */
if (class -> superclass) {
return class;
}
/* Give the subclass its own group. */
- class -> group = clone_group (class -> group,
- "parse_class_declaration");
+ class -> group = clone_group (class -> group, MDL);
}
if (!parse_lbrace (cfile))
class -> lease_limit = atoi (val);
class -> billed_leases =
dmalloc (class -> lease_limit *
- sizeof (struct lease *),
- "parse_class_declaration");
+ sizeof (struct lease *), MDL);
if (!class -> billed_leases)
log_fatal ("no memory for billed leases.");
memset (class -> billed_leases, 0,
char *name;
int declaration = 0;
- share = new_shared_network ("parse_shared_net_declaration");
+ share = new_shared_network (MDL);
if (!share)
log_fatal ("No memory for shared subnet");
share -> pools = (struct pool *)0;
share -> next = (struct shared_network *)0;
share -> interface = (struct interface_info *)0;
- share -> group = clone_group (group, "parse_shared_net_declaration");
+ share -> group = clone_group (group, MDL);
share -> group -> shared_network = share;
/* Get the name of the shared network... */
parse_warn (cfile, "zero-length shared network name");
val = "<no-name-given>";
}
- name = malloc (strlen (val) + 1);
+ name = dmalloc (strlen (val) + 1, MDL);
if (!name)
log_fatal ("no memory for shared network name");
strcpy (name, val);
if (token == RBRACE) {
token = next_token (&val, cfile);
if (!share -> subnets) {
- parse_warn (cfile,
- "empty shared-network decl");
+ parse_warn (cfile, MDL);
return;
}
enter_shared_network (share);
int declaration = 0;
struct interface_info *ip;
- subnet = new_subnet ("parse_subnet_declaration");
+ subnet = new_subnet (MDL);
if (!subnet)
log_fatal ("No memory for new subnet");
subnet -> shared_network = share;
- subnet -> group = clone_group (share -> group,
- "parse_subnet_declaration");
+ subnet -> group = clone_group (share -> group, MDL);
subnet -> group -> subnet = subnet;
/* Get the network number... */
int dynamicp = 0;
int staticp = 0;
- g = clone_group (group, "parse_group_declaration");
+ g = clone_group (group, MDL);
token = peek_token (&val, cfile);
if (is_identifier (token) || token == STRING) {
next_token (&val, cfile);
- name = dmalloc (strlen (val) + 1, "parse_group_declaration");
+ name = dmalloc (strlen (val) + 1, MDL);
if (!name)
log_fatal ("no memory for group decl name %s", val);
strcpy (name, val);
}
}
} else {
- t = dmalloc (sizeof *t, "parse_group_declaration");
+ t = dmalloc (sizeof *t, MDL);
if (!t)
log_fatal ("no memory for group decl %s", val);
memset (t, 0, sizeof *t);
if (expr) {
new = (struct expression *)0;
status = make_concat (&new, expr, tmp);
- expression_dereference
- (&expr, "parse_fixed_addr_param");
- expression_dereference
- (&tmp, "parse_fixed_addr_param");
+ expression_dereference (&expr, MDL);
+ expression_dereference (&tmp, MDL);
if (status)
return 0;
expr = new;
expr = tmp;
} else {
if (expr)
- expression_dereference
- (&expr, "parse_fixed_addr_param");
+ expression_dereference (&expr, MDL);
return 0;
}
token = peek_token (&val, cfile);
if (!parse_semi (cfile)) {
if (expr)
- expression_dereference (&expr,
- "parse_fixed_addr_param");
+ expression_dereference (&expr, MDL);
return 0;
}
status = option_cache (oc, (struct data_string *)0, expr,
(struct option *)0);
- expression_dereference (&expr, "parse_fixed_addr_param");
+ expression_dereference (&expr, MDL);
return status;
}
| TIMESTAMP date
| HARDWARE hardware-parameter
| UID hex_numbers SEMI
- | DDNS_FWD_NAME hostname
- | DDNS_REV_NAME hostname
| HOSTNAME hostname SEMI
| CLIENT_HOSTNAME hostname SEMI
| CLASS identifier SEMI
char tbuf [32];
static struct lease lease;
struct executable_statement *on;
+ struct expression *exp;
+ struct data_string ds;
int lose;
TIME t;
+ char *s;
+ int noequal, newbinding;
+ struct binding *binding;
/* Zap the lease structure... */
memset (&lease, 0, sizeof lease);
unsigned char *tuid;
token = next_token (&val, cfile);
lease.uid_len = strlen (val);
- tuid = (unsigned char *)malloc (lease.uid_len);
+ tuid = ((unsigned char *)
+ dmalloc (lease.uid_len, MDL));
if (!tuid) {
log_error ("no space for uid");
return (struct lease *)0;
lease.uid = (parse_numeric_aggregate
(cfile, (unsigned char *)0,
&lease.uid_len, ':', 16, 8));
- if (!lease.uid) {
- log_error ("no space for uid");
+ if (!lease.uid)
return (struct lease *)0;
- }
if (lease.uid_len == 0) {
lease.uid = (unsigned char *)0;
parse_warn (cfile, "zero-length uid");
skip_to_rbrace (cfile, 1);
return (struct lease *)0;
}
+ seenbit = 0;
if ((on -> data.on.evtypes & ON_EXPIRY) &&
on -> data.on.statements) {
- seenbit = 16384;
+ seenbit |= 16384;
executable_statement_reference
(&lease.on_expiry,
- on -> data.on.statements,
- "parse_lease_declaration");
+ on -> data.on.statements, MDL);
}
if ((on -> data.on.evtypes & ON_RELEASE) &&
on -> data.on.statements) {
- seenbit = 32768;
+ seenbit |= 32768;
executable_statement_reference
(&lease.on_release,
- on -> data.on.statements,
- "parse_lease_declaration");
+ on -> data.on.statements, MDL);
}
- executable_statement_dereference
- (&on, "parse_lease_declaration");
+ executable_statement_dereference (&on, MDL);
break;
+ case TOKEN_SET:
+ noequal = 0;
+
+ token = next_token (&val, cfile);
+ if (token != NAME && token != NUMBER_OR_NAME) {
+ parse_warn (cfile,
+ "%s can't be a variable name",
+ val);
+ badset:
+ skip_to_semi (cfile);
+ return (struct lease *)0;
+ }
+
+ seenbit = 0;
+ special_set:
+ binding = find_binding (&lease.scope, val);
+ if (!binding) {
+ binding = dmalloc (sizeof *binding, MDL);
+ if (!binding)
+ log_fatal ("No memory for lease %s.",
+ "binding");
+ memset (binding, 0, sizeof *binding);
+ binding -> name =
+ dmalloc (strlen (val) + 1, MDL);
+ if (!binding -> name)
+ log_fatal ("No memory for binding %s.",
+ "name");
+ strcpy (binding -> name, val);
+ newbinding = 1;
+ } else if (binding -> value.data) {
+ data_string_forget (&binding -> value, MDL);
+ newbinding = 0;
+ }
+
+ if (!noequal) {
+ token = next_token (&val, cfile);
+ if (token != EQUAL) {
+ parse_warn (cfile,
+ "expecting '=' in set statement.");
+ goto badset;
+ }
+ }
+
+ token = peek_token (&val, cfile);
+ if (token == STRING) {
+ unsigned char *tuid;
+ token = next_token (&val, cfile);
+ binding -> value.len = strlen (val); /* !! */
+ if (!(buffer_allocate
+ (&binding -> value.buffer,
+ binding -> value.len + 1, MDL)))
+ log_fatal ("No memory for binding.");
+ strcpy (binding -> value.buffer -> data, val);
+ binding -> value.data =
+ binding -> value.buffer -> data;
+ binding -> value.terminated = 1;
+ } else {
+ s = (parse_numeric_aggregate
+ (cfile, (unsigned char *)0,
+ &binding -> value.len, ':', 16, 8));
+ if (!s)
+ return (struct lease *)0;
+ if (binding -> value.len) {
+ if (!(buffer_allocate
+ (&binding -> value.buffer,
+ binding -> value.len + 1, MDL)))
+ log_fatal ("No memory for%s.",
+ " binding");
+ memcpy (binding -> value.buffer -> data,
+ s, binding -> value.len);
+ dfree (s, MDL);
+ binding -> value.data =
+ binding -> value.buffer -> data;
+ }
+ }
+ if (newbinding) {
+ binding -> next = lease.scope.bindings;
+ lease.scope.bindings = binding;
+ }
+ parse_semi (cfile);
+ break;
+
+
default:
+ if (!strcasecmp (val, "ddns-fwd-name")) {
+ seenbit = 4096;
+ noequal = 1;
+ goto special_set;
+ } else if (!strcasecmp (val, "ddns-rev-name")) {
+ seenbit = 8192;
+ noequal = 1;
+ goto special_set;
+ }
skip_to_semi (cfile);
seenbit = 0;
return (struct lease *)0;
/* If we're permitting dynamic bootp for this range,
then look for a pool with an empty prohibit list and
- a permit list with one entry which permits dynamic
- bootp. */
+ a permit list with one entry that permits all clients. */
for (pool = share -> pools; pool; pool = pool -> next) {
- if ((!dynamic &&
- !pool -> permit_list && !pool -> prohibit_list) ||
- (dynamic &&
- !pool -> prohibit_list &&
+ if ((!dynamic && !pool -> permit_list &&
+ pool -> prohibit_list &&
+ !pool -> prohibit_list -> next &&
+ (pool -> prohibit_list -> type ==
+ permit_dynamic_bootp_clients)) ||
+ (dynamic && !pool -> prohibit_list &&
pool -> permit_list &&
!pool -> permit_list -> next &&
(pool -> permit_list -> type ==
permit_all_clients))) {
- break;
+ break;
}
last = pool;
}
/* If we didn't get a pool, make one. */
if (!pool) {
- pool = new_pool ("parse_address_range");
+ struct permit *p;
+ pool = new_pool (MDL);
if (!pool)
log_fatal ("no memory for ad-hoc pool.");
+ p = new_permit (MDL);
+ if (!p)
+ log_fatal ("no memory for ad-hoc permit.");
+
+ /* Dynamic pools permit all clients. Otherwise
+ we prohibit BOOTP clients. */
if (dynamic) {
- pool -> permit_list =
- new_permit ("parse_address_range");
- if (!pool -> permit_list)
- log_fatal ("no memory for ad-hoc %s.",
- "permit");
- pool -> permit_list -> type =
- permit_all_clients;
+ p -> type = permit_all_clients;
+ pool -> permit_list = p;
+ } else {
+ p -> type = permit_dynamic_bootp_clients;
+ pool -> prohibit_list = p;
}
+
if (share -> pools)
last -> next = pool;
else
share -> pools = pool;
pool -> shared_network = share;
- pool -> group = clone_group (share -> group,
- "parse_address_range");
+ pool -> group = clone_group (share -> group, MDL);
}
}