]> git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/lease.c
Accumulated 2.60 changes going into git
[people/ms/dnsmasq.git] / src / lease.c
1 /* dnsmasq is Copyright (c) 2000-2011 Simon Kelley
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include "dnsmasq.h"
18
19 #ifdef HAVE_DHCP
20
21 static struct dhcp_lease *leases = NULL, *old_leases = NULL;
22 static int dns_dirty, file_dirty, leases_left;
23
24 void lease_init(time_t now)
25 {
26 unsigned long ei;
27 struct all_addr addr;
28 struct dhcp_lease *lease;
29 int clid_len, hw_len, hw_type;
30 FILE *leasestream;
31 #ifdef HAVE_DHCP6
32 int v6pass = 0;
33 #endif
34
35 /* These each hold a DHCP option max size 255
36 and get a terminating zero added */
37 daemon->dhcp_buff = safe_malloc(256);
38 daemon->dhcp_buff2 = safe_malloc(256);
39 daemon->dhcp_buff3 = safe_malloc(256);
40
41 leases_left = daemon->dhcp_max;
42
43 if (option_bool(OPT_LEASE_RO))
44 {
45 /* run "<lease_change_script> init" once to get the
46 initial state of the database. If leasefile-ro is
47 set without a script, we just do without any
48 lease database. */
49 #ifdef HAVE_SCRIPT
50 if (daemon->lease_change_command)
51 {
52 strcpy(daemon->dhcp_buff, daemon->lease_change_command);
53 strcat(daemon->dhcp_buff, " init");
54 leasestream = popen(daemon->dhcp_buff, "r");
55 }
56 else
57 #endif
58 {
59 file_dirty = dns_dirty = 0;
60 return;
61 }
62
63 }
64 else
65 {
66 /* NOTE: need a+ mode to create file if it doesn't exist */
67 leasestream = daemon->lease_stream = fopen(daemon->lease_file, "a+");
68
69 if (!leasestream)
70 die(_("cannot open or create lease file %s: %s"), daemon->lease_file, EC_FILE);
71
72 /* a+ mode leaves pointer at end. */
73 rewind(leasestream);
74 }
75
76 #ifdef HAVE_DHCP6
77 again:
78 #endif
79
80 /* client-id max length is 255 which is 255*2 digits + 254 colons
81 borrow DNS packet buffer which is always larger than 1000 bytes */
82 if (leasestream)
83 while (fscanf(leasestream, "%lu %255s %64s %255s %764s",
84 &ei, daemon->dhcp_buff2, daemon->namebuff,
85 daemon->dhcp_buff, daemon->packet) == 5)
86 {
87 #ifdef HAVE_DHCP6
88 if (!v6pass)
89 #endif
90 {
91 hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
92 /* For backwards compatibility, no explict MAC address type means ether. */
93 if (hw_type == 0 && hw_len != 0)
94 hw_type = ARPHRD_ETHER;
95 }
96
97 #ifdef HAVE_DHCP6
98 if (v6pass)
99 inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6);
100 else
101 #endif
102 inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4);
103
104 clid_len = 0;
105 if (strcmp(daemon->packet, "*") != 0)
106 clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
107
108 #ifdef HAVE_DHCP6
109 if (v6pass)
110 lease = lease_allocate6(&addr.addr.addr6);
111 else
112 #endif
113 lease = lease_allocate4(addr.addr.addr4);
114
115 if (!lease)
116 die (_("too many stored leases"), NULL, EC_MISC);
117
118 #ifdef HAVE_BROKEN_RTC
119 if (ei != 0)
120 lease->expires = (time_t)ei + now;
121 else
122 lease->expires = (time_t)0;
123 lease->length = ei;
124 #else
125 /* strictly time_t is opaque, but this hack should work on all sane systems,
126 even when sizeof(time_t) == 8 */
127 lease->expires = (time_t)ei;
128 #endif
129
130 #ifdef HAVE_DHCP6
131 if (!v6pass)
132 #endif
133 lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet, hw_len, hw_type, clid_len);
134
135 if (strcmp(daemon->dhcp_buff, "*") != 0)
136 lease_set_hostname(lease, daemon->dhcp_buff, 0);
137
138 /* set these correctly: the "old" events are generated later from
139 the startup synthesised SIGHUP. */
140 lease->new = lease->changed = 0;
141 }
142
143 #ifdef HAVE_DHCP6
144 if (!v6pass)
145 {
146 if (fscanf(leasestream, "duid %255s", daemon->dhcp_buff) == 1)
147 {
148 daemon->duid_len = parse_hex(daemon->dhcp_buff, (unsigned char *)daemon->dhcp_buff, 130, NULL, NULL);
149 daemon->duid = safe_malloc(daemon->duid_len);
150 memcpy(daemon->duid, daemon->dhcp_buff, daemon->duid_len );
151 v6pass = 1;
152 goto again;
153 }
154
155 /* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */
156 if (daemon->dhcp6)
157 make_duid(now);
158 }
159 #endif
160
161 #ifdef HAVE_SCRIPT
162 if (!daemon->lease_stream)
163 {
164 int rc = 0;
165
166 /* shell returns 127 for "command not found", 126 for bad permissions. */
167 if (!leasestream || (rc = pclose(leasestream)) == -1 || WEXITSTATUS(rc) == 127 || WEXITSTATUS(rc) == 126)
168 {
169 if (WEXITSTATUS(rc) == 127)
170 errno = ENOENT;
171 else if (WEXITSTATUS(rc) == 126)
172 errno = EACCES;
173 die(_("cannot run lease-init script %s: %s"), daemon->lease_change_command, EC_FILE);
174 }
175
176 if (WEXITSTATUS(rc) != 0)
177 {
178 sprintf(daemon->dhcp_buff, "%d", WEXITSTATUS(rc));
179 die(_("lease-init script returned exit code %s"), daemon->dhcp_buff, WEXITSTATUS(rc) + EC_INIT_OFFSET);
180 }
181 }
182 #endif
183
184 /* Some leases may have expired */
185 file_dirty = 0;
186 lease_prune(NULL, now);
187 dns_dirty = 1;
188 }
189
190 void lease_update_from_configs(void)
191 {
192 /* changes to the config may change current leases. */
193
194 struct dhcp_lease *lease;
195 struct dhcp_config *config;
196 char *name;
197
198 for (lease = leases; lease; lease = lease->next)
199 if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len,
200 lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) &&
201 (config->flags & CONFIG_NAME) &&
202 (!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr))
203 lease_set_hostname(lease, config->hostname, 1);
204 else if ((name = host_from_dns(lease->addr)))
205 lease_set_hostname(lease, name, 1); /* updates auth flag only */
206 }
207
208 static void ourprintf(int *errp, char *format, ...)
209 {
210 va_list ap;
211
212 va_start(ap, format);
213 if (!(*errp) && vfprintf(daemon->lease_stream, format, ap) < 0)
214 *errp = errno;
215 va_end(ap);
216 }
217
218 void lease_update_file(time_t now)
219 {
220 struct dhcp_lease *lease;
221 time_t next_event;
222 int i, err = 0;
223
224 if (file_dirty != 0 && daemon->lease_stream)
225 {
226 errno = 0;
227 rewind(daemon->lease_stream);
228 if (errno != 0 || ftruncate(fileno(daemon->lease_stream), 0) != 0)
229 err = errno;
230
231 for (lease = leases; lease; lease = lease->next)
232 {
233
234 #ifdef HAVE_DHCP6
235 if (lease->is_ipv6)
236 continue;
237 #endif
238
239 #ifdef HAVE_BROKEN_RTC
240 ourprintf(&err, "%u ", lease->length);
241 #else
242 ourprintf(&err, "%lu ", (unsigned long)lease->expires);
243 #endif
244
245 if (lease->hwaddr_type != ARPHRD_ETHER || lease->hwaddr_len == 0)
246 ourprintf(&err, "%.2x-", lease->hwaddr_type);
247 for (i = 0; i < lease->hwaddr_len; i++)
248 {
249 ourprintf(&err, "%.2x", lease->hwaddr[i]);
250 if (i != lease->hwaddr_len - 1)
251 ourprintf(&err, ":");
252 }
253
254 inet_ntop(AF_INET, &lease->addr, daemon->addrbuff, ADDRSTRLEN);
255
256 ourprintf(&err, " %s ", daemon->addrbuff);
257 ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
258
259 if (lease->clid && lease->clid_len != 0)
260 {
261 for (i = 0; i < lease->clid_len - 1; i++)
262 ourprintf(&err, "%.2x:", lease->clid[i]);
263 ourprintf(&err, "%.2x\n", lease->clid[i]);
264 }
265 else
266 ourprintf(&err, "*\n");
267 }
268
269 #ifdef HAVE_DHCP6
270 if (daemon->duid)
271 {
272 ourprintf(&err, "duid ");
273 for (i = 0; i < daemon->duid_len - 1; i++)
274 ourprintf(&err, "%.2x:", daemon->duid[i]);
275 ourprintf(&err, "%.2x\n", daemon->duid[i]);
276
277 for (lease = leases; lease; lease = lease->next)
278 {
279
280 if (!lease->is_ipv6)
281 continue;
282
283 #ifdef HAVE_BROKEN_RTC
284 ourprintf(&err, "%u ", lease->length);
285 #else
286 ourprintf(&err, "%lu ", (unsigned long)lease->expires);
287 #endif
288
289 inet_ntop(AF_INET6, lease->hwaddr, daemon->addrbuff, ADDRSTRLEN);
290
291 ourprintf(&err, "* %s ", daemon->addrbuff);
292 ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
293
294 if (lease->clid && lease->clid_len != 0)
295 {
296 for (i = 0; i < lease->clid_len - 1; i++)
297 ourprintf(&err, "%.2x:", lease->clid[i]);
298 ourprintf(&err, "%.2x\n", lease->clid[i]);
299 }
300 else
301 ourprintf(&err, "*\n");
302 }
303 }
304 #endif
305
306 if (fflush(daemon->lease_stream) != 0 ||
307 fsync(fileno(daemon->lease_stream)) < 0)
308 err = errno;
309
310 if (!err)
311 file_dirty = 0;
312 }
313
314 /* Set alarm for when the first lease expires + slop. */
315 for (next_event = 0, lease = leases; lease; lease = lease->next)
316 if (lease->expires != 0 &&
317 (next_event == 0 || difftime(next_event, lease->expires + 10) > 0.0))
318 next_event = lease->expires + 10;
319
320 if (err)
321 {
322 if (next_event == 0 || difftime(next_event, LEASE_RETRY + now) > 0.0)
323 next_event = LEASE_RETRY + now;
324
325 my_syslog(MS_DHCP | LOG_ERR, _("failed to write %s: %s (retry in %us)"),
326 daemon->lease_file, strerror(err),
327 (unsigned int)difftime(next_event, now));
328 }
329
330 if (next_event != 0)
331 alarm((unsigned)difftime(next_event, now));
332 }
333
334 void lease_update_dns(void)
335 {
336 struct dhcp_lease *lease;
337
338 if (daemon->port != 0 && dns_dirty)
339 {
340 cache_unhash_dhcp();
341
342 for (lease = leases; lease; lease = lease->next)
343 {
344 if (lease->fqdn)
345 cache_add_dhcp_entry(lease->fqdn, &lease->addr, lease->expires);
346
347 if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
348 cache_add_dhcp_entry(lease->hostname, &lease->addr, lease->expires);
349 }
350
351 dns_dirty = 0;
352 }
353 }
354
355 void lease_prune(struct dhcp_lease *target, time_t now)
356 {
357 struct dhcp_lease *lease, *tmp, **up;
358
359 for (lease = leases, up = &leases; lease; lease = tmp)
360 {
361 tmp = lease->next;
362 if ((lease->expires != 0 && difftime(now, lease->expires) > 0) || lease == target)
363 {
364 file_dirty = 1;
365 if (lease->hostname)
366 dns_dirty = 1;
367
368 *up = lease->next; /* unlink */
369
370 /* Put on old_leases list 'till we
371 can run the script */
372 lease->next = old_leases;
373 old_leases = lease;
374
375 leases_left++;
376 }
377 else
378 up = &lease->next;
379 }
380 }
381
382
383 struct dhcp_lease *lease_find_by_client(unsigned char *hwaddr, int hw_len, int hw_type,
384 unsigned char *clid, int clid_len)
385 {
386 struct dhcp_lease *lease;
387
388 if (clid)
389 for (lease = leases; lease; lease = lease->next)
390 {
391 #ifdef HAVE_DHCP6
392 if (lease->is_ipv6)
393 continue;
394 #endif
395 if (lease->clid && clid_len == lease->clid_len &&
396 memcmp(clid, lease->clid, clid_len) == 0)
397 return lease;
398 }
399
400 for (lease = leases; lease; lease = lease->next)
401 {
402 #ifdef HAVE_DHCP6
403 if (lease->is_ipv6)
404 continue;
405 #endif
406 if ((!lease->clid || !clid) &&
407 hw_len != 0 &&
408 lease->hwaddr_len == hw_len &&
409 lease->hwaddr_type == hw_type &&
410 memcmp(hwaddr, lease->hwaddr, hw_len) == 0)
411 return lease;
412 }
413
414 return NULL;
415 }
416
417 struct dhcp_lease *lease_find_by_addr(struct in_addr addr)
418 {
419 struct dhcp_lease *lease;
420
421 for (lease = leases; lease; lease = lease->next)
422 {
423 #ifdef HAVE_DHCP6
424 if (lease->is_ipv6)
425 continue;
426 #endif
427 if (lease->addr.s_addr == addr.s_addr)
428 return lease;
429 }
430
431 return NULL;
432 }
433
434 /* Find largest assigned address in context */
435 struct in_addr lease_find_max_addr(struct dhcp_context *context)
436 {
437 struct dhcp_lease *lease;
438 struct in_addr addr = context->start;
439
440 if (!(context->flags & (CONTEXT_STATIC | CONTEXT_PROXY)))
441 for (lease = leases; lease; lease = lease->next)
442 {
443 #ifdef HAVE_DHCP6
444 if (lease->is_ipv6)
445 continue;
446 #endif
447 if (((unsigned)ntohl(lease->addr.s_addr)) > ((unsigned)ntohl(context->start.s_addr)) &&
448 ((unsigned)ntohl(lease->addr.s_addr)) <= ((unsigned)ntohl(context->end.s_addr)) &&
449 ((unsigned)ntohl(lease->addr.s_addr)) > ((unsigned)ntohl(addr.s_addr)))
450 addr = lease->addr;
451 }
452
453 return addr;
454 }
455
456 static struct dhcp_lease *lease_allocate(void)
457 {
458 struct dhcp_lease *lease;
459 if (!leases_left || !(lease = whine_malloc(sizeof(struct dhcp_lease))))
460 return NULL;
461
462 memset(lease, 0, sizeof(struct dhcp_lease));
463 lease->new = 1;
464 lease->expires = 1;
465 #ifdef HAVE_BROKEN_RTC
466 lease->length = 0xffffffff; /* illegal value */
467 #endif
468 lease->next = leases;
469 leases = lease;
470
471 file_dirty = 1;
472 leases_left--;
473
474 return lease;
475 }
476
477 struct dhcp_lease *lease_allocate4(struct in_addr addr)
478 {
479 struct dhcp_lease *lease = lease_allocate();
480 lease->addr = addr;
481 lease->hwaddr_len = 256; /* illegal value */
482
483 return lease;
484 }
485
486 #ifdef HAVE_DHCP6
487 struct dhcp_lease *lease_allocate6(struct in6_addr *addrp)
488 {
489 struct dhcp_lease *lease = lease_allocate();
490 memcpy(lease->hwaddr, addrp, sizeof(*addrp)) ;
491 lease->is_ipv6 = 1;
492
493 return lease;
494 }
495 #endif
496
497 void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now)
498 {
499 time_t exp = now + (time_t)len;
500
501 if (len == 0xffffffff)
502 {
503 exp = 0;
504 len = 0;
505 }
506
507 if (exp != lease->expires)
508 {
509 dns_dirty = 1;
510 lease->expires = exp;
511 #ifndef HAVE_BROKEN_RTC
512 lease->aux_changed = file_dirty = 1;
513 #endif
514 }
515
516 #ifdef HAVE_BROKEN_RTC
517 if (len != lease->length)
518 {
519 lease->length = len;
520 lease->aux_changed = file_dirty = 1;
521 }
522 #endif
523 }
524
525 void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
526 unsigned char *clid, int hw_len, int hw_type, int clid_len)
527 {
528 if (hw_len != lease->hwaddr_len ||
529 hw_type != lease->hwaddr_type ||
530 (hw_len != 0 && memcmp(lease->hwaddr, hwaddr, hw_len) != 0))
531 {
532 memcpy(lease->hwaddr, hwaddr, hw_len);
533 lease->hwaddr_len = hw_len;
534 lease->hwaddr_type = hw_type;
535 lease->changed = file_dirty = 1; /* run script on change */
536 }
537
538 /* only update clid when one is available, stops packets
539 without a clid removing the record. Lease init uses
540 clid_len == 0 for no clid. */
541 if (clid_len != 0 && clid)
542 {
543 if (!lease->clid)
544 lease->clid_len = 0;
545
546 if (lease->clid_len != clid_len)
547 {
548 lease->aux_changed = file_dirty = 1;
549 free(lease->clid);
550 if (!(lease->clid = whine_malloc(clid_len)))
551 return;
552 }
553 else if (memcmp(lease->clid, clid, clid_len) != 0)
554 lease->aux_changed = file_dirty = 1;
555
556 lease->clid_len = clid_len;
557 memcpy(lease->clid, clid, clid_len);
558 }
559
560 }
561
562 static void kill_name(struct dhcp_lease *lease)
563 {
564 /* run script to say we lost our old name */
565
566 /* this shouldn't happen unless updates are very quick and the
567 script very slow, we just avoid a memory leak if it does. */
568 free(lease->old_hostname);
569
570 /* If we know the fqdn, pass that. The helper will derive the
571 unqualified name from it, free the unqulaified name here. */
572
573 if (lease->fqdn)
574 {
575 lease->old_hostname = lease->fqdn;
576 free(lease->hostname);
577 }
578 else
579 lease->old_hostname = lease->hostname;
580
581 lease->hostname = lease->fqdn = NULL;
582 }
583
584 void lease_set_hostname(struct dhcp_lease *lease, char *name, int auth)
585 {
586 struct dhcp_lease *lease_tmp;
587 char *new_name = NULL, *new_fqdn = NULL;
588
589 if (lease->hostname && name && hostname_isequal(lease->hostname, name))
590 {
591 lease->auth_name = auth;
592 return;
593 }
594
595 if (!name && !lease->hostname)
596 return;
597
598 /* If a machine turns up on a new net without dropping the old lease,
599 or two machines claim the same name, then we end up with two interfaces with
600 the same name. Check for that here and remove the name from the old lease.
601 Don't allow a name from the client to override a name from dnsmasq config. */
602
603 if (name)
604 {
605 if ((new_name = whine_malloc(strlen(name) + 1)))
606 {
607 char *suffix = get_domain(lease->addr);
608 strcpy(new_name, name);
609 if (suffix && (new_fqdn = whine_malloc(strlen(new_name) + strlen(suffix) + 2)))
610 {
611 strcpy(new_fqdn, name);
612 strcat(new_fqdn, ".");
613 strcat(new_fqdn, suffix);
614 }
615 }
616
617 /* Depending on mode, we check either unqualified name or FQDN. */
618 for (lease_tmp = leases; lease_tmp; lease_tmp = lease_tmp->next)
619 {
620 if (option_bool(OPT_DHCP_FQDN))
621 {
622 if (!new_fqdn || !lease_tmp->fqdn || !hostname_isequal(lease_tmp->fqdn, new_fqdn) )
623 continue;
624 }
625 else
626 {
627 if (!new_name || !lease_tmp->hostname || !hostname_isequal(lease_tmp->hostname, new_name) )
628 continue;
629 }
630
631 if (lease_tmp->auth_name && !auth)
632 {
633 free(new_name);
634 free(new_fqdn);
635 return;
636 }
637
638 kill_name(lease_tmp);
639 break;
640 }
641 }
642
643 if (lease->hostname)
644 kill_name(lease);
645
646 lease->hostname = new_name;
647 lease->fqdn = new_fqdn;
648 lease->auth_name = auth;
649
650 file_dirty = 1;
651 dns_dirty = 1;
652 lease->changed = 1; /* run script on change */
653 }
654
655 void lease_set_interface(struct dhcp_lease *lease, int interface)
656 {
657 if (lease->last_interface == interface)
658 return;
659
660 lease->last_interface = interface;
661 lease->changed = 1;
662 }
663
664 void rerun_scripts(void)
665 {
666 struct dhcp_lease *lease;
667
668 for (lease = leases; lease; lease = lease->next)
669 lease->changed = 1;
670 }
671
672 /* deleted leases get transferred to the old_leases list.
673 remove them here, after calling the lease change
674 script. Also run the lease change script on new/modified leases.
675
676 Return zero if nothing to do. */
677 int do_script_run(time_t now)
678 {
679 struct dhcp_lease *lease;
680
681 #ifdef HAVE_DBUS
682 /* If we're going to be sending DBus signals, but the connection is not yet up,
683 delay everything until it is. */
684 if (option_bool(OPT_DBUS) && !daemon->dbus)
685 return 0;
686 #endif
687
688 if (old_leases)
689 {
690 lease = old_leases;
691
692 /* If the lease still has an old_hostname, do the "old" action on that first */
693 if (lease->old_hostname)
694 {
695 #ifdef HAVE_SCRIPT
696 queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
697 #endif
698 free(lease->old_hostname);
699 lease->old_hostname = NULL;
700 return 1;
701 }
702 else
703 {
704 kill_name(lease);
705 #ifdef HAVE_SCRIPT
706 queue_script(ACTION_DEL, lease, lease->old_hostname, now);
707 #endif
708 #ifdef HAVE_DBUS
709 emit_dbus_signal(ACTION_DEL, lease, lease->old_hostname);
710 #endif
711 old_leases = lease->next;
712
713 free(lease->old_hostname);
714 free(lease->clid);
715 free(lease->extradata);
716 free(lease);
717
718 return 1;
719 }
720 }
721
722 /* make sure we announce the loss of a hostname before its new location. */
723 for (lease = leases; lease; lease = lease->next)
724 if (lease->old_hostname)
725 {
726 #ifdef HAVE_SCRIPT
727 queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
728 #endif
729 free(lease->old_hostname);
730 lease->old_hostname = NULL;
731 return 1;
732 }
733
734 for (lease = leases; lease; lease = lease->next)
735 if (lease->new || lease->changed ||
736 (lease->aux_changed && option_bool(OPT_LEASE_RO)))
737 {
738 #ifdef HAVE_SCRIPT
739 queue_script(lease->new ? ACTION_ADD : ACTION_OLD, lease,
740 lease->fqdn ? lease->fqdn : lease->hostname, now);
741 #endif
742 #ifdef HAVE_DBUS
743 emit_dbus_signal(lease->new ? ACTION_ADD : ACTION_OLD, lease,
744 lease->fqdn ? lease->fqdn : lease->hostname);
745 #endif
746 lease->new = lease->changed = lease->aux_changed = 0;
747
748 /* this is used for the "add" call, then junked, since they're not in the database */
749 free(lease->extradata);
750 lease->extradata = NULL;
751
752 return 1;
753 }
754
755 return 0; /* nothing to do */
756 }
757
758 #endif
759
760
761
762