From: David Hankins Date: Fri, 30 Sep 2005 17:57:32 +0000 (+0000) Subject: Corrections to changes made on HEAD pursuant to review of changes between X-Git-Tag: DHCPv6_parsing_base~53 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=06e77c34fb9817079c106c94e8f15b2a78c99281;p=thirdparty%2Fdhcp.git Corrections to changes made on HEAD pursuant to review of changes between V3.0.3 and HEAD. [ISC-Bugs #15348] --- diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 50899d5c0..dc3f52e8f 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -600,6 +600,12 @@ struct collection { 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. */ struct class { OMAPI_OBJECT_PREAMBLE; @@ -1917,7 +1923,8 @@ int write_failover_state (dhcp_failover_state_t *); #endif int db_printable PROTO ((const char *)); 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); int write_billing_class PROTO ((struct class *)); void commit_leases_timeout PROTO ((void *)); @@ -2460,7 +2467,7 @@ void hw_hash_add PROTO ((struct lease *)); void hw_hash_delete PROTO ((struct lease *)); int write_leases PROTO ((void)); 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 dump_subnets PROTO ((void)); #if defined (DEBUG_MEMORY_LEAKAGE) || \ diff --git a/includes/omapip/hash.h b/includes/omapip/hash.h index b8ecbe6c5..a194accce 100644 --- a/includes/omapip/hash.h +++ b/includes/omapip/hash.h @@ -42,8 +42,8 @@ typedef struct { int foo; } hashed_object_t; -typedef void (*hash_foreach_func) (const unsigned char *, - unsigned, hashed_object_t *); +typedef isc_result_t (*hash_foreach_func)(const unsigned char *, unsigned, + void *); typedef int (*hash_reference) (hashed_object_t **, 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); \ int name##_hash_lookup (type **, hashtype *, bufarg, unsigned, \ const char *, int); \ -int name##_hash_foreach (hashtype *, \ - void (*) (bufarg, unsigned, type *)); \ +int name##_hash_foreach (hashtype *, hash_foreach_func); \ int name##_new_hash (hashtype **, int, 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); \ } \ \ -int name##_hash_foreach (hashtype *table, \ - void (*func) (bufarg, unsigned, type *)) \ +int name##_hash_foreach (hashtype *table, hash_foreach_func func) \ { \ 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) \ diff --git a/omapip/hash.c b/omapip/hash.c index 3031ad9a5..1bd5e124a 100644 --- a/omapip/hash.c +++ b/omapip/hash.c @@ -34,7 +34,7 @@ #ifndef lint 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 */ #include @@ -380,7 +380,9 @@ int hash_foreach (struct hash_table *table, hash_foreach_func func) bp = table -> buckets [i]; while (bp) { 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; count++; } diff --git a/server/Makefile.dist b/server/Makefile.dist index 907fabebd..4d59d0a68 100644 --- a/server/Makefile.dist +++ b/server/Makefile.dist @@ -44,7 +44,7 @@ install: all foo=$${foo}/$$bar; \ if [ ! -d $$foo ]; then \ mkdir $$foo; \ - chmod 755 $$foo; \ + $(CHMOD) 755 $$foo; \ fi; \ done; \ done @@ -56,7 +56,9 @@ install: all $(DESTDIR)$(FFMANDIR)/dhcpd.conf$(FFMANEXT) $(MANINSTALL) $(MANFROM) dhcpd.leases.$(MANCAT)5 $(MANTO) \ $(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: $(MKDEP) $(INCLUDES) $(PREDEFINES) $(SRCS) diff --git a/server/confpars.c b/server/confpars.c index 1332a978b..b66567e14 100644 --- a/server/confpars.c +++ b/server/confpars.c @@ -34,7 +34,7 @@ #ifndef lint 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 */ #include "dhcpd.h" @@ -268,9 +268,11 @@ isc_result_t lease_file_subparse (struct parse *cfile) parse_warn (cfile, "possibly corrupt lease file"); } 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) { - parse_class_declaration (0, cfile, root_group, 3); + parse_class_declaration(0, cfile, root_group, + CLASS_TYPE_SUBCLASS); } else if (token == HOST) { parse_host_declaration (cfile, root_group); } else if (token == GROUP) { @@ -464,7 +466,7 @@ int parse_statement (cfile, group, type, host_decl, declaration) skip_to_semi (cfile); break; } - parse_class_declaration ((struct class **)0, cfile, group, 0); + parse_class_declaration(NULL, cfile, group, CLASS_TYPE_VENDOR); return 1; case USER_CLASS: @@ -475,7 +477,7 @@ int parse_statement (cfile, group, type, host_decl, declaration) skip_to_semi (cfile); break; } - parse_class_declaration ((struct class **)0, cfile, group, 1); + parse_class_declaration(NULL, cfile, group, CLASS_TYPE_USER); return 1; case CLASS: @@ -486,7 +488,7 @@ int parse_statement (cfile, group, type, host_decl, declaration) skip_to_semi (cfile); break; } - parse_class_declaration ((struct class **)0, cfile, group, 2); + parse_class_declaration(NULL, cfile, group, CLASS_TYPE_CLASS); return 1; case SUBCLASS: @@ -497,7 +499,8 @@ int parse_statement (cfile, group, type, host_decl, declaration) skip_to_semi (cfile); break; } - parse_class_declaration ((struct class **)0, cfile, group, 3); + parse_class_declaration(NULL, cfile, group, + CLASS_TYPE_SUBCLASS); return 1; case HARDWARE: @@ -1828,8 +1831,8 @@ int parse_class_declaration (cp, cfile, group, type) struct expression *expr; int new = 1; isc_result_t status = ISC_R_FAILURE; - int deleted = 0; - int dynamic = 0; + int matchedonce = 0; + int submatchedonce = 0; token = next_token (&val, (unsigned *)0, cfile); 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. */ find_class (&pc, val, MDL); - /* If this isn't a subclass, we're updating an existing class. */ - if (pc && type != 0 && type != 1 && type != 3) { - class_reference (&class, pc, MDL); + /* If it is a class, we're updating it. If it's any of the other + * types (subclass, vendor or user class), the named class is a + * reference to the parent class so its mandatory. + */ + if (pc && (type == CLASS_TYPE_CLASS)) { + class_reference(&class, pc, MDL); new = 0; - class_dereference (&pc, MDL); - } - - /* If this _is_ a subclass, there _must_ be a class with the - same name. */ - if (!pc && (type == 0 || type == 1 || type == 3)) { - parse_warn (cfile, "no class named %s", val); - skip_to_semi (cfile); + class_dereference(&pc, MDL); + } else if (!pc && (type != CLASS_TYPE_CLASS)) { + parse_warn(cfile, "no class named %s", val); + skip_to_semi(cfile); return 0; } @@ -1863,7 +1865,7 @@ int parse_class_declaration (cp, cfile, group, type) are turned into subclasses of the implicit classes, and the submatch expression of the implicit classes extracts the contents of 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.buffer = (struct buffer *)0; if (!buffer_allocate (&data.buffer, data.len + 1, MDL)) @@ -1872,7 +1874,7 @@ int parse_class_declaration (cp, cfile, group, type) data.terminated = 1; tname = type ? "implicit-vendor-class" : "implicit-user-class"; - } else if (type == 2) { + } else if (type == CLASS_TYPE_CLASS) { tname = val; } else { tname = (const char *)0; @@ -1887,7 +1889,7 @@ int parse_class_declaration (cp, cfile, group, type) name = (char *)0; /* 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); if (token == STRING) { 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) { memset (&data, 0, sizeof data); if (!parse_cshl (&data, cfile)) { - class_dereference (&pc, MDL); + if (pc) + class_dereference (&pc, MDL); return 0; } } 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 hash data. */ - if (type == 0 || type == 1 || type == 3) + if (type != CLASS_TYPE_CLASS) class_hash_lookup (&class, pc -> hash, (const char *)data.data, data.len, MDL); @@ -1950,6 +1953,8 @@ int parse_class_declaration (cp, cfile, group, type) class -> hash_string.len, (void *)class, MDL); } else { + if (class->group) + group_dereference(&class->group, MDL); if (!clone_group (&class -> group, group, MDL)) 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 statement that causes the vendor or user class ID to 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; if (!executable_statement_allocate (&stmt, MDL)) 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 -> option = dhcp_universe.options - [type + [(type == CLASS_TYPE_VENDOR) ? DHO_VENDOR_CLASS_IDENTIFIER : DHO_USER_CLASS]; } @@ -1975,11 +1980,13 @@ int parse_class_declaration (cp, cfile, group, type) } /* 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) - data_string_forget (&data, MDL); + if (type != CLASS_TYPE_CLASS) + data_string_forget(&data, MDL); /* Spawned classes don't have to have their own settings. */ if (class -> superclass) { @@ -2016,13 +2023,13 @@ int parse_class_declaration (cp, cfile, group, type) parse_warn (cfile, "unexpected end of file"); break; } else if (token == DYNAMIC) { - dynamic = 1; + class->flags |= CLASS_DECL_DYNAMIC; token = next_token (&val, (unsigned *)0, cfile); if (!parse_semi (cfile)) break; continue; } else if (token == TOKEN_DELETED) { - deleted = 1; + class->flags |= CLASS_DECL_DELETED; token = next_token (&val, (unsigned *)0, cfile); if (!parse_semi (cfile)) break; @@ -2038,13 +2045,17 @@ int parse_class_declaration (cp, cfile, group, type) token = peek_token (&val, (unsigned *)0, cfile); if (token != IF) goto submatch; - if (class -> expr) { - parse_warn (cfile, "can't override match."); - skip_to_semi (cfile); + token = next_token (&val, (unsigned *)0, cfile); + if (matchedonce) { + parse_warn(cfile, "A class may only have " + "one 'match if' clause."); + skip_to_semi(cfile); break; } - token = next_token (&val, (unsigned *)0, cfile); - if (!parse_boolean_expression (&class -> expr, cfile, + matchedonce = 1; + if (class->expr) + expression_dereference(&class->expr, MDL); + if (!parse_boolean_expression (&class->expr, cfile, &lose)) { if (!lose) { parse_warn (cfile, @@ -2059,13 +2070,13 @@ int parse_class_declaration (cp, cfile, group, type) parse_semi (cfile); } } else if (token == SPAWN) { + token = next_token (&val, (unsigned *)0, cfile); if (pc) { parse_warn (cfile, "invalid spawn in subclass."); skip_to_semi (cfile); break; } - token = next_token (&val, (unsigned *)0, cfile); class -> spawning = 1; token = next_token (&val, (unsigned *)0, cfile); if (token != WITH) { @@ -2075,13 +2086,16 @@ int parse_class_declaration (cp, cfile, group, type) break; } submatch: - if (class -> submatch) { + if (submatchedonce) { parse_warn (cfile, "can't override existing %s.", "submatch/spawn"); skip_to_semi (cfile); break; } + submatchedonce = 1; + if (class->submatch) + expression_dereference(&class->submatch, MDL); if (!parse_data_expression (&class -> submatch, cfile, &lose)) { if (!lose) { @@ -2113,6 +2127,8 @@ int parse_class_declaration (cp, cfile, group, type) break; } class -> lease_limit = atoi (val); + if (class->billed_leases) + dfree(class->billed_leases, MDL); class -> billed_leases = dmalloc (class -> lease_limit * sizeof (struct lease *), MDL); @@ -2131,19 +2147,21 @@ int parse_class_declaration (cp, cfile, group, type) } } while (1); - if (deleted) { - struct class *theclass = 0; + if (class->flags & CLASS_DECL_DELETED) { + if (type == CLASS_TYPE_CLASS) { + struct class *theclass = NULL; - status = find_class(&theclass, class->name, MDL); - if (status == ISC_R_SUCCESS) { - delete_class(theclass, 0); - class_dereference(&theclass, MDL); - } - } else if (type == 2 && new) { - if (dynamic) { - class->flags |= CLASS_DECL_DYNAMIC; + status = find_class(&theclass, class->name, MDL); + if (status == ISC_R_SUCCESS) { + delete_class(theclass, 0); + class_dereference(&theclass, MDL); + } + } else { + class_hash_delete(pc->hash, + (char *)class->hash_string.data, + class->hash_string.len, MDL); } - + } else if (type == CLASS_TYPE_CLASS && new) { if (!collections -> classes) class_reference (&collections -> classes, class, MDL); else { @@ -2153,10 +2171,8 @@ int parse_class_declaration (cp, cfile, group, type) ; class_reference (&c -> nic, class, MDL); } - } else if (type == 3 && dynamic) { - class->flags |= CLASS_DECL_DYNAMIC; } - + if (cp) /* should always be 0??? */ status = class_reference (cp, class, MDL); class_dereference (&class, MDL); @@ -2851,9 +2867,8 @@ int parse_lease_declaration (struct lease **lp, struct parse *cfile) if (lease -> billing_class) class_dereference (&lease -> billing_class, MDL); - parse_class_declaration - (&class, - cfile, (struct group *)0, 3); + parse_class_declaration(&class, cfile, NULL, + CLASS_TYPE_SUBCLASS); } else { parse_warn (cfile, "expecting \"class\""); if (token != SEMI) diff --git a/server/db.c b/server/db.c index 23ae7f76e..800660075 100644 --- a/server/db.c +++ b/server/db.c @@ -34,7 +34,7 @@ #ifndef lint 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 */ #include "dhcpd.h" @@ -610,102 +610,115 @@ int db_printable_len (s, len) static int print_hash_string(FILE *fp, struct class *class) { int i; - int errors = 0; - for (i = 0; i < class -> hash_string.len; i++) - if (!isascii (class -> hash_string.data [i]) || - !isprint (class -> hash_string.data [i])) + 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 (fp, " \"%.*s\"", - (int)class -> hash_string.len, - class -> hash_string.data); - if (errno) - ++errors; + if (i == class->hash_string.len) { + if (fprintf(fp, " \"%.*s\"", (int)class->hash_string.len, + class->hash_string.data) <= 0) { + log_error("Failure writing hash string: %m"); + return 0; + } } else { - errno = 0; - fprintf (fp, " %2.2x", class -> hash_string.data [0]); - if (errno) - ++errors; - for (i = 1; i < class -> hash_string.len; i++) { - errno = 0; - fprintf (fp, ":%2.2x", - class -> hash_string.data [i]); - if (errno) - ++errors; + if (fprintf(fp, " %2.2x", class->hash_string.data[0]) <= 0) { + log_error("Failure writing hash string: %m"); + return 0; + } + for (i = 1 ; i < class->hash_string.len ; i++) { + if (fprintf(fp, ":%2.2x", + class->hash_string.data[i]) <= 0) { + log_error("Failure writing hash string: %m"); + return 0; + } } - errno = 0; - if (errno) - ++errors; } - return !errors; + return 1; } - -/* XXXJAB this needs to return non-zero on error. */ -void write_named_billing_class (const char *name, unsigned len, - struct class *class) +isc_result_t +write_named_billing_class(const unsigned char *name, unsigned len, + void *object) { + struct class *class = object; + if (class->flags & CLASS_DECL_DYNAMIC) { numclasseswritten++; 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 { - fprintf(db_file, "subclass \"%s\"", - class->superclass->name); - print_hash_string(db_file, class); - fprintf(db_file, " {\n"); + if (fprintf(db_file, "subclass \"%s\"", + class->superclass->name) <= 0) + return ISC_R_IOERROR; + 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) { - fprintf(db_file, " deleted;\n"); + if (fprintf(db_file, " deleted;\n") <= 0) + return ISC_R_IOERROR; } else { - fprintf(db_file, " dynamic;\n"); + if (fprintf(db_file, " dynamic;\n") <= 0) + return ISC_R_IOERROR; } 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) { - 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); - fprintf(db_file, ";\n"); + if (fprintf(db_file, ";\n") <= 0) + return ISC_R_IOERROR; } if (class->submatch != 0) { if (class->spawning) { - fprintf(db_file, " spawn "); + if (fprintf(db_file, " spawn ") <= 0) + return ISC_R_IOERROR; } else { - fprintf(db_file, " match "); + if (fprintf(db_file, " match ") <= 0) + return ISC_R_IOERROR; } 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) { write_statements(db_file, class->statements, 8); } - /* XXXJAB this isn't right, but classes read in off the leases file - don't get the root group assigned to them (due to clone_group() - call). */ - if (class->group != 0 && class->group->authoritative != 0) { - write_statements (db_file, - class -> group -> statements, 8); - } + /* XXXJAB this isn't right, but classes read in off the + leases file don't get the root group assigned to them + (due to clone_group() call). */ + if (class->group != 0 && class->group->authoritative != 0) + write_statements(db_file, 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. */ - class_hash_foreach (class -> hash, write_named_billing_class); + if (class->hash != NULL) { /* yep. recursive. god help us. */ + /* 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 () @@ -748,39 +761,8 @@ int write_billing_class (class) if (errno) ++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); fprintf(db_file, ";"); -#endif class -> dirty = !errors; if (errors) diff --git a/server/mdb.c b/server/mdb.c index e26f23f5b..52e09fff9 100644 --- a/server/mdb.c +++ b/server/mdb.c @@ -34,7 +34,7 @@ #ifndef lint 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 */ #include "dhcpd.h" @@ -59,6 +59,10 @@ isc_result_t enter_class(cd, dynamicp, commit) int commit; { if (!collections -> classes) { + /* A subclass with no parent is invalid. */ + if (cd->name == NULL) + return ISC_R_INVALIDARG; + class_reference (&collections -> classes, cd, MDL); } else if (cd->name != NULL) { /* regular class */ struct class *c = 0; @@ -68,6 +72,7 @@ isc_result_t enter_class(cd, dynamicp, commit) return ISC_R_EXISTS; } + /* Find the tail. */ for (c = collections -> classes; c -> nic; c = c -> nic) /* nothing */ ; @@ -1995,9 +2000,10 @@ int lease_enqueue (struct lease *comp) in each appropriate hash, understanding that it's already by definition in lease_ip_addr_hash. */ -void lease_instantiate (const unsigned char *val, unsigned len, - struct lease *lease) +isc_result_t +lease_instantiate(const unsigned char *val, unsigned len, void *object) { + struct lease *lease = object; struct class *class; /* 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, @@ -2006,22 +2012,28 @@ void lease_instantiate (const unsigned char *val, unsigned len, lease_hash_delete (lease_ip_addr_hash, lease -> ip_addr.iabuf, lease -> ip_addr.len, MDL); - return; + return ISC_R_SUCCESS; } - /* Put the lease on the right queue. */ - lease_enqueue (lease); + /* Put the lease on the right queue. Failure to queue is probably + * 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. */ if (lease -> uid) { uid_hash_add (lease); } - + /* Record it in the hardware address hash if possible. */ if (lease -> hardware_addr.hlen) { hw_hash_add (lease); } - + /* If the lease has a billing class, set up the billing. */ if (lease -> billing_class) { class = (struct class *)0; @@ -2036,7 +2048,7 @@ void lease_instantiate (const unsigned char *val, unsigned len, bill_class (lease, class); class_dereference (&class, MDL); } - return; + return ISC_R_SUCCESS; } /* Run expiry events on every pool. This is called on startup so that diff --git a/server/omapi.c b/server/omapi.c index 02de07b0b..74deaf75b 100644 --- a/server/omapi.c +++ b/server/omapi.c @@ -41,7 +41,7 @@ #ifndef lint 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 */ #include "dhcpd.h" @@ -1727,88 +1727,83 @@ class_set_value (omapi_object_t *h, class = (struct class *)h; - if (!omapi_ds_strcmp (name, "name")) { + if (!omapi_ds_strcmp(name, "name")) { char *tname; - if (class -> name) + if (class->name) 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; } - - 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) { status = find_class(&superclass, tname, MDL); dfree(tname, MDL); - + if (status == ISC_R_NOTFOUND) return status; - - if (class -> superclass != 0) { - class_dereference(&class -> superclass, MDL); - } - - class_reference(&class -> superclass, - superclass, MDL); + + if (class->superclass != NULL) + class_dereference(&class->superclass, MDL); + + class_reference(&class->superclass, superclass, MDL); } else if (value -> type == omapi_datatype_data || value -> type == omapi_datatype_string) { - class -> name = dmalloc (value -> u.buffer.len+1, - MDL); - if (!class -> name) + class->name = dmalloc(value->u.buffer.len + 1, MDL); + if (!class->name) return ISC_R_NOMEMORY; - memcpy (class -> name, - value -> u.buffer.value, - value -> u.buffer.len); - class -> name [value -> u.buffer.len] = 0; - } else { + /* class->name is null-terminated from dmalloc() */ + memcpy(class->name, value->u.buffer.value, + value->u.buffer.len); + } else return ISC_R_INVALIDARG; - } - + return ISC_R_SUCCESS; } if (issubclass && !omapi_ds_strcmp(name, "hashstring")) { - if (class -> hash_string.data) + if (class->hash_string.data) return ISC_R_EXISTS; - - if (value -> type == omapi_datatype_data || - value -> type == omapi_datatype_string) { - if (!buffer_allocate (&class -> hash_string.buffer, - value -> u.buffer.len, MDL)) + + if (value->type == omapi_datatype_data || + value->type == omapi_datatype_string) { + if (!buffer_allocate(&class->hash_string.buffer, + value->u.buffer.len, MDL)) return ISC_R_NOMEMORY; class->hash_string.data = - &class->hash_string.buffer -> data[0]; - memcpy (class -> hash_string.buffer -> data, - value -> u.buffer.value, - value -> u.buffer.len); - class -> hash_string.len = value -> u.buffer.len; + class->hash_string.buffer->data; + memcpy(class->hash_string.data, value->u.buffer.value, + value->u.buffer.len); + class->hash_string.len = value->u.buffer.len; } else - return ISC_R_INVALIDARG; + return ISC_R_INVALIDARG; + 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")) { - if (value -> type == omapi_datatype_data || - value -> type == omapi_datatype_string) { - struct group_object *group; - 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)) + 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; - if (class -> group) - group_dereference (&class -> group, MDL); - group_reference (&class -> group, group -> group, MDL); - group_object_dereference (&group, MDL); + if (class->group) + group_dereference(&class->group, MDL); + group_reference(&class->group, group->group, MDL); + group_object_dereference(&group, MDL); } else return ISC_R_INVALIDARG; + 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 expressions parser needs to be re-done to support parsing from strings and not just files. */ - - if (!omapi_ds_strcmp (name, "match")) { - if (value -> type == omapi_datatype_data || - value -> type == omapi_datatype_string) { - unsigned minlen = (value -> u.buffer.len > 8 ? - 8 : value -> u.buffer.len); - + + if (!omapi_ds_strcmp(name, "match")) { + if (value->type == omapi_datatype_data || + value->type == omapi_datatype_string) { + unsigned minlen = (value->u.buffer.len > 8 ? + 8 : value->u.buffer.len); + if (!strncmp("hardware", - (char *)value -> u.buffer.value, minlen)) + (char *)value->u.buffer.value, minlen)) { if (!expression_allocate(&class->submatch, - MDL)) { + MDL)) return ISC_R_NOMEMORY; - } - + class->expr->op = expr_hardware; - } else { + } else return ISC_R_INVALIDARG; - } - } else { + } else return ISC_R_INVALIDARG; - } - + return ISC_R_SUCCESS; } - if (!omapi_ds_strcmp (name, "option")) { - if (value -> type == omapi_datatype_data || - value -> type == omapi_datatype_string) { + if (!omapi_ds_strcmp(name, "option")) { + if (value->type == omapi_datatype_data || + value->type == omapi_datatype_string) { /* XXXJAB support 'options' here. */ /* XXXJAB specifically 'bootfile-name' */ return ISC_R_INVALIDARG; /* XXX tmp */ - } else { + } else return ISC_R_INVALIDARG; - } - + return ISC_R_SUCCESS; } - /* Try to find some inner object that can take the value. */ - if (h -> inner && h -> inner -> type -> set_value) { - status = ((*(h -> inner -> type -> set_value)) - (h -> inner, id, name, value)); + if (h->inner && h->inner->type->set_value) { + status = ((*(h->inner->type->set_value)) + (h->inner, id, name, value)); if (status == ISC_R_SUCCESS || status == ISC_R_UNCHANGED) return status; } - + return ISC_R_UNKNOWNATTRIBUTE; } - isc_result_t dhcp_class_set_value (omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name,