33#define LEASE_REWRITE_PERIOD 3600
35static isc_result_t write_binding_scope(FILE *
db_file,
struct binding *bnd,
40static int counting = 0;
49write_binding_scope(FILE *
db_file,
struct binding *bnd,
char *prepend) {
52 if ((
db_file == NULL) || (bnd == NULL) || (prepend == NULL))
61 fprintf(
db_file,
"%sset %s = %s;",
62 prepend, bnd->
name, s);
70 }
else if (bnd->
value->
type == binding_numeric) {
72 fprintf(
db_file,
"%sset %s = %%%ld;", prepend,
76 }
else if (bnd->
value->
type == binding_boolean) {
78 fprintf(
db_file,
"%sset %s = %s;", prepend, bnd->
name,
82 }
else if (bnd->
value->
type == binding_dns) {
83 log_error(
"%s: persistent dns values not supported.",
85 }
else if (bnd->
value->
type == binding_function) {
86 log_error(
"%s: persistent functions not supported.",
122 fprintf(
db_file,
"\n starts %s", tval) < 0))
127 fprintf(
db_file,
"\n ends %s", tval) < 0))
132 fprintf(
db_file,
"\n tstp %s", tval) < 0))
137 fprintf(
db_file,
"\n tsfp %s", tval) < 0))
142 fprintf(
db_file,
"\n atsfp %s", tval) < 0))
147 fprintf(
db_file,
"\n cltt %s", tval) < 0))
150 if (fprintf (
db_file,
"\n binding state %s;",
151 ((
lease -> binding_state > 0 &&
157 if (
lease -> binding_state !=
lease -> next_binding_state)
158 if (fprintf (
db_file,
"\n next binding state %s;",
159 ((
lease -> next_binding_state > 0 &&
162 [
lease -> next_binding_state - 1])
176 (fprintf(
db_file,
"\n rewind binding state %s;",
181 if (fprintf(
db_file,
"\n reserved;") < 0)
185 if (fprintf(
db_file,
"\n dynamic-bootp;") < 0)
198 if (
lease -> hardware_addr.hlen) {
200 fprintf (
db_file,
"\n hardware %s %s;",
203 lease -> hardware_addr.hlen - 1,
204 &
lease -> hardware_addr.hbuf [1]));
208 if (
lease -> uid_len) {
213 fprintf (
db_file,
"\n uid %s;", s);
236 memset (&ds, 0,
sizeof ds);
241 fprintf (
db_file,
"\n option agent.%s %s;",
250 if (
lease -> client_hostname &&
255 fprintf (
db_file,
"\n client-hostname \"%s\";", s);
264 fprintf (
db_file,
"\n on expiry%s {",
266 ?
" or release" :
"");
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 ?
"," :
"");
415 if (host -> named_group) {
417 fprintf (
db_file,
"\n group \"%s\";",
418 host -> named_group -> name);
424 (!host -> named_group ||
425 host ->
group != host -> named_group ->
group) &&
429 host ->
group -> statements, 8);
441 log_info (
"write_host: unable to write host %s",
473 fprintf (
db_file,
"\n dynamic;");
480 fprintf (
db_file,
"\n static;");
487 fprintf (
db_file,
"\n deleted;");
506 log_info (
"write_group: unable to write group %s",
522 char addr_buf[
sizeof(
"ffff:ffff:ffff:ffff:ffff:ffff.255.255.255.255")];
523 const char *binding_state;
570 fprintf_ret = fprintf(
db_file,
"ia-na %s {\n", s);
573 fprintf_ret = fprintf(
db_file,
"ia-ta %s {\n", s);
576 fprintf_ret = fprintf(
db_file,
"ia-pd %s {\n", s);
579 log_error(
"Unknown ia type %u for %s at %s:%d",
584 if (fprintf_ret < 0) {
592 if (fprintf(
db_file,
" cltt %s\n", tval) < 0) {
600 addr_buf,
sizeof(addr_buf));
602 (fprintf(
db_file,
" iaaddr %s {\n", addr_buf) < 0)) {
606 (fprintf(
db_file,
" iaprefix %s/%d {\n",
611 log_fatal(
"Unknown iasubopt state %d at %s:%d",
615 if (fprintf(
db_file,
" binding state %s;\n",
616 binding_state) < 0) {
619 if (fprintf(
db_file,
" preferred-life %u;\n",
623 if (fprintf(
db_file,
" max-life %u;\n",
641 if (fprintf(
db_file,
" ends %s", tval) < 0) {
653 for (; bnd != NULL ; bnd = bnd->
next) {
654 if (bnd->
value == NULL)
660 if (write_binding_scope(
db_file, bnd,
667 if (fprintf(
db_file,
"\n on expiry%s {",
670 ?
" or release" :
"") < 0)
674 if (fprintf(
db_file,
"\n }") < 0)
681 if (fprintf(
db_file,
"\n on release {") < 0)
685 if (fprintf(
db_file,
"\n }") < 0)
689 if (fprintf(
db_file,
"\n }\n") < 0)
692 if (fprintf(
db_file,
"}\n\n") < 0)
699 log_info(
"write_ia: unable to write ia");
734 memset(&server_duid, 0,
sizeof(server_duid));
746 fprintf_ret = fprintf(
db_file,
"server-duid %s;\n\n", s);
748 if (fprintf_ret < 0) {
759 log_info(
"write_server_duid: unable to write server-duid");
765#if defined (FAILOVER_PROTOCOL)
776 fprintf (
db_file,
"\nfailover peer \"%s\" state {", state -> name);
782 fprintf(
db_file,
"\n my state %s at %s",
791 fprintf(
db_file,
"\n partner state %s at %s",
796 if (state -> i_am == secondary) {
798 fprintf (
db_file,
"\n mclt %ld;",
799 (
unsigned long)state -> mclt);
810 log_info (
"write_failover_state: unable to write state %s",
822 const unsigned char *s;
825 for (i = 0; s [i]; i++)
826 if (!isascii (s [i]) || !isprint (s [i])
827 || s [i] ==
'"' || s [i] ==
'\\')
833 const unsigned char *s;
838 for (i = 0; i <
len; i++)
839 if (!isascii (s [i]) || !isprint (s [i]) ||
840 s [i] ==
'"' || s [i] ==
'\\')
845static int print_hash_string(FILE *fp,
struct class *
class)
849 for (i = 0 ; i <
class->hash_string.len ; i++)
857 log_error(
"Failure writing hash string: %m");
862 log_error(
"Failure writing hash string: %m");
865 for (i = 1 ; i <
class->hash_string.len ; i++) {
866 if (fprintf(fp,
":%2.2x",
868 log_error(
"Failure writing hash string: %m");
881 const unsigned char *name = key;
882 struct class *
class = object;
887 if (fprintf(
db_file,
"class \"%s\" {\n", name) <= 0)
888 return ISC_R_IOERROR;
890 if (fprintf(
db_file,
"subclass \"%s\"",
892 return ISC_R_IOERROR;
893 if (!print_hash_string(
db_file,
class))
894 return ISC_R_IOERROR;
895 if (fprintf(
db_file,
" {\n") <= 0)
896 return ISC_R_IOERROR;
900 if (fprintf(
db_file,
" deleted;\n") <= 0)
901 return ISC_R_IOERROR;
903 if (fprintf(
db_file,
" dynamic;\n") <= 0)
904 return ISC_R_IOERROR;
908 if (fprintf(
db_file,
" lease limit %d;\n",
910 return ISC_R_IOERROR;
914 if (fprintf(
db_file,
" match if ") <= 0)
915 return ISC_R_IOERROR;
920 return ISC_R_IOERROR;
922 if (fprintf(
db_file,
";\n") <= 0)
923 return ISC_R_IOERROR;
928 if (fprintf(
db_file,
" spawn ") <= 0)
929 return ISC_R_IOERROR;
931 if (fprintf(
db_file,
" match ") <= 0)
932 return ISC_R_IOERROR;
938 return ISC_R_IOERROR;
940 if (fprintf(
db_file,
";\n") <= 0)
941 return ISC_R_IOERROR;
948 return ISC_R_IOERROR;
958 return ISC_R_IOERROR;
961 if (fprintf(
db_file,
"}\n\n") <= 0)
962 return ISC_R_IOERROR;
981 for (cp = lp -> classes; cp; cp = cp ->
nic) {
1002 fprintf (
db_file,
"\n billing class \"%s\";",
class ->
name);
1006 if (fprintf(
db_file,
"\n billing subclass \"%s\"",
1010 if (!print_hash_string(
db_file,
class))
1013 if (fprintf(
db_file,
";") < 0)
1016 class -> dirty = !errors;
1036 if (fflush (
db_file) == EOF) {
1037 log_info(
"commit_leases: unable to commit, fflush(): %m");
1041 (fsync(fileno (
db_file)) < 0)) {
1042 log_info (
"commit_leases: unable to commit, fsync(): %m");
1074 const char *current_db_path;
1075 isc_result_t status;
1077#if defined (TRACING)
1086 (
struct group *)0, 0, 1);
1092#if defined (TRACING)
1096#if defined (TRACING)
1107 current_db_path = (test_mode ?
"/dev/null" :
path_dhcpd_db);
1108 db_file = fopen (current_db_path,
"a");
1110 log_fatal (
"Can't open %s for append.", current_db_path);
1114#if defined (TRACING)
1122#if defined(REPORT_HASH_PERFORMANCE)
1135 char newfname [512];
1136 char backfname [512];
1153 if (snprintf (newfname,
sizeof newfname,
"%s.%d",
1155 log_fatal(
"new_lease_file: lease file path too long");
1157 db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0664);
1159 log_error (
"Can't create new lease file: %m");
1163#if defined (PARANOIA)
1170 if ((
set_uid != 0) && (geteuid() == 0) &&
1171 (
set_gid != 0) && (getegid() == 0)) {
1173 log_fatal (
"Can't chown new lease file: %m");
1178 if ((new_db_file = fdopen(db_fd,
"we")) == NULL) {
1179 log_error(
"Can't fdopen new lease file: %m");
1190 fprintf (
db_file,
"# The format of this file is documented in the %s",
1191 "dhcpd.leases(5) manual page.\n");
1196 fprintf (
db_file,
"# This lease file was written by isc-dhcp-%s\n\n",
1201 fprintf (
db_file,
"# authoring-byte-order entry is generated,"
1202 " DO NOT DELETE\n");
1206 fprintf (
db_file,
"authoring-byte-order %s;\n\n",
1208 "little-endian" :
"big-endian"));
1224 " removing temp lease file: %s",
1226 (void)unlink (newfname);
1230#if defined (TRACING)
1239 if (snprintf (backfname,
sizeof backfname,
"%s~",
path_dhcpd_db)
1240 >=
sizeof backfname)
1241 log_fatal(
"new_lease_file: backup lease file path too long");
1244 if (unlink (backfname) < 0 && errno != ENOENT) {
1245 log_error (
"Can't remove old lease database backup %s: %m",
1250 if (errno == ENOENT) {
1251 log_error(
"%s is missing - no lease db to backup.",
1254 log_error(
"Can't backup lease database %s to %s: %m",
1259#if defined (TRACING)
1265 log_error (
"Can't install new lease database %s to %s: %m",
1276 (void)unlink (newfname);
void data_string_forget(struct data_string *data, const char *file, int line)
const char * pretty_print_option(struct option *option, const unsigned char *data, unsigned len, int emit_commas, int emit_quotes)
struct collection * collections
char * format_lease_id(const unsigned char *s, unsigned len, int format, const char *file, int line)
char * quotify_string(const char *s, const char *file, int line)
char * quotify_buf(const unsigned char *s, unsigned len, char enclose_char, const char *file, int line)
char * print_hw_addr(int htype, const int hlen, const unsigned char *data) const
const char * print_time(TIME t)
int write_group(struct group_object *group)
int lease_file_is_corrupt
void commit_leases_timeout(void *foo)
int write_ia(const struct ia_xx *ia)
int write_host(struct host_decl *host)
void write_billing_classes()
int db_printable_len(unsigned char *s, unsigned len) const
int db_printable(unsigned char *s) const
int new_lease_file(int test_mode)
void db_startup(int test_mode)
int write_billing_class(struct class *class)
int commit_leases_timed()
int write_lease(struct lease *lease)
int group_writer(struct group_object *group)
#define LEASE_REWRITE_PERIOD
isc_result_t write_named_billing_class(const void *key, unsigned len, void *object)
int write_billing_class(struct class *)
host_hash_t * host_hw_addr_hash
int write_server_duid(void)
int write_failover_state(dhcp_failover_state_t *)
#define HOST_DECL_DYNAMIC
int write_group(struct group_object *)
#define GROUP_OBJECT_DELETED
#define HOST_DECL_DELETED
lease_id_hash_t * lease_hw_addr_hash
void expire_all_pools(void)
void copy_server_duid(struct data_string *ds, const char *file, int line)
const char * path_dhcpd_db
lease_id_hash_t * lease_uid_hash
host_hash_t * host_uid_hash
int new_lease_file(int test_mode)
#define GROUP_OBJECT_STATIC
#define GROUP_OBJECT_DYNAMIC
isc_boolean_t server_duid_isset(void)
const char * dhcp_failover_state_name_print(enum failover_state)
#define CLASS_DECL_DELETED
isc_result_t read_conf_file(const char *, struct group *, int, int)
const char * binding_state_names[]
isc_result_t write_named_billing_class(const void *, unsigned, void *)
int db_printable_len(const unsigned char *, unsigned)
#define CLASS_DECL_DYNAMIC
lease_ip_hash_t * lease_ip_addr_hash
void write_statements(FILE *file, struct executable_statement *statements, int indent)
struct iaddr ip_addr(struct iaddr subnet, struct iaddr mask, u_int32_t host_address)
const char * piaddr(const struct iaddr addr)
struct group * root_group
void dfree(void *, const char *, int)
int log_error(const char *,...) __attribute__((__format__(__printf__
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int int log_info(const char *,...) __attribute__((__format__(__printf__
#define DHCP_R_INVALIDARG
struct binding * bindings
enum binding_value::@135246253323115003010247222006030375211205217247 type
union binding_value::value value
struct binding_value * value
struct executable_statement * statements
struct expression * submatch
struct class * superclass
struct data_string hash_string
const unsigned char * data
struct executable_statement * statements
struct data_string iaid_duid
struct iasubopt ** iasubopt
time_t hard_lifetime_end_time
struct binding_scope * scope
struct ipv6_pool * ipv6_pool
time_t soft_lifetime_end_time
struct ipv6_pond * ipv6_pond
struct binding_scope * scope
binding_state_t rewind_binding_state
binding_state_t binding_state
struct executable_statement * on_expiry
struct executable_statement * on_release
const char * hardware_types[]
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)
int write_expression(FILE *file, struct expression *expr, int col, int indent, int firstp)
struct binding_scope * global_scope