33 #define LEASE_REWRITE_PERIOD 3600 35 static isc_result_t write_binding_scope(FILE *
db_file,
struct binding *bnd,
40 static int counting = 0;
49 write_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.",
121 ((tval =
print_time(lease->starts)) == NULL ||
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 &&
160 lease -> next_binding_state <=
FTS_LAST)
162 [lease -> next_binding_state - 1])
173 if ((lease->binding_state != lease->rewind_binding_state) &&
174 (lease->rewind_binding_state > 0) &&
175 (lease->rewind_binding_state <=
FTS_LAST) &&
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)
190 if (lease -> billing_class && lease -> ends >
cur_time) {
193 lease -> billing_class ->
name);
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);
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 ?
"," :
"");
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",
467 fprintf (
db_file,
"group %s {", group -> name);
473 fprintf (
db_file,
"\n dynamic;");
480 fprintf (
db_file,
"\n static;");
487 fprintf (
db_file,
"\n deleted;");
491 if (group -> group) {
494 group -> group -> statements, 8);
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;
549 fprintf_ret = fprintf(
db_file,
"ia-na %s {\n", s);
552 fprintf_ret = fprintf(
db_file,
"ia-ta %s {\n", s);
555 fprintf_ret = fprintf(
db_file,
"ia-pd %s {\n", s);
558 log_error(
"Unknown ia type %u for %s at %s:%d",
563 if (fprintf_ret < 0) {
571 if (fprintf(
db_file,
" cltt %s\n", tval) < 0) {
578 inet_ntop(AF_INET6, &iasubopt->
addr,
579 addr_buf,
sizeof(addr_buf));
581 (fprintf(
db_file,
" iaaddr %s {\n", addr_buf) < 0)) {
585 (fprintf(
db_file,
" iaprefix %s/%d {\n",
586 addr_buf, (
int)iasubopt->
plen) < 0)) {
590 log_fatal(
"Unknown iasubopt state %d at %s:%d",
594 if (fprintf(
db_file,
" binding state %s;\n",
595 binding_state) < 0) {
598 if (fprintf(
db_file,
" preferred-life %u;\n",
599 (
unsigned)iasubopt->
prefer) < 0) {
602 if (fprintf(
db_file,
" max-life %u;\n",
603 (
unsigned)iasubopt->
valid) < 0) {
620 if (fprintf(
db_file,
" ends %s", tval) < 0) {
627 if (iasubopt->
scope != NULL)
632 for (; bnd != NULL ; bnd = bnd->
next) {
633 if (bnd->
value == NULL)
639 if (write_binding_scope(
db_file, bnd,
640 "\n ") != ISC_R_SUCCESS)
646 if (fprintf(
db_file,
"\n on expiry%s {",
649 ?
" or release" :
"") < 0)
653 if (fprintf(
db_file,
"\n }") < 0)
660 if (fprintf(
db_file,
"\n on release {") < 0)
664 if (fprintf(
db_file,
"\n }") < 0)
668 if (fprintf(
db_file,
"\n }\n") < 0)
671 if (fprintf(
db_file,
"}\n\n") < 0)
678 log_info(
"write_ia: unable to write ia");
713 memset(&server_duid, 0,
sizeof(server_duid));
725 fprintf_ret = fprintf(
db_file,
"server-duid %s;\n\n", s);
727 if (fprintf_ret < 0) {
738 log_info(
"write_server_duid: unable to write server-duid");
744 #if defined (FAILOVER_PROTOCOL) 755 fprintf (
db_file,
"\nfailover peer \"%s\" state {", state -> name);
761 fprintf(
db_file,
"\n my state %s at %s",
770 fprintf(
db_file,
"\n partner state %s at %s",
775 if (state -> i_am == secondary) {
777 fprintf (
db_file,
"\n mclt %ld;",
778 (
unsigned long)state -> mclt);
789 log_info (
"write_failover_state: unable to write state %s",
801 const
unsigned char *s;
804 for (i = 0; s [i]; i++)
805 if (!isascii (s [i]) || !isprint (s [i])
806 || s [i] ==
'"' || s [i] ==
'\\')
812 const
unsigned char *s;
817 for (i = 0; i <
len; i++)
818 if (!isascii (s [i]) || !isprint (s [i]) ||
819 s [i] ==
'"' || s [i] ==
'\\')
824 static int print_hash_string(FILE *fp,
struct class *
class)
828 for (i = 0 ; i <
class->hash_string.len ; i++)
836 log_error(
"Failure writing hash string: %m");
841 log_error(
"Failure writing hash string: %m");
844 for (i = 1 ; i <
class->hash_string.len ; i++) {
845 if (fprintf(fp,
":%2.2x",
847 log_error(
"Failure writing hash string: %m");
860 const unsigned char *name = key;
861 struct class *
class = object;
866 if (fprintf(
db_file,
"class \"%s\" {\n", name) <= 0)
867 return ISC_R_IOERROR;
869 if (fprintf(
db_file,
"subclass \"%s\"",
871 return ISC_R_IOERROR;
872 if (!print_hash_string(
db_file,
class))
873 return ISC_R_IOERROR;
874 if (fprintf(
db_file,
" {\n") <= 0)
875 return ISC_R_IOERROR;
879 if (fprintf(
db_file,
" deleted;\n") <= 0)
880 return ISC_R_IOERROR;
882 if (fprintf(
db_file,
" dynamic;\n") <= 0)
883 return ISC_R_IOERROR;
887 if (fprintf(
db_file,
" lease limit %d;\n",
889 return ISC_R_IOERROR;
893 if (fprintf(
db_file,
" match if ") <= 0)
894 return ISC_R_IOERROR;
899 return ISC_R_IOERROR;
901 if (fprintf(
db_file,
";\n") <= 0)
902 return ISC_R_IOERROR;
907 if (fprintf(
db_file,
" spawn ") <= 0)
908 return ISC_R_IOERROR;
910 if (fprintf(
db_file,
" match ") <= 0)
911 return ISC_R_IOERROR;
917 return ISC_R_IOERROR;
919 if (fprintf(
db_file,
";\n") <= 0)
920 return ISC_R_IOERROR;
927 return ISC_R_IOERROR;
937 return ISC_R_IOERROR;
940 if (fprintf(
db_file,
"}\n\n") <= 0)
941 return ISC_R_IOERROR;
951 return ISC_R_SUCCESS;
960 for (cp = lp -> classes; cp; cp = cp ->
nic) {
981 fprintf (
db_file,
"\n billing class \"%s\";",
class ->
name);
985 if (fprintf(
db_file,
"\n billing subclass \"%s\"",
989 if (!print_hash_string(
db_file,
class))
995 class -> dirty = !errors;
1015 if (fflush (
db_file) == EOF) {
1016 log_info(
"commit_leases: unable to commit, fflush(): %m");
1020 (fsync(fileno (
db_file)) < 0)) {
1021 log_info (
"commit_leases: unable to commit, fsync(): %m");
1054 isc_result_t status;
1056 #if defined (TRACING) 1065 (
struct group *)0, 0, 1);
1066 if (status != ISC_R_SUCCESS) {
1071 #if defined (TRACING) 1075 #if defined (TRACING) 1088 #if defined (TRACING) 1097 #if defined(REPORT_HASH_PERFORMANCE) 1110 char newfname [512];
1111 char backfname [512];
1128 if (snprintf (newfname,
sizeof newfname,
"%s.%d",
1130 log_fatal(
"new_lease_file: lease file path too long");
1132 db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0664);
1134 log_error (
"Can't create new lease file: %m");
1138 #if defined (PARANOIA) 1145 if ((
set_uid != 0) && (geteuid() == 0) &&
1146 (
set_gid != 0) && (getegid() == 0)) {
1148 log_fatal (
"Can't chown new lease file: %m");
1153 if ((new_db_file = fdopen(db_fd,
"we")) == NULL) {
1154 log_error(
"Can't fdopen new lease file: %m");
1165 fprintf (
db_file,
"# The format of this file is documented in the %s",
1166 "dhcpd.leases(5) manual page.\n");
1171 fprintf (
db_file,
"# This lease file was written by isc-dhcp-%s\n\n",
1176 fprintf (
db_file,
"# authoring-byte-order entry is generated," 1177 " DO NOT DELETE\n");
1181 fprintf (
db_file,
"authoring-byte-order %s;\n\n",
1183 "little-endian" :
"big-endian"));
1197 #if defined (TRACING) 1206 if (snprintf (backfname,
sizeof backfname,
"%s~",
path_dhcpd_db)
1207 >=
sizeof backfname)
1208 log_fatal(
"new_lease_file: backup lease file path too long");
1211 if (unlink (backfname) < 0 && errno != ENOENT) {
1212 log_error (
"Can't remove old lease database backup %s: %m",
1217 if (errno == ENOENT) {
1218 log_error(
"%s is missing - no lease db to backup.",
1221 log_error(
"Can't backup lease database %s to %s: %m",
1226 #if defined (TRACING) 1232 log_error (
"Can't install new lease database %s to %s: %m",
1243 (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)
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
char * quotify_buf(const unsigned char *s, unsigned len, char enclose_char, const char *file, int line)
#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
char * format_lease_id(const unsigned char *s, unsigned len, int format, const char *file, int line)
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