34 #define LEASE_REWRITE_PERIOD 3600 36 static isc_result_t write_binding_scope(FILE *
db_file,
struct binding *bnd,
41 static int counting = 0;
50 write_binding_scope(FILE *
db_file,
struct binding *bnd,
char *prepend) {
53 if ((db_file == NULL) || (bnd == NULL) || (prepend == NULL))
62 fprintf(db_file,
"%sset %s = \"%s\";",
63 prepend, bnd->
name, s);
71 }
else if (bnd->
value->
type == binding_numeric) {
73 fprintf(db_file,
"%sset %s = %%%ld;", prepend,
77 }
else if (bnd->
value->
type == binding_boolean) {
79 fprintf(db_file,
"%sset %s = %s;", prepend, bnd->
name,
83 }
else if (bnd->
value->
type == binding_dns) {
84 log_error(
"%s: persistent dns values not supported.",
86 }
else if (bnd->
value->
type == binding_function) {
87 log_error(
"%s: persistent functions not supported.",
122 ((tval =
print_time(lease->starts)) == NULL ||
123 fprintf(
db_file,
"\n starts %s", tval) < 0))
128 fprintf(
db_file,
"\n ends %s", tval) < 0))
133 fprintf(
db_file,
"\n tstp %s", tval) < 0))
138 fprintf(
db_file,
"\n tsfp %s", tval) < 0))
143 fprintf(
db_file,
"\n atsfp %s", tval) < 0))
148 fprintf(
db_file,
"\n cltt %s", tval) < 0))
151 if (fprintf (
db_file,
"\n binding state %s;",
152 ((lease -> binding_state > 0 &&
158 if (lease -> binding_state != lease -> next_binding_state)
159 if (fprintf (
db_file,
"\n next binding state %s;",
160 ((lease -> next_binding_state > 0 &&
161 lease -> next_binding_state <=
FTS_LAST)
163 [lease -> next_binding_state - 1])
174 if ((lease->binding_state != lease->rewind_binding_state) &&
175 (lease->rewind_binding_state > 0) &&
176 (lease->rewind_binding_state <=
FTS_LAST) &&
177 (fprintf(
db_file,
"\n rewind binding state %s;",
182 if (fprintf(
db_file,
"\n reserved;") < 0)
186 if (fprintf(
db_file,
"\n dynamic-bootp;") < 0)
191 if (lease -> billing_class && lease -> ends >
cur_time) {
194 lease -> billing_class ->
name);
199 if (lease -> hardware_addr.hlen) {
201 fprintf (
db_file,
"\n hardware %s %s;",
204 lease -> hardware_addr.hlen - 1,
205 &lease -> hardware_addr.hbuf [1]));
209 if (lease -> uid_len) {
213 fprintf (
db_file,
"\n uid \"%s\";", s);
221 if (lease->scope != NULL) {
222 for (b = lease->scope->bindings; b; b = b->
next) {
226 if (write_binding_scope(
db_file, b,
"\n ") != ISC_R_SUCCESS)
236 memset (&ds, 0,
sizeof ds);
241 fprintf (
db_file,
"\n option agent.%s %s;",
250 if (lease -> client_hostname &&
251 db_printable((
unsigned char *)lease->client_hostname)) {
255 fprintf (
db_file,
"\n client-hostname \"%s\";", s);
262 if (lease->on_star.on_expiry) {
264 fprintf (
db_file,
"\n on expiry%s {",
265 lease->on_star.on_expiry == lease->on_star.on_release
266 ?
" or release" :
"");
273 if (lease->on_star.on_release &&
274 lease->on_star.on_release != lease->on_star.on_expiry) {
276 fprintf (
db_file,
"\n on release {");
290 log_info (
"write_lease: unable to write lease %s",
318 fprintf (
db_file,
"host %s {", host -> name);
324 fprintf (
db_file,
"\n dynamic;");
331 fprintf (
db_file,
"\n deleted;");
335 if (host -> interface.hlen) {
337 fprintf (
db_file,
"\n hardware %s %s;",
340 host -> interface.hlen - 1,
341 &host -> interface.hbuf [1]));
345 if (host -> client_identifier.len) {
349 host -> client_identifier.len)) {
350 fprintf (
db_file,
"\n uid \"%.*s\";",
351 (
int)host -> client_identifier.len,
352 host -> client_identifier.data);
358 host -> client_identifier.data [0]);
362 i < host -> client_identifier.len; i++) {
366 client_identifier.data [i]);
378 memset (&ip_addrs, 0,
sizeof ip_addrs);
379 if (host -> fixed_addr &&
386 host -> fixed_addr,
MDL)) {
389 fprintf (
db_file,
"\n fixed-address ");
392 for (i = 0; i < ip_addrs.
len - 3; i += 4) {
395 fprintf (
db_file,
"%u.%u.%u.%u%s",
396 ip_addrs.
data [i] & 0xff,
397 ip_addrs.
data [i + 1] & 0xff,
398 ip_addrs.
data [i + 2] & 0xff,
399 ip_addrs.
data [i + 3] & 0xff,
400 i + 7 < ip_addrs.
len ?
"," :
"");
412 if (host -> named_group) {
414 fprintf (
db_file,
"\n group \"%s\";",
415 host -> named_group -> name);
421 (!host -> named_group ||
422 host ->
group != host -> named_group ->
group) &&
426 host ->
group -> statements, 8);
438 log_info (
"write_host: unable to write host %s",
464 fprintf (
db_file,
"group %s {", group -> name);
470 fprintf (
db_file,
"\n dynamic;");
477 fprintf (
db_file,
"\n static;");
484 fprintf (
db_file,
"\n deleted;");
488 if (group -> group) {
491 group -> group -> statements, 8);
503 log_info (
"write_group: unable to write group %s",
519 char addr_buf[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff.255.255.255.255")];
520 const char *binding_state;
546 fprintf_ret = fprintf(
db_file,
"ia-na \"%s\" {\n", s);
549 fprintf_ret = fprintf(
db_file,
"ia-ta \"%s\" {\n", s);
552 fprintf_ret = fprintf(
db_file,
"ia-pd \"%s\" {\n", s);
555 log_error(
"Unknown ia type %u for \"%s\" at %s:%d",
560 if (fprintf_ret < 0) {
568 if (fprintf(
db_file,
" cltt %s\n", tval) < 0) {
575 inet_ntop(AF_INET6, &iasubopt->
addr,
576 addr_buf,
sizeof(addr_buf));
578 (fprintf(
db_file,
" iaaddr %s {\n", addr_buf) < 0)) {
582 (fprintf(
db_file,
" iaprefix %s/%d {\n",
583 addr_buf, (
int)iasubopt->
plen) < 0)) {
587 log_fatal(
"Unknown iasubopt state %d at %s:%d",
591 if (fprintf(
db_file,
" binding state %s;\n",
592 binding_state) < 0) {
595 if (fprintf(
db_file,
" preferred-life %u;\n",
596 (
unsigned)iasubopt->
prefer) < 0) {
599 if (fprintf(
db_file,
" max-life %u;\n",
600 (
unsigned)iasubopt->
valid) < 0) {
617 if (fprintf(
db_file,
" ends %s", tval) < 0) {
624 if (iasubopt->
scope != NULL)
629 for (; bnd != NULL ; bnd = bnd->
next) {
630 if (bnd->
value == NULL)
636 if (write_binding_scope(
db_file, bnd,
637 "\n ") != ISC_R_SUCCESS)
643 if (fprintf(
db_file,
"\n on expiry%s {",
646 ?
" or release" :
"") < 0)
650 if (fprintf(
db_file,
"\n }") < 0)
657 if (fprintf(
db_file,
"\n on release {") < 0)
661 if (fprintf(
db_file,
"\n }") < 0)
665 if (fprintf(
db_file,
"\n }\n") < 0)
668 if (fprintf(
db_file,
"}\n\n") < 0)
675 log_info(
"write_ia: unable to write ia");
710 memset(&server_duid, 0,
sizeof(server_duid));
721 fprintf_ret = fprintf(
db_file,
"server-duid \"%s\";\n\n", s);
723 if (fprintf_ret < 0) {
734 log_info(
"write_server_duid: unable to write server-duid");
740 #if defined (FAILOVER_PROTOCOL) 751 fprintf (
db_file,
"\nfailover peer \"%s\" state {", state -> name);
757 fprintf(
db_file,
"\n my state %s at %s",
766 fprintf(
db_file,
"\n partner state %s at %s",
771 if (state -> i_am == secondary) {
773 fprintf (
db_file,
"\n mclt %ld;",
774 (
unsigned long)state -> mclt);
785 log_info (
"write_failover_state: unable to write state %s",
797 const
unsigned char *s;
800 for (i = 0; s [i]; i++)
801 if (!isascii (s [i]) || !isprint (s [i])
802 || s [i] ==
'"' || s [i] ==
'\\')
808 const
unsigned char *s;
813 for (i = 0; i <
len; i++)
814 if (!isascii (s [i]) || !isprint (s [i]) ||
815 s [i] ==
'"' || s [i] ==
'\\')
820 static int print_hash_string(FILE *fp,
struct class *
class)
824 for (i = 0 ; i <
class->hash_string.len ; i++)
832 log_error(
"Failure writing hash string: %m");
837 log_error(
"Failure writing hash string: %m");
840 for (i = 1 ; i <
class->hash_string.len ; i++) {
841 if (fprintf(fp,
":%2.2x",
843 log_error(
"Failure writing hash string: %m");
856 const unsigned char *name = key;
857 struct class *
class = object;
862 if (fprintf(
db_file,
"class \"%s\" {\n", name) <= 0)
863 return ISC_R_IOERROR;
865 if (fprintf(
db_file,
"subclass \"%s\"",
867 return ISC_R_IOERROR;
868 if (!print_hash_string(
db_file,
class))
869 return ISC_R_IOERROR;
870 if (fprintf(
db_file,
" {\n") <= 0)
871 return ISC_R_IOERROR;
875 if (fprintf(
db_file,
" deleted;\n") <= 0)
876 return ISC_R_IOERROR;
878 if (fprintf(
db_file,
" dynamic;\n") <= 0)
879 return ISC_R_IOERROR;
883 if (fprintf(
db_file,
" lease limit %d;\n",
885 return ISC_R_IOERROR;
889 if (fprintf(
db_file,
" match if ") <= 0)
890 return ISC_R_IOERROR;
895 return ISC_R_IOERROR;
897 if (fprintf(
db_file,
";\n") <= 0)
898 return ISC_R_IOERROR;
903 if (fprintf(
db_file,
" spawn ") <= 0)
904 return ISC_R_IOERROR;
906 if (fprintf(
db_file,
" match ") <= 0)
907 return ISC_R_IOERROR;
913 return ISC_R_IOERROR;
915 if (fprintf(
db_file,
";\n") <= 0)
916 return ISC_R_IOERROR;
923 return ISC_R_IOERROR;
933 return ISC_R_IOERROR;
936 if (fprintf(
db_file,
"}\n\n") <= 0)
937 return ISC_R_IOERROR;
947 return ISC_R_SUCCESS;
956 for (cp = lp -> classes; cp; cp = cp ->
nic) {
977 fprintf (
db_file,
"\n billing class \"%s\";",
class ->
name);
981 if (fprintf(
db_file,
"\n billing subclass \"%s\"",
985 if (!print_hash_string(
db_file,
class))
991 class -> dirty = !errors;
1011 if (fflush (
db_file) == EOF) {
1012 log_info(
"commit_leases: unable to commit, fflush(): %m");
1016 (fsync(fileno (
db_file)) < 0)) {
1017 log_info (
"commit_leases: unable to commit, fsync(): %m");
1050 isc_result_t status;
1052 #if defined (TRACING) 1057 (
struct group *)0, 0, 1);
1058 if (status != ISC_R_SUCCESS) {
1063 #if defined (TRACING) 1067 #if defined (TRACING) 1080 #if defined (TRACING) 1089 #if defined(REPORT_HASH_PERFORMANCE) 1102 char newfname [512];
1103 char backfname [512];
1120 if (snprintf (newfname,
sizeof newfname,
"%s.%d",
1122 log_fatal(
"new_lease_file: lease file path too long");
1124 db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0664);
1126 log_error (
"Can't create new lease file: %m");
1130 #if defined (PARANOIA) 1137 if ((
set_uid != 0) && (geteuid() == 0) &&
1138 (
set_gid != 0) && (getegid() == 0)) {
1140 log_fatal (
"Can't chown new lease file: %m");
1145 if ((new_db_file = fdopen(db_fd,
"we")) == NULL) {
1146 log_error(
"Can't fdopen new lease file: %m");
1157 fprintf (
db_file,
"# The format of this file is documented in the %s",
1158 "dhcpd.leases(5) manual page.\n");
1162 fprintf (
db_file,
"# This lease file was written by isc-dhcp-%s\n\n",
1177 #if defined (TRACING) 1186 if (snprintf (backfname,
sizeof backfname,
"%s~",
path_dhcpd_db)
1187 >=
sizeof backfname)
1188 log_fatal(
"new_lease_file: backup lease file path too long");
1191 if (unlink (backfname) < 0 && errno != ENOENT) {
1192 log_error (
"Can't remove old lease database backup %s: %m",
1197 if (errno == ENOENT) {
1198 log_error(
"%s is missing - no lease db to backup.",
1201 log_error(
"Can't backup lease database %s to %s: %m",
1206 #if defined (TRACING) 1212 log_error (
"Can't install new lease database %s to %s: %m",
1223 (void)unlink (newfname);
#define GROUP_OBJECT_DYNAMIC
lease_id_hash_t * lease_uid_hash
struct binding_scope * global_scope
const char * hardware_types[]
int write_failover_state(dhcp_failover_state_t *)
void write_billing_classes()
int group_writer(struct group_object *group)
char * quotify_buf(const unsigned char *s, unsigned len, const char *file, int line)
const char * piaddr(const struct iaddr addr)
int write_ia(const struct ia_xx *ia)
void expire_all_pools(void)
isc_boolean_t server_duid_isset(void)
struct class * superclass
struct iaddr ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
char * print_hw_addr(int htype, const int hlen, const unsigned char *data) const
#define HOST_DECL_DYNAMIC
#define DHCP_R_INVALIDARG
#define CLASS_DECL_DELETED
host_hash_t * host_uid_hash
struct executable_statement * on_release
int commit_leases_timed()
void data_string_forget(struct data_string *data, const char *file, int line)
int write_lease(struct lease *lease)
const char * pretty_print_option(struct option *option, const unsigned char *data, unsigned len, int emit_commas, int emit_quotes)
struct group * root_group
enum binding_value::@15 type
struct data_string hash_string
const char * path_dhcpd_db
int log_error(const char *,...) __attribute__((__format__(__printf__
struct collection * collections
#define HOST_DECL_DELETED
lease_id_hash_t * lease_hw_addr_hash
void commit_leases_timeout(void *foo)
struct binding_scope * scope
void copy_server_duid(struct data_string *ds, const char *file, int line)
int lease_file_is_corrupt
int write_host(struct host_decl *host)
void log_fatal(const char *,...) __attribute__((__format__(__printf__
struct executable_statement * statements
const char * print_time(TIME t)
#define CLASS_DECL_DYNAMIC
time_t hard_lifetime_end_time
int evaluate_option_cache(struct data_string *result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *cfg_options, struct binding_scope **scope, struct option_cache *oc, const char *file, int line)
#define LEASE_REWRITE_PERIOD
int write_billing_class(struct class *class)
int write_server_duid(void)
host_hash_t * host_hw_addr_hash
struct data_string iaid_duid
const char * dhcp_failover_state_name_print(enum failover_state)
struct expression * submatch
void dfree(void *, const char *, int)
int int log_info(const char *,...) __attribute__((__format__(__printf__
void write_statements(FILE *file, struct executable_statement *statements, int indent)
#define GROUP_OBJECT_DELETED
isc_result_t write_named_billing_class(const void *key, unsigned len, void *object)
union binding_value::value value
int db_printable(unsigned char *s) const
struct binding * bindings
struct executable_statement * statements
struct binding_value * value
int write_group(struct group_object *group)
time_t soft_lifetime_end_time
struct iasubopt ** iasubopt
const char * binding_state_names[]
struct executable_statement * on_expiry
int write_expression(FILE *file, struct expression *expr, int col, int indent, int firstp)
void db_startup(int testp)
isc_result_t read_conf_file(const char *, struct group *, int, int)
char * quotify_string(const char *s, const char *file, int line)
const unsigned char * data
lease_ip_hash_t * lease_ip_addr_hash
#define GROUP_OBJECT_STATIC
int db_printable_len(unsigned char *s, unsigned len) const