mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-29 13:28:14 +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:
parent
c75473d800
commit
06e77c34fb
@ -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) || \
|
||||
|
@ -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) \
|
||||
|
@ -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++;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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,6 +1908,7 @@ 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)) {
|
||||
if (pc)
|
||||
class_dereference (&pc, MDL);
|
||||
return 0;
|
||||
}
|
||||
@ -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;
|
||||
} 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,8 +2171,6 @@ 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??? */
|
||||
@ -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)
|
||||
|
152
server/db.c
152
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;
|
||||
} 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 (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 {
|
||||
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);
|
||||
|
||||
if (fprintf(db_file, "}\n\n") <= 0)
|
||||
return ISC_R_IOERROR;
|
||||
}
|
||||
|
||||
fprintf(db_file, "}\n\n");
|
||||
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);
|
||||
}
|
||||
|
||||
if (class -> hash != NULL) { /* yep. recursive. god help us. */
|
||||
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)
|
||||
|
26
server/mdb.c
26
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,11 +2012,17 @@ 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) {
|
||||
@ -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
|
||||
|
119
server/omapi.c
119
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,17 +1727,18 @@ 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);
|
||||
@ -1746,69 +1747,63 @@ class_set_value (omapi_object_t *h,
|
||||
if (status == ISC_R_NOTFOUND)
|
||||
return status;
|
||||
|
||||
if (class -> superclass != 0) {
|
||||
class_dereference(&class -> superclass, MDL);
|
||||
}
|
||||
if (class->superclass != NULL)
|
||||
class_dereference(&class->superclass, MDL);
|
||||
|
||||
class_reference(&class -> superclass,
|
||||
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_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;
|
||||
}
|
||||
|
||||
@ -1817,51 +1812,46 @@ class_set_value (omapi_object_t *h,
|
||||
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;
|
||||
}
|
||||
@ -1871,7 +1861,6 @@ class_set_value (omapi_object_t *h,
|
||||
|
||||
|
||||
|
||||
|
||||
isc_result_t dhcp_class_set_value (omapi_object_t *h,
|
||||
omapi_object_t *id,
|
||||
omapi_data_string_t *name,
|
||||
|
Loading…
x
Reference in New Issue
Block a user