]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Corrections to changes made on HEAD pursuant to review of changes between
authorDavid Hankins <dhankins@isc.org>
Fri, 30 Sep 2005 17:57:32 +0000 (17:57 +0000)
committerDavid Hankins <dhankins@isc.org>
Fri, 30 Sep 2005 17:57:32 +0000 (17:57 +0000)
V3.0.3 and HEAD.  [ISC-Bugs #15348]

includes/dhcpd.h
includes/omapip/hash.h
omapip/hash.c
server/Makefile.dist
server/confpars.c
server/db.c
server/mdb.c
server/omapi.c

index 50899d5c02842a9842541295f8da7a0da898be1a..dc3f52e8f73036c23790548e4ea6f17e7625155c 100644 (file)
@@ -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) || \
index b8ecbe6c5b549726117d5f45c90b941c8550dba8..a194acccef327433d8de87d60ffa85770cf5d92a 100644 (file)
@@ -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)       \
index 3031ad9a59cca9bb67909ca73a6a4c98e938ba6c..1bd5e124a77807179b94d39d27c71a31a6f65692 100644 (file)
@@ -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 <omapip/omapip_p.h>
@@ -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++;
                }
index 907fabebd14584b7c55469377b7cfa1df5cb9319..4d59d0a687c35e615f1670d9177f54721eb33f16 100644 (file)
@@ -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)
index 1332a978ba875206efb2fb43946081c1cd50e84e..b66567e142b94fa933d74c0c1ec1e807f32559cc 100644 (file)
@@ -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)
index 23ae7f76e6318e46a50f47cbd2cf00856982eef4..8006600750bd5ad1158dbb47dec162c155cc6adf 100644 (file)
@@ -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)
index e26f23f5b3b424c39547ce558aabc34b72b2326f..52e09fff91b0311d3f7de55d2cb0bde2c116835b 100644 (file)
@@ -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
index 02de07b0be3e87937191f6cf3e354bf124c7666b..74deaf75b8496eaa79d92b753c02856de8b1f9e8 100644 (file)
@@ -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,