2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-29 21:38:10 +00:00

Corrections to changes made on HEAD pursuant to review of changes between

V3.0.3 and HEAD.  [ISC-Bugs #15348]
This commit is contained in:
David Hankins 2005-09-30 17:57:32 +00:00
parent c75473d800
commit 06e77c34fb
8 changed files with 248 additions and 241 deletions

View File

@ -600,6 +600,12 @@ struct collection {
struct class *classes; struct class *classes;
}; };
/* Used as an argument to parse_clasS_decl() */
#define CLASS_TYPE_VENDOR 0
#define CLASS_TYPE_USER 1
#define CLASS_TYPE_CLASS 2
#define CLASS_TYPE_SUBCLASS 3
/* XXX classes must be reference-counted. */ /* XXX classes must be reference-counted. */
struct class { struct class {
OMAPI_OBJECT_PREAMBLE; OMAPI_OBJECT_PREAMBLE;
@ -1917,7 +1923,8 @@ int write_failover_state (dhcp_failover_state_t *);
#endif #endif
int db_printable PROTO ((const char *)); int db_printable PROTO ((const char *));
int db_printable_len PROTO ((const unsigned char *, unsigned)); int db_printable_len PROTO ((const unsigned char *, unsigned));
void write_named_billing_class (const char *, unsigned, struct class *); isc_result_t write_named_billing_class(const unsigned char *, unsigned,
void *);
void write_billing_classes (void); void write_billing_classes (void);
int write_billing_class PROTO ((struct class *)); int write_billing_class PROTO ((struct class *));
void commit_leases_timeout PROTO ((void *)); void commit_leases_timeout PROTO ((void *));
@ -2460,7 +2467,7 @@ void hw_hash_add PROTO ((struct lease *));
void hw_hash_delete PROTO ((struct lease *)); void hw_hash_delete PROTO ((struct lease *));
int write_leases PROTO ((void)); int write_leases PROTO ((void));
int lease_enqueue (struct lease *); int lease_enqueue (struct lease *);
void lease_instantiate (const unsigned char *, unsigned, struct lease *); isc_result_t lease_instantiate(const unsigned char *, unsigned, void *);
void expire_all_pools PROTO ((void)); void expire_all_pools PROTO ((void));
void dump_subnets PROTO ((void)); void dump_subnets PROTO ((void));
#if defined (DEBUG_MEMORY_LEAKAGE) || \ #if defined (DEBUG_MEMORY_LEAKAGE) || \

View File

@ -42,8 +42,8 @@ typedef struct {
int foo; int foo;
} hashed_object_t; } hashed_object_t;
typedef void (*hash_foreach_func) (const unsigned char *, typedef isc_result_t (*hash_foreach_func)(const unsigned char *, unsigned,
unsigned, hashed_object_t *); void *);
typedef int (*hash_reference) (hashed_object_t **, hashed_object_t *, typedef int (*hash_reference) (hashed_object_t **, hashed_object_t *,
const char *, int); const char *, int);
typedef int (*hash_dereference) (hashed_object_t **, const char *, int); typedef int (*hash_dereference) (hashed_object_t **, const char *, int);
@ -79,8 +79,7 @@ void name##_hash_delete (hashtype *, bufarg, unsigned, \
const char *, int); \ const char *, int); \
int name##_hash_lookup (type **, hashtype *, bufarg, unsigned, \ int name##_hash_lookup (type **, hashtype *, bufarg, unsigned, \
const char *, int); \ const char *, int); \
int name##_hash_foreach (hashtype *, \ int name##_hash_foreach (hashtype *, hash_foreach_func); \
void (*) (bufarg, unsigned, type *)); \
int name##_new_hash (hashtype **, int, const char *, int); \ int name##_new_hash (hashtype **, int, const char *, int); \
void name##_free_hash_table (hashtype **, const char *, int); void name##_free_hash_table (hashtype **, const char *, int);
@ -111,11 +110,10 @@ int name##_hash_lookup (type **ptr, hashtype *table, \
(const unsigned char *)buf, len, file, line); \ (const unsigned char *)buf, len, file, line); \
} \ } \
\ \
int name##_hash_foreach (hashtype *table, \ int name##_hash_foreach (hashtype *table, hash_foreach_func func) \
void (*func) (bufarg, unsigned, type *)) \
{ \ { \
return hash_foreach ((struct hash_table *)table, \ return hash_foreach ((struct hash_table *)table, \
(hash_foreach_func)func); \ func); \
} \ } \
\ \
int name##_new_hash (hashtype **tp, int c, const char *file, int line) \ int name##_new_hash (hashtype **tp, int c, const char *file, int line) \

View File

@ -34,7 +34,7 @@
#ifndef lint #ifndef lint
static char copyright[] = static char copyright[] =
"$Id: hash.c,v 1.5 2005/03/17 20:15:22 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n"; "$Id: hash.c,v 1.6 2005/09/30 17:57:32 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#include <omapip/omapip_p.h> #include <omapip/omapip_p.h>
@ -380,7 +380,9 @@ int hash_foreach (struct hash_table *table, hash_foreach_func func)
bp = table -> buckets [i]; bp = table -> buckets [i];
while (bp) { while (bp) {
next = bp -> next; next = bp -> next;
(*func) (bp -> name, bp -> len, bp -> value); if ((*func)(bp->name, bp->len, bp->value)
!= ISC_R_SUCCESS)
return count;
bp = next; bp = next;
count++; count++;
} }

View File

@ -44,7 +44,7 @@ install: all
foo=$${foo}/$$bar; \ foo=$${foo}/$$bar; \
if [ ! -d $$foo ]; then \ if [ ! -d $$foo ]; then \
mkdir $$foo; \ mkdir $$foo; \
chmod 755 $$foo; \ $(CHMOD) 755 $$foo; \
fi; \ fi; \
done; \ done; \
done done
@ -56,7 +56,9 @@ install: all
$(DESTDIR)$(FFMANDIR)/dhcpd.conf$(FFMANEXT) $(DESTDIR)$(FFMANDIR)/dhcpd.conf$(FFMANEXT)
$(MANINSTALL) $(MANFROM) dhcpd.leases.$(MANCAT)5 $(MANTO) \ $(MANINSTALL) $(MANFROM) dhcpd.leases.$(MANCAT)5 $(MANTO) \
$(DESTDIR)$(FFMANDIR)/dhcpd.leases$(FFMANEXT) $(DESTDIR)$(FFMANDIR)/dhcpd.leases$(FFMANEXT)
umask 177; $(TOUCH) $(DESTDIR)$(VARDB)/dhcpd.leases $(TOUCH) $(DESTDIR)$(VARDB)/dhcpd.leases
# Note file mode is hardcoded to mode 0664 in server/db.c (889).
$(CHMOD) 664 $(DESTDIR)$(VARDB)/dhcpd.leases
depend: depend:
$(MKDEP) $(INCLUDES) $(PREDEFINES) $(SRCS) $(MKDEP) $(INCLUDES) $(PREDEFINES) $(SRCS)

View File

@ -34,7 +34,7 @@
#ifndef lint #ifndef lint
static char copyright[] = static char copyright[] =
"$Id: confpars.c,v 1.148 2005/03/17 20:15:26 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n"; "$Id: confpars.c,v 1.149 2005/09/30 17:57:32 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@ -268,9 +268,11 @@ isc_result_t lease_file_subparse (struct parse *cfile)
parse_warn (cfile, parse_warn (cfile,
"possibly corrupt lease file"); "possibly corrupt lease file");
} else if (token == CLASS) { } else if (token == CLASS) {
parse_class_declaration (0, cfile, root_group, 2); parse_class_declaration(0, cfile, root_group,
CLASS_TYPE_CLASS);
} else if (token == SUBCLASS) { } else if (token == SUBCLASS) {
parse_class_declaration (0, cfile, root_group, 3); parse_class_declaration(0, cfile, root_group,
CLASS_TYPE_SUBCLASS);
} else if (token == HOST) { } else if (token == HOST) {
parse_host_declaration (cfile, root_group); parse_host_declaration (cfile, root_group);
} else if (token == GROUP) { } else if (token == GROUP) {
@ -464,7 +466,7 @@ int parse_statement (cfile, group, type, host_decl, declaration)
skip_to_semi (cfile); skip_to_semi (cfile);
break; break;
} }
parse_class_declaration ((struct class **)0, cfile, group, 0); parse_class_declaration(NULL, cfile, group, CLASS_TYPE_VENDOR);
return 1; return 1;
case USER_CLASS: case USER_CLASS:
@ -475,7 +477,7 @@ int parse_statement (cfile, group, type, host_decl, declaration)
skip_to_semi (cfile); skip_to_semi (cfile);
break; break;
} }
parse_class_declaration ((struct class **)0, cfile, group, 1); parse_class_declaration(NULL, cfile, group, CLASS_TYPE_USER);
return 1; return 1;
case CLASS: case CLASS:
@ -486,7 +488,7 @@ int parse_statement (cfile, group, type, host_decl, declaration)
skip_to_semi (cfile); skip_to_semi (cfile);
break; break;
} }
parse_class_declaration ((struct class **)0, cfile, group, 2); parse_class_declaration(NULL, cfile, group, CLASS_TYPE_CLASS);
return 1; return 1;
case SUBCLASS: case SUBCLASS:
@ -497,7 +499,8 @@ int parse_statement (cfile, group, type, host_decl, declaration)
skip_to_semi (cfile); skip_to_semi (cfile);
break; break;
} }
parse_class_declaration ((struct class **)0, cfile, group, 3); parse_class_declaration(NULL, cfile, group,
CLASS_TYPE_SUBCLASS);
return 1; return 1;
case HARDWARE: case HARDWARE:
@ -1828,8 +1831,8 @@ int parse_class_declaration (cp, cfile, group, type)
struct expression *expr; struct expression *expr;
int new = 1; int new = 1;
isc_result_t status = ISC_R_FAILURE; isc_result_t status = ISC_R_FAILURE;
int deleted = 0; int matchedonce = 0;
int dynamic = 0; int submatchedonce = 0;
token = next_token (&val, (unsigned *)0, cfile); token = next_token (&val, (unsigned *)0, cfile);
if (token != STRING) { if (token != STRING) {
@ -1841,18 +1844,17 @@ int parse_class_declaration (cp, cfile, group, type)
/* See if there's already a class with the specified name. */ /* See if there's already a class with the specified name. */
find_class (&pc, val, MDL); find_class (&pc, val, MDL);
/* If this isn't a subclass, we're updating an existing class. */ /* If it is a class, we're updating it. If it's any of the other
if (pc && type != 0 && type != 1 && type != 3) { * types (subclass, vendor or user class), the named class is a
class_reference (&class, pc, MDL); * reference to the parent class so its mandatory.
*/
if (pc && (type == CLASS_TYPE_CLASS)) {
class_reference(&class, pc, MDL);
new = 0; new = 0;
class_dereference (&pc, MDL); class_dereference(&pc, MDL);
} } else if (!pc && (type != CLASS_TYPE_CLASS)) {
parse_warn(cfile, "no class named %s", val);
/* If this _is_ a subclass, there _must_ be a class with the skip_to_semi(cfile);
same name. */
if (!pc && (type == 0 || type == 1 || type == 3)) {
parse_warn (cfile, "no class named %s", val);
skip_to_semi (cfile);
return 0; return 0;
} }
@ -1863,7 +1865,7 @@ int parse_class_declaration (cp, cfile, group, type)
are turned into subclasses of the implicit classes, and the are turned into subclasses of the implicit classes, and the
submatch expression of the implicit classes extracts the contents of submatch expression of the implicit classes extracts the contents of
the vendor class or user class. */ the vendor class or user class. */
if (type == 0 || type == 1) { if ((type == CLASS_TYPE_VENDOR) || (type == CLASS_TYPE_USER)) {
data.len = strlen (val); data.len = strlen (val);
data.buffer = (struct buffer *)0; data.buffer = (struct buffer *)0;
if (!buffer_allocate (&data.buffer, data.len + 1, MDL)) if (!buffer_allocate (&data.buffer, data.len + 1, MDL))
@ -1872,7 +1874,7 @@ int parse_class_declaration (cp, cfile, group, type)
data.terminated = 1; data.terminated = 1;
tname = type ? "implicit-vendor-class" : "implicit-user-class"; tname = type ? "implicit-vendor-class" : "implicit-user-class";
} else if (type == 2) { } else if (type == CLASS_TYPE_CLASS) {
tname = val; tname = val;
} else { } else {
tname = (const char *)0; tname = (const char *)0;
@ -1887,7 +1889,7 @@ int parse_class_declaration (cp, cfile, group, type)
name = (char *)0; name = (char *)0;
/* If this is a straight subclass, parse the hash string. */ /* If this is a straight subclass, parse the hash string. */
if (type == 3) { if (type == CLASS_TYPE_SUBCLASS) {
token = peek_token (&val, (unsigned *)0, cfile); token = peek_token (&val, (unsigned *)0, cfile);
if (token == STRING) { if (token == STRING) {
token = next_token (&val, &data.len, cfile); token = next_token (&val, &data.len, cfile);
@ -1906,7 +1908,8 @@ int parse_class_declaration (cp, cfile, group, type)
} else if (token == NUMBER_OR_NAME || token == NUMBER) { } else if (token == NUMBER_OR_NAME || token == NUMBER) {
memset (&data, 0, sizeof data); memset (&data, 0, sizeof data);
if (!parse_cshl (&data, cfile)) { if (!parse_cshl (&data, cfile)) {
class_dereference (&pc, MDL); if (pc)
class_dereference (&pc, MDL);
return 0; return 0;
} }
} else { } else {
@ -1919,7 +1922,7 @@ int parse_class_declaration (cp, cfile, group, type)
/* See if there's already a class in the hash table matching the /* See if there's already a class in the hash table matching the
hash data. */ hash data. */
if (type == 0 || type == 1 || type == 3) if (type != CLASS_TYPE_CLASS)
class_hash_lookup (&class, pc -> hash, class_hash_lookup (&class, pc -> hash,
(const char *)data.data, data.len, MDL); (const char *)data.data, data.len, MDL);
@ -1950,6 +1953,8 @@ int parse_class_declaration (cp, cfile, group, type)
class -> hash_string.len, class -> hash_string.len,
(void *)class, MDL); (void *)class, MDL);
} else { } else {
if (class->group)
group_dereference(&class->group, MDL);
if (!clone_group (&class -> group, group, MDL)) if (!clone_group (&class -> group, group, MDL))
log_fatal ("no memory to clone class group."); log_fatal ("no memory to clone class group.");
} }
@ -1957,7 +1962,7 @@ int parse_class_declaration (cp, cfile, group, type)
/* If this is an implicit vendor or user class, add a /* If this is an implicit vendor or user class, add a
statement that causes the vendor or user class ID to statement that causes the vendor or user class ID to
be sent back in the reply. */ be sent back in the reply. */
if (type == 0 || type == 1) { if (type == CLASS_TYPE_VENDOR || type == CLASS_TYPE_USER) {
stmt = (struct executable_statement *)0; stmt = (struct executable_statement *)0;
if (!executable_statement_allocate (&stmt, MDL)) if (!executable_statement_allocate (&stmt, MDL))
log_fatal ("no memory for class statement."); log_fatal ("no memory for class statement.");
@ -1967,7 +1972,7 @@ int parse_class_declaration (cp, cfile, group, type)
stmt -> data.option -> data = data; stmt -> data.option -> data = data;
stmt -> data.option -> option = stmt -> data.option -> option =
dhcp_universe.options dhcp_universe.options
[type [(type == CLASS_TYPE_VENDOR)
? DHO_VENDOR_CLASS_IDENTIFIER ? DHO_VENDOR_CLASS_IDENTIFIER
: DHO_USER_CLASS]; : DHO_USER_CLASS];
} }
@ -1975,11 +1980,13 @@ int parse_class_declaration (cp, cfile, group, type)
} }
/* Save the name, if there is one. */ /* Save the name, if there is one. */
class -> name = name; if (class->name != NULL)
dfree(class->name, MDL);
class->name = name;
} }
if (type == 0 || type == 1 || type == 3) if (type != CLASS_TYPE_CLASS)
data_string_forget (&data, MDL); data_string_forget(&data, MDL);
/* Spawned classes don't have to have their own settings. */ /* Spawned classes don't have to have their own settings. */
if (class -> superclass) { if (class -> superclass) {
@ -2016,13 +2023,13 @@ int parse_class_declaration (cp, cfile, group, type)
parse_warn (cfile, "unexpected end of file"); parse_warn (cfile, "unexpected end of file");
break; break;
} else if (token == DYNAMIC) { } else if (token == DYNAMIC) {
dynamic = 1; class->flags |= CLASS_DECL_DYNAMIC;
token = next_token (&val, (unsigned *)0, cfile); token = next_token (&val, (unsigned *)0, cfile);
if (!parse_semi (cfile)) if (!parse_semi (cfile))
break; break;
continue; continue;
} else if (token == TOKEN_DELETED) { } else if (token == TOKEN_DELETED) {
deleted = 1; class->flags |= CLASS_DECL_DELETED;
token = next_token (&val, (unsigned *)0, cfile); token = next_token (&val, (unsigned *)0, cfile);
if (!parse_semi (cfile)) if (!parse_semi (cfile))
break; break;
@ -2038,13 +2045,17 @@ int parse_class_declaration (cp, cfile, group, type)
token = peek_token (&val, (unsigned *)0, cfile); token = peek_token (&val, (unsigned *)0, cfile);
if (token != IF) if (token != IF)
goto submatch; goto submatch;
if (class -> expr) { token = next_token (&val, (unsigned *)0, cfile);
parse_warn (cfile, "can't override match."); if (matchedonce) {
skip_to_semi (cfile); parse_warn(cfile, "A class may only have "
"one 'match if' clause.");
skip_to_semi(cfile);
break; break;
} }
token = next_token (&val, (unsigned *)0, cfile); matchedonce = 1;
if (!parse_boolean_expression (&class -> expr, cfile, if (class->expr)
expression_dereference(&class->expr, MDL);
if (!parse_boolean_expression (&class->expr, cfile,
&lose)) { &lose)) {
if (!lose) { if (!lose) {
parse_warn (cfile, parse_warn (cfile,
@ -2059,13 +2070,13 @@ int parse_class_declaration (cp, cfile, group, type)
parse_semi (cfile); parse_semi (cfile);
} }
} else if (token == SPAWN) { } else if (token == SPAWN) {
token = next_token (&val, (unsigned *)0, cfile);
if (pc) { if (pc) {
parse_warn (cfile, parse_warn (cfile,
"invalid spawn in subclass."); "invalid spawn in subclass.");
skip_to_semi (cfile); skip_to_semi (cfile);
break; break;
} }
token = next_token (&val, (unsigned *)0, cfile);
class -> spawning = 1; class -> spawning = 1;
token = next_token (&val, (unsigned *)0, cfile); token = next_token (&val, (unsigned *)0, cfile);
if (token != WITH) { if (token != WITH) {
@ -2075,13 +2086,16 @@ int parse_class_declaration (cp, cfile, group, type)
break; break;
} }
submatch: submatch:
if (class -> submatch) { if (submatchedonce) {
parse_warn (cfile, parse_warn (cfile,
"can't override existing %s.", "can't override existing %s.",
"submatch/spawn"); "submatch/spawn");
skip_to_semi (cfile); skip_to_semi (cfile);
break; break;
} }
submatchedonce = 1;
if (class->submatch)
expression_dereference(&class->submatch, MDL);
if (!parse_data_expression (&class -> submatch, if (!parse_data_expression (&class -> submatch,
cfile, &lose)) { cfile, &lose)) {
if (!lose) { if (!lose) {
@ -2113,6 +2127,8 @@ int parse_class_declaration (cp, cfile, group, type)
break; break;
} }
class -> lease_limit = atoi (val); class -> lease_limit = atoi (val);
if (class->billed_leases)
dfree(class->billed_leases, MDL);
class -> billed_leases = class -> billed_leases =
dmalloc (class -> lease_limit * dmalloc (class -> lease_limit *
sizeof (struct lease *), MDL); sizeof (struct lease *), MDL);
@ -2131,19 +2147,21 @@ int parse_class_declaration (cp, cfile, group, type)
} }
} while (1); } while (1);
if (deleted) { if (class->flags & CLASS_DECL_DELETED) {
struct class *theclass = 0; if (type == CLASS_TYPE_CLASS) {
struct class *theclass = NULL;
status = find_class(&theclass, class->name, MDL); status = find_class(&theclass, class->name, MDL);
if (status == ISC_R_SUCCESS) { if (status == ISC_R_SUCCESS) {
delete_class(theclass, 0); delete_class(theclass, 0);
class_dereference(&theclass, MDL); class_dereference(&theclass, MDL);
}
} else {
class_hash_delete(pc->hash,
(char *)class->hash_string.data,
class->hash_string.len, MDL);
} }
} else if (type == 2 && new) { } else if (type == CLASS_TYPE_CLASS && new) {
if (dynamic) {
class->flags |= CLASS_DECL_DYNAMIC;
}
if (!collections -> classes) if (!collections -> classes)
class_reference (&collections -> classes, class, MDL); class_reference (&collections -> classes, class, MDL);
else { else {
@ -2153,10 +2171,8 @@ int parse_class_declaration (cp, cfile, group, type)
; ;
class_reference (&c -> nic, class, MDL); class_reference (&c -> nic, class, MDL);
} }
} else if (type == 3 && dynamic) {
class->flags |= CLASS_DECL_DYNAMIC;
} }
if (cp) /* should always be 0??? */ if (cp) /* should always be 0??? */
status = class_reference (cp, class, MDL); status = class_reference (cp, class, MDL);
class_dereference (&class, MDL); class_dereference (&class, MDL);
@ -2851,9 +2867,8 @@ int parse_lease_declaration (struct lease **lp, struct parse *cfile)
if (lease -> billing_class) if (lease -> billing_class)
class_dereference (&lease -> billing_class, class_dereference (&lease -> billing_class,
MDL); MDL);
parse_class_declaration parse_class_declaration(&class, cfile, NULL,
(&class, CLASS_TYPE_SUBCLASS);
cfile, (struct group *)0, 3);
} else { } else {
parse_warn (cfile, "expecting \"class\""); parse_warn (cfile, "expecting \"class\"");
if (token != SEMI) if (token != SEMI)

View File

@ -34,7 +34,7 @@
#ifndef lint #ifndef lint
static char copyright[] = static char copyright[] =
"$Id: db.c,v 1.68 2005/03/17 20:15:26 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n"; "$Id: db.c,v 1.69 2005/09/30 17:57:32 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@ -610,102 +610,115 @@ int db_printable_len (s, len)
static int print_hash_string(FILE *fp, struct class *class) static int print_hash_string(FILE *fp, struct class *class)
{ {
int i; int i;
int errors = 0;
for (i = 0; i < class -> hash_string.len; i++) for (i = 0 ; i < class->hash_string.len ; i++)
if (!isascii (class -> hash_string.data [i]) || if (!isascii(class->hash_string.data[i]) ||
!isprint (class -> hash_string.data [i])) !isprint(class->hash_string.data[i]))
break; break;
if (i == class -> hash_string.len) { if (i == class->hash_string.len) {
errno = 0; if (fprintf(fp, " \"%.*s\"", (int)class->hash_string.len,
fprintf (fp, " \"%.*s\"", class->hash_string.data) <= 0) {
(int)class -> hash_string.len, log_error("Failure writing hash string: %m");
class -> hash_string.data); return 0;
if (errno) }
++errors; } else {
} else { if (fprintf(fp, " %2.2x", class->hash_string.data[0]) <= 0) {
errno = 0; log_error("Failure writing hash string: %m");
fprintf (fp, " %2.2x", class -> hash_string.data [0]); return 0;
if (errno) }
++errors; for (i = 1 ; i < class->hash_string.len ; i++) {
for (i = 1; i < class -> hash_string.len; i++) { if (fprintf(fp, ":%2.2x",
errno = 0; class->hash_string.data[i]) <= 0) {
fprintf (fp, ":%2.2x", log_error("Failure writing hash string: %m");
class -> hash_string.data [i]); return 0;
if (errno) }
++errors;
} }
errno = 0;
if (errno)
++errors;
} }
return !errors; return 1;
} }
isc_result_t
/* XXXJAB this needs to return non-zero on error. */ write_named_billing_class(const unsigned char *name, unsigned len,
void write_named_billing_class (const char *name, unsigned len, void *object)
struct class *class)
{ {
struct class *class = object;
if (class->flags & CLASS_DECL_DYNAMIC) { if (class->flags & CLASS_DECL_DYNAMIC) {
numclasseswritten++; numclasseswritten++;
if (class->superclass == 0) { if (class->superclass == 0) {
fprintf(db_file, "class \"%s\" {\n", name); if (fprintf(db_file, "class \"%s\" {\n", name) <= 0)
return ISC_R_IOERROR;
} else { } else {
fprintf(db_file, "subclass \"%s\"", if (fprintf(db_file, "subclass \"%s\"",
class->superclass->name); class->superclass->name) <= 0)
print_hash_string(db_file, class); return ISC_R_IOERROR;
fprintf(db_file, " {\n"); if (!print_hash_string(db_file, class))
return ISC_R_IOERROR;
if (fprintf(db_file, " {\n") <= 0)
return ISC_R_IOERROR;
} }
if ((class->flags & CLASS_DECL_DELETED) != 0) { if ((class->flags & CLASS_DECL_DELETED) != 0) {
fprintf(db_file, " deleted;\n"); if (fprintf(db_file, " deleted;\n") <= 0)
return ISC_R_IOERROR;
} else { } else {
fprintf(db_file, " dynamic;\n"); if (fprintf(db_file, " dynamic;\n") <= 0)
return ISC_R_IOERROR;
} }
if (class->lease_limit > 0) { if (class->lease_limit > 0) {
fprintf(db_file, " lease limit %d;\n", class->lease_limit); if (fprintf(db_file, " lease limit %d;\n",
class->lease_limit) <= 0)
return ISC_R_IOERROR;
} }
if (class->expr != 0) { if (class->expr != 0) {
fprintf(db_file, " match if "); if (fprintf(db_file, " match if ") <= 0)
return ISC_R_IOERROR;
write_expression(db_file, class->expr, 5, 5, 0); write_expression(db_file, class->expr, 5, 5, 0);
fprintf(db_file, ";\n"); if (fprintf(db_file, ";\n") <= 0)
return ISC_R_IOERROR;
} }
if (class->submatch != 0) { if (class->submatch != 0) {
if (class->spawning) { if (class->spawning) {
fprintf(db_file, " spawn "); if (fprintf(db_file, " spawn ") <= 0)
return ISC_R_IOERROR;
} else { } else {
fprintf(db_file, " match "); if (fprintf(db_file, " match ") <= 0)
return ISC_R_IOERROR;
} }
write_expression(db_file, class->submatch, 5, 5, 0); write_expression(db_file, class->submatch, 5, 5, 0);
fprintf(db_file, ";\n"); if (fprintf(db_file, ";\n") <= 0)
return ISC_R_IOERROR;
} }
if (class->statements != 0) { if (class->statements != 0) {
write_statements(db_file, class->statements, 8); write_statements(db_file, class->statements, 8);
} }
/* XXXJAB this isn't right, but classes read in off the leases file /* XXXJAB this isn't right, but classes read in off the
don't get the root group assigned to them (due to clone_group() leases file don't get the root group assigned to them
call). */ (due to clone_group() call). */
if (class->group != 0 && class->group->authoritative != 0) { if (class->group != 0 && class->group->authoritative != 0)
write_statements (db_file, write_statements(db_file, class->group->statements, 8);
class -> group -> statements, 8);
}
fprintf(db_file, "}\n\n"); if (fprintf(db_file, "}\n\n") <= 0)
return ISC_R_IOERROR;
} }
if (class -> hash != NULL) { /* yep. recursive. god help us. */ if (class->hash != NULL) { /* yep. recursive. god help us. */
class_hash_foreach (class -> hash, write_named_billing_class); /* XXX - cannot check error status of this...
* foo_hash_foreach returns a count of operations completed.
*/
class_hash_foreach(class->hash, write_named_billing_class);
} }
return ISC_R_SUCCESS;
} }
void write_billing_classes () void write_billing_classes ()
@ -748,39 +761,8 @@ int write_billing_class (class)
if (errno) if (errno)
++errors; ++errors;
#if 0
for (i = 0; i < class -> hash_string.len; i++)
if (!isascii (class -> hash_string.data [i]) ||
!isprint (class -> hash_string.data [i]))
break;
if (i == class -> hash_string.len) {
errno = 0;
fprintf (db_file, " \"%.*s\";",
(int)class -> hash_string.len,
class -> hash_string.data);
if (errno)
++errors;
} else {
errno = 0;
fprintf (db_file, " %2.2x", class -> hash_string.data [0]);
if (errno)
++errors;
for (i = 1; i < class -> hash_string.len; i++) {
errno = 0;
fprintf (db_file, ":%2.2x",
class -> hash_string.data [i]);
if (errno)
++errors;
}
errno = 0;
fprintf (db_file, ";");
if (errno)
++errors;
}
#else
print_hash_string(db_file, class); print_hash_string(db_file, class);
fprintf(db_file, ";"); fprintf(db_file, ";");
#endif
class -> dirty = !errors; class -> dirty = !errors;
if (errors) if (errors)

View File

@ -34,7 +34,7 @@
#ifndef lint #ifndef lint
static char copyright[] = static char copyright[] =
"$Id: mdb.c,v 1.72 2005/03/17 20:15:28 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n"; "$Id: mdb.c,v 1.73 2005/09/30 17:57:32 dhankins Exp $ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@ -59,6 +59,10 @@ isc_result_t enter_class(cd, dynamicp, commit)
int commit; int commit;
{ {
if (!collections -> classes) { if (!collections -> classes) {
/* A subclass with no parent is invalid. */
if (cd->name == NULL)
return ISC_R_INVALIDARG;
class_reference (&collections -> classes, cd, MDL); class_reference (&collections -> classes, cd, MDL);
} else if (cd->name != NULL) { /* regular class */ } else if (cd->name != NULL) { /* regular class */
struct class *c = 0; struct class *c = 0;
@ -68,6 +72,7 @@ isc_result_t enter_class(cd, dynamicp, commit)
return ISC_R_EXISTS; return ISC_R_EXISTS;
} }
/* Find the tail. */
for (c = collections -> classes; for (c = collections -> classes;
c -> nic; c = c -> nic) c -> nic; c = c -> nic)
/* nothing */ ; /* nothing */ ;
@ -1995,9 +2000,10 @@ int lease_enqueue (struct lease *comp)
in each appropriate hash, understanding that it's already by definition in each appropriate hash, understanding that it's already by definition
in lease_ip_addr_hash. */ in lease_ip_addr_hash. */
void lease_instantiate (const unsigned char *val, unsigned len, isc_result_t
struct lease *lease) lease_instantiate(const unsigned char *val, unsigned len, void *object)
{ {
struct lease *lease = object;
struct class *class; struct class *class;
/* XXX If the lease doesn't have a pool at this point, it's an /* XXX If the lease doesn't have a pool at this point, it's an
XXX orphan, which we *should* keep around until it expires, XXX orphan, which we *should* keep around until it expires,
@ -2006,22 +2012,28 @@ void lease_instantiate (const unsigned char *val, unsigned len,
lease_hash_delete (lease_ip_addr_hash, lease_hash_delete (lease_ip_addr_hash,
lease -> ip_addr.iabuf, lease -> ip_addr.iabuf,
lease -> ip_addr.len, MDL); lease -> ip_addr.len, MDL);
return; return ISC_R_SUCCESS;
} }
/* Put the lease on the right queue. */ /* Put the lease on the right queue. Failure to queue is probably
lease_enqueue (lease); * due to a bogus binding state. In such a case, we claim success,
* so that later leases in a hash_foreach are processed, but we
* return early as we really don't want hw address hash entries or
* other cruft to surround such a bogus entry.
*/
if (!lease_enqueue(lease))
return ISC_R_SUCCESS;
/* Record the lease in the uid hash if possible. */ /* Record the lease in the uid hash if possible. */
if (lease -> uid) { if (lease -> uid) {
uid_hash_add (lease); uid_hash_add (lease);
} }
/* Record it in the hardware address hash if possible. */ /* Record it in the hardware address hash if possible. */
if (lease -> hardware_addr.hlen) { if (lease -> hardware_addr.hlen) {
hw_hash_add (lease); hw_hash_add (lease);
} }
/* If the lease has a billing class, set up the billing. */ /* If the lease has a billing class, set up the billing. */
if (lease -> billing_class) { if (lease -> billing_class) {
class = (struct class *)0; class = (struct class *)0;
@ -2036,7 +2048,7 @@ void lease_instantiate (const unsigned char *val, unsigned len,
bill_class (lease, class); bill_class (lease, class);
class_dereference (&class, MDL); class_dereference (&class, MDL);
} }
return; return ISC_R_SUCCESS;
} }
/* Run expiry events on every pool. This is called on startup so that /* Run expiry events on every pool. This is called on startup so that

View File

@ -41,7 +41,7 @@
#ifndef lint #ifndef lint
static char copyright[] = static char copyright[] =
"$Id: omapi.c,v 1.53 2005/03/17 20:15:28 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n"; "$Id: omapi.c,v 1.54 2005/09/30 17:57:32 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@ -1727,88 +1727,83 @@ class_set_value (omapi_object_t *h,
class = (struct class *)h; class = (struct class *)h;
if (!omapi_ds_strcmp (name, "name")) { if (!omapi_ds_strcmp(name, "name")) {
char *tname; char *tname;
if (class -> name) if (class->name)
return ISC_R_EXISTS; return ISC_R_EXISTS;
if ((tname = dmalloc (value -> u.buffer.len+1, MDL)) == NULL) { if ((tname = dmalloc(value->u.buffer.len + 1, MDL)) == NULL) {
return ISC_R_NOMEMORY; return ISC_R_NOMEMORY;
} }
memcpy (tname, value -> u.buffer.value, value -> u.buffer.len); /* tname is null terminated from dmalloc() */
memcpy(tname, value->u.buffer.value, value->u.buffer.len);
if (issubclass) { if (issubclass) {
status = find_class(&superclass, tname, MDL); status = find_class(&superclass, tname, MDL);
dfree(tname, MDL); dfree(tname, MDL);
if (status == ISC_R_NOTFOUND) if (status == ISC_R_NOTFOUND)
return status; return status;
if (class -> superclass != 0) { if (class->superclass != NULL)
class_dereference(&class -> superclass, MDL); class_dereference(&class->superclass, MDL);
}
class_reference(&class->superclass, superclass, MDL);
class_reference(&class -> superclass,
superclass, MDL);
} else if (value -> type == omapi_datatype_data || } else if (value -> type == omapi_datatype_data ||
value -> type == omapi_datatype_string) { value -> type == omapi_datatype_string) {
class -> name = dmalloc (value -> u.buffer.len+1, class->name = dmalloc(value->u.buffer.len + 1, MDL);
MDL); if (!class->name)
if (!class -> name)
return ISC_R_NOMEMORY; return ISC_R_NOMEMORY;
memcpy (class -> name, /* class->name is null-terminated from dmalloc() */
value -> u.buffer.value, memcpy(class->name, value->u.buffer.value,
value -> u.buffer.len); value->u.buffer.len);
class -> name [value -> u.buffer.len] = 0; } else
} else {
return ISC_R_INVALIDARG; return ISC_R_INVALIDARG;
}
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
} }
if (issubclass && !omapi_ds_strcmp(name, "hashstring")) { if (issubclass && !omapi_ds_strcmp(name, "hashstring")) {
if (class -> hash_string.data) if (class->hash_string.data)
return ISC_R_EXISTS; return ISC_R_EXISTS;
if (value -> type == omapi_datatype_data || if (value->type == omapi_datatype_data ||
value -> type == omapi_datatype_string) { value->type == omapi_datatype_string) {
if (!buffer_allocate (&class -> hash_string.buffer, if (!buffer_allocate(&class->hash_string.buffer,
value -> u.buffer.len, MDL)) value->u.buffer.len, MDL))
return ISC_R_NOMEMORY; return ISC_R_NOMEMORY;
class->hash_string.data = class->hash_string.data =
&class->hash_string.buffer -> data[0]; class->hash_string.buffer->data;
memcpy (class -> hash_string.buffer -> data, memcpy(class->hash_string.data, value->u.buffer.value,
value -> u.buffer.value, value->u.buffer.len);
value -> u.buffer.len); class->hash_string.len = value->u.buffer.len;
class -> hash_string.len = value -> u.buffer.len;
} else } else
return ISC_R_INVALIDARG; return ISC_R_INVALIDARG;
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
} }
if (!omapi_ds_strcmp(name, "group")) {
if (value->type == omapi_datatype_data ||
value->type == omapi_datatype_string) {
struct group_object *group = NULL;
if (!omapi_ds_strcmp (name, "group")) { group_hash_lookup(&group, group_name_hash,
if (value -> type == omapi_datatype_data || (char *)value->u.buffer.value,
value -> type == omapi_datatype_string) { value->u.buffer.len, MDL);
struct group_object *group; if (!group || (group->flags & GROUP_OBJECT_DELETED))
group = (struct group_object *)0;
group_hash_lookup (&group, group_name_hash,
(char *)value -> u.buffer.value,
value -> u.buffer.len, MDL);
if (!group || (group -> flags & GROUP_OBJECT_DELETED))
return ISC_R_NOTFOUND; return ISC_R_NOTFOUND;
if (class -> group) if (class->group)
group_dereference (&class -> group, MDL); group_dereference(&class->group, MDL);
group_reference (&class -> group, group -> group, MDL); group_reference(&class->group, group->group, MDL);
group_object_dereference (&group, MDL); group_object_dereference(&group, MDL);
} else } else
return ISC_R_INVALIDARG; return ISC_R_INVALIDARG;
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
} }
@ -1816,62 +1811,56 @@ class_set_value (omapi_object_t *h,
/* note we do not support full expressions via omapi because the /* note we do not support full expressions via omapi because the
expressions parser needs to be re-done to support parsing from expressions parser needs to be re-done to support parsing from
strings and not just files. */ strings and not just files. */
if (!omapi_ds_strcmp (name, "match")) { if (!omapi_ds_strcmp(name, "match")) {
if (value -> type == omapi_datatype_data || if (value->type == omapi_datatype_data ||
value -> type == omapi_datatype_string) { value->type == omapi_datatype_string) {
unsigned minlen = (value -> u.buffer.len > 8 ? unsigned minlen = (value->u.buffer.len > 8 ?
8 : value -> u.buffer.len); 8 : value->u.buffer.len);
if (!strncmp("hardware", if (!strncmp("hardware",
(char *)value -> u.buffer.value, minlen)) (char *)value->u.buffer.value, minlen))
{ {
if (!expression_allocate(&class->submatch, if (!expression_allocate(&class->submatch,
MDL)) { MDL))
return ISC_R_NOMEMORY; return ISC_R_NOMEMORY;
}
class->expr->op = expr_hardware; class->expr->op = expr_hardware;
} else { } else
return ISC_R_INVALIDARG; return ISC_R_INVALIDARG;
} } else
} else {
return ISC_R_INVALIDARG; return ISC_R_INVALIDARG;
}
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
} }
if (!omapi_ds_strcmp (name, "option")) { if (!omapi_ds_strcmp(name, "option")) {
if (value -> type == omapi_datatype_data || if (value->type == omapi_datatype_data ||
value -> type == omapi_datatype_string) { value->type == omapi_datatype_string) {
/* XXXJAB support 'options' here. */ /* XXXJAB support 'options' here. */
/* XXXJAB specifically 'bootfile-name' */ /* XXXJAB specifically 'bootfile-name' */
return ISC_R_INVALIDARG; /* XXX tmp */ return ISC_R_INVALIDARG; /* XXX tmp */
} else { } else
return ISC_R_INVALIDARG; return ISC_R_INVALIDARG;
}
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
} }
/* Try to find some inner object that can take the value. */ /* Try to find some inner object that can take the value. */
if (h -> inner && h -> inner -> type -> set_value) { if (h->inner && h->inner->type->set_value) {
status = ((*(h -> inner -> type -> set_value)) status = ((*(h->inner->type->set_value))
(h -> inner, id, name, value)); (h->inner, id, name, value));
if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED)
return status; return status;
} }
return ISC_R_UNKNOWNATTRIBUTE; return ISC_R_UNKNOWNATTRIBUTE;
} }
isc_result_t dhcp_class_set_value (omapi_object_t *h, isc_result_t dhcp_class_set_value (omapi_object_t *h,
omapi_object_t *id, omapi_object_t *id,
omapi_data_string_t *name, omapi_data_string_t *name,