ISC DHCP  4.3.1
A reference DHCPv4 and DHCPv6 implementation
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ldap.c
Go to the documentation of this file.
1 /* ldap.c
2 
3  Routines for reading the configuration from LDAP */
4 
5 /*
6  * Copyright (c) 2003-2006 Ntelos, Inc.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of The Internet Software Consortium nor the names
19  * of its contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * This LDAP module was written by Brian Masney <masneyb@ntelos.net>. Its
37  * development was sponsored by Ntelos, Inc. (www.ntelos.com).
38  */
39 
40 #include "dhcpd.h"
41 #include <signal.h>
42 #include <errno.h>
43 
44 #if defined(LDAP_CONFIGURATION)
45 
46 #if defined(LDAP_CASA_AUTH)
47 #include "ldap_casa.h"
48 #endif
49 
50 static LDAP * ld = NULL;
51 static char *ldap_server = NULL,
52  *ldap_username = NULL,
53  *ldap_password = NULL,
54  *ldap_base_dn = NULL,
55  *ldap_dhcp_server_cn = NULL,
56  *ldap_debug_file = NULL;
57 static int ldap_port = LDAP_PORT,
58  ldap_method = LDAP_METHOD_DYNAMIC,
59  ldap_referrals = -1,
60  ldap_debug_fd = -1;
61 #if defined (LDAP_USE_SSL)
62 static int ldap_use_ssl = -1, /* try TLS if possible */
63  ldap_tls_reqcert = -1,
64  ldap_tls_crlcheck = -1;
65 static char *ldap_tls_ca_file = NULL,
66  *ldap_tls_ca_dir = NULL,
67  *ldap_tls_cert = NULL,
68  *ldap_tls_key = NULL,
69  *ldap_tls_ciphers = NULL,
70  *ldap_tls_randfile = NULL;
71 #endif
72 static struct ldap_config_stack *ldap_stack = NULL;
73 
74 typedef struct ldap_dn_node {
75  struct ldap_dn_node *next;
76  size_t refs;
77  char *dn;
78 } ldap_dn_node;
79 
80 static ldap_dn_node *ldap_service_dn_head = NULL;
81 static ldap_dn_node *ldap_service_dn_tail = NULL;
82 
83 
84 static char *
85 x_strncat(char *dst, const char *src, size_t dst_size)
86 {
87  size_t len = strlen(dst);
88  return strncat(dst, src, dst_size > len ? dst_size - len - 1: 0);
89 }
90 
91 static void
92 ldap_parse_class (struct ldap_config_stack *item, struct parse *cfile)
93 {
94  struct berval **tempbv;
95 
96  if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
97  tempbv[0] == NULL)
98  {
99  if (tempbv != NULL)
100  ldap_value_free_len (tempbv);
101 
102  return;
103  }
104 
105  x_strncat (cfile->inbuf, "class \"", LDAP_BUFFER_SIZE);
106  x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
107  x_strncat (cfile->inbuf, "\" {\n", LDAP_BUFFER_SIZE);
108 
109  item->close_brace = 1;
110  ldap_value_free_len (tempbv);
111 }
112 
113 
114 static void
115 ldap_parse_subclass (struct ldap_config_stack *item, struct parse *cfile)
116 {
117  struct berval **tempbv, **classdata;
118 
119  if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
120  tempbv[0] == NULL)
121  {
122  if (tempbv != NULL)
123  ldap_value_free_len (tempbv);
124 
125  return;
126  }
127 
128  if ((classdata = ldap_get_values_len (ld, item->ldent,
129  "dhcpClassData")) == NULL ||
130  classdata[0] == NULL)
131  {
132  if (classdata != NULL)
133  ldap_value_free_len (classdata);
134  ldap_value_free_len (tempbv);
135 
136  return;
137  }
138 
139  x_strncat (cfile->inbuf, "subclass ", LDAP_BUFFER_SIZE);
140  x_strncat (cfile->inbuf, classdata[0]->bv_val, LDAP_BUFFER_SIZE);
141  x_strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
142  x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
143  x_strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
144 
145  item->close_brace = 1;
146  ldap_value_free_len (tempbv);
147  ldap_value_free_len (classdata);
148 }
149 
150 
151 static void
152 ldap_parse_host (struct ldap_config_stack *item, struct parse *cfile)
153 {
154  struct berval **tempbv, **hwaddr;
155 
156  if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
157  tempbv[0] == NULL)
158  {
159  if (tempbv != NULL)
160  ldap_value_free_len (tempbv);
161 
162  return;
163  }
164 
165  hwaddr = ldap_get_values_len (ld, item->ldent, "dhcpHWAddress");
166 
167  x_strncat (cfile->inbuf, "host ", LDAP_BUFFER_SIZE);
168  x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
169 
170  if (hwaddr != NULL && hwaddr[0] != NULL)
171  {
172  x_strncat (cfile->inbuf, " {\nhardware ", LDAP_BUFFER_SIZE);
173  x_strncat (cfile->inbuf, hwaddr[0]->bv_val, LDAP_BUFFER_SIZE);
174  x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
175  ldap_value_free_len (hwaddr);
176  }
177 
178  item->close_brace = 1;
179  ldap_value_free_len (tempbv);
180 }
181 
182 
183 static void
184 ldap_parse_shared_network (struct ldap_config_stack *item, struct parse *cfile)
185 {
186  struct berval **tempbv;
187 
188  if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
189  tempbv[0] == NULL)
190  {
191  if (tempbv != NULL)
192  ldap_value_free_len (tempbv);
193 
194  return;
195  }
196 
197  x_strncat (cfile->inbuf, "shared-network \"", LDAP_BUFFER_SIZE);
198  x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
199  x_strncat (cfile->inbuf, "\" {\n", LDAP_BUFFER_SIZE);
200 
201  item->close_brace = 1;
202  ldap_value_free_len (tempbv);
203 }
204 
205 
206 static void
207 parse_netmask (int netmask, char *netmaskbuf)
208 {
209  unsigned long nm;
210  int i;
211 
212  nm = 0;
213  for (i=1; i <= netmask; i++)
214  {
215  nm |= 1 << (32 - i);
216  }
217 
218  sprintf (netmaskbuf, "%d.%d.%d.%d", (int) (nm >> 24) & 0xff,
219  (int) (nm >> 16) & 0xff,
220  (int) (nm >> 8) & 0xff,
221  (int) nm & 0xff);
222 }
223 
224 
225 static void
226 ldap_parse_subnet (struct ldap_config_stack *item, struct parse *cfile)
227 {
228  struct berval **tempbv, **netmaskstr;
229  char netmaskbuf[sizeof("255.255.255.255")];
230  int i;
231 
232  if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
233  tempbv[0] == NULL)
234  {
235  if (tempbv != NULL)
236  ldap_value_free_len (tempbv);
237 
238  return;
239  }
240 
241  if ((netmaskstr = ldap_get_values_len (ld, item->ldent,
242  "dhcpNetmask")) == NULL ||
243  netmaskstr[0] == NULL)
244  {
245  if (netmaskstr != NULL)
246  ldap_value_free_len (netmaskstr);
247  ldap_value_free_len (tempbv);
248 
249  return;
250  }
251 
252  x_strncat (cfile->inbuf, "subnet ", LDAP_BUFFER_SIZE);
253  x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
254 
255  x_strncat (cfile->inbuf, " netmask ", LDAP_BUFFER_SIZE);
256  parse_netmask (strtol (netmaskstr[0]->bv_val, NULL, 10), netmaskbuf);
257  x_strncat (cfile->inbuf, netmaskbuf, LDAP_BUFFER_SIZE);
258 
259  x_strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
260 
261  ldap_value_free_len (tempbv);
262  ldap_value_free_len (netmaskstr);
263 
264  if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpRange")) != NULL)
265  {
266  for (i=0; tempbv[i] != NULL; i++)
267  {
268  x_strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE);
269  x_strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
270  x_strncat (cfile->inbuf, tempbv[i]->bv_val, LDAP_BUFFER_SIZE);
271  x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
272  }
273  }
274 
275  item->close_brace = 1;
276 }
277 
278 
279 static void
280 ldap_parse_pool (struct ldap_config_stack *item, struct parse *cfile)
281 {
282  struct berval **tempbv;
283  int i;
284 
285  x_strncat (cfile->inbuf, "pool {\n", LDAP_BUFFER_SIZE);
286 
287  if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpRange")) != NULL)
288  {
289  x_strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE);
290  for (i=0; tempbv[i] != NULL; i++)
291  {
292  x_strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
293  x_strncat (cfile->inbuf, tempbv[i]->bv_val, LDAP_BUFFER_SIZE);
294  }
295  x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
296  ldap_value_free_len (tempbv);
297  }
298 
299  if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpPermitList")) != NULL)
300  {
301  for (i=0; tempbv[i] != NULL; i++)
302  {
303  x_strncat (cfile->inbuf, tempbv[i]->bv_val, LDAP_BUFFER_SIZE);
304  x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
305  }
306  ldap_value_free_len (tempbv);
307  }
308 
309  item->close_brace = 1;
310 }
311 
312 
313 static void
314 ldap_parse_group (struct ldap_config_stack *item, struct parse *cfile)
315 {
316  x_strncat (cfile->inbuf, "group {\n", LDAP_BUFFER_SIZE);
317  item->close_brace = 1;
318 }
319 
320 
321 static void
322 ldap_parse_key (struct ldap_config_stack *item, struct parse *cfile)
323 {
324  struct berval **tempbv;
325 
326  if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) != NULL)
327  {
328  x_strncat (cfile->inbuf, "key ", LDAP_BUFFER_SIZE);
329  x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
330  x_strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
331  ldap_value_free_len (tempbv);
332  }
333 
334  if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpKeyAlgorithm")) != NULL)
335  {
336  x_strncat (cfile->inbuf, "algorithm ", LDAP_BUFFER_SIZE);
337  x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
338  x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
339  ldap_value_free_len (tempbv);
340  }
341 
342  if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpKeySecret")) != NULL)
343  {
344  x_strncat (cfile->inbuf, "secret ", LDAP_BUFFER_SIZE);
345  x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
346  x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
347  ldap_value_free_len (tempbv);
348  }
349 
350  item->close_brace = 1;
351 }
352 
353 
354 static void
355 ldap_parse_zone (struct ldap_config_stack *item, struct parse *cfile)
356 {
357  char *cnFindStart, *cnFindEnd;
358  struct berval **tempbv;
359  char *keyCn;
360  size_t len;
361 
362  if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) != NULL)
363  {
364  x_strncat (cfile->inbuf, "zone ", LDAP_BUFFER_SIZE);
365  x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
366  x_strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
367  ldap_value_free_len (tempbv);
368  }
369 
370  if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpDnsZoneServer")) != NULL)
371  {
372  x_strncat (cfile->inbuf, "primary ", LDAP_BUFFER_SIZE);
373  x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
374 
375  x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
376  ldap_value_free_len (tempbv);
377  }
378 
379  if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpKeyDN")) != NULL)
380  {
381  cnFindStart = strchr(tempbv[0]->bv_val,'=');
382  if (cnFindStart != NULL)
383  cnFindEnd = strchr(++cnFindStart,',');
384  else
385  cnFindEnd = NULL;
386 
387  if (cnFindEnd != NULL && cnFindEnd > cnFindStart)
388  {
389  len = cnFindEnd - cnFindStart;
390  keyCn = dmalloc (len + 1, MDL);
391  }
392  else
393  {
394  len = 0;
395  keyCn = NULL;
396  }
397 
398  if (keyCn != NULL)
399  {
400  strncpy (keyCn, cnFindStart, len);
401  keyCn[len] = '\0';
402 
403  x_strncat (cfile->inbuf, "key ", LDAP_BUFFER_SIZE);
404  x_strncat (cfile->inbuf, keyCn, LDAP_BUFFER_SIZE);
405  x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
406 
407  dfree (keyCn, MDL);
408  }
409 
410  ldap_value_free_len (tempbv);
411  }
412 
413  item->close_brace = 1;
414 }
415 
416 
417 static void
418 add_to_config_stack (LDAPMessage * res, LDAPMessage * ent)
419 {
420  struct ldap_config_stack *ns;
421 
422  ns = dmalloc (sizeof (*ns), MDL);
423  ns->res = res;
424  ns->ldent = ent;
425  ns->close_brace = 0;
426  ns->processed = 0;
427  ns->next = ldap_stack;
428  ldap_stack = ns;
429 }
430 
431 
432 static void
433 ldap_stop()
434 {
435  struct sigaction old, new;
436 
437  if (ld == NULL)
438  return;
439 
440  /*
441  ** ldap_unbind after a LDAP_SERVER_DOWN result
442  ** causes a SIGPIPE and dhcpd gets terminated,
443  ** since it doesn't handle it...
444  */
445 
446  new.sa_flags = 0;
447  new.sa_handler = SIG_IGN;
448  sigemptyset (&new.sa_mask);
449  sigaction (SIGPIPE, &new, &old);
450 
451  ldap_unbind_ext_s (ld, NULL, NULL);
452  ld = NULL;
453 
454  sigaction (SIGPIPE, &old, &new);
455 }
456 
457 
458 static char *
459 _do_lookup_dhcp_string_option (struct option_state *options, int option_name)
460 {
461  struct option_cache *oc;
462  struct data_string db;
463  char *ret;
464 
465  memset (&db, 0, sizeof (db));
466  oc = lookup_option (&server_universe, options, option_name);
467  if (oc &&
468  evaluate_option_cache (&db, (struct packet*) NULL,
469  (struct lease *) NULL,
470  (struct client_state *) NULL, options,
471  (struct option_state *) NULL,
472  &global_scope, oc, MDL) &&
473  db.data != NULL && *db.data != '\0')
474 
475  {
476  ret = dmalloc (db.len + 1, MDL);
477  if (ret == NULL)
478  log_fatal ("no memory for ldap option %d value", option_name);
479 
480  memcpy (ret, db.data, db.len);
481  ret[db.len] = 0;
482  data_string_forget (&db, MDL);
483  }
484  else
485  ret = NULL;
486 
487  return (ret);
488 }
489 
490 
491 static int
492 _do_lookup_dhcp_int_option (struct option_state *options, int option_name)
493 {
494  struct option_cache *oc;
495  struct data_string db;
496  int ret;
497 
498  memset (&db, 0, sizeof (db));
499  oc = lookup_option (&server_universe, options, option_name);
500  if (oc &&
501  evaluate_option_cache (&db, (struct packet*) NULL,
502  (struct lease *) NULL,
503  (struct client_state *) NULL, options,
504  (struct option_state *) NULL,
505  &global_scope, oc, MDL) &&
506  db.data != NULL && *db.data != '\0')
507  {
508  ret = strtol ((const char *) db.data, NULL, 10);
509  data_string_forget (&db, MDL);
510  }
511  else
512  ret = 0;
513 
514  return (ret);
515 }
516 
517 
518 static int
519 _do_lookup_dhcp_enum_option (struct option_state *options, int option_name)
520 {
521  struct option_cache *oc;
522  struct data_string db;
523  int ret = -1;
524 
525  memset (&db, 0, sizeof (db));
526  oc = lookup_option (&server_universe, options, option_name);
527  if (oc &&
528  evaluate_option_cache (&db, (struct packet*) NULL,
529  (struct lease *) NULL,
530  (struct client_state *) NULL, options,
531  (struct option_state *) NULL,
532  &global_scope, oc, MDL) &&
533  db.data != NULL && *db.data != '\0')
534  {
535  if (db.len == 1)
536  ret = db.data [0];
537  else
538  log_fatal ("invalid option name %d", option_name);
539 
540  data_string_forget (&db, MDL);
541  }
542  else
543  ret = 0;
544 
545  return (ret);
546 }
547 
548 int
549 ldap_rebind_cb (LDAP *ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *parms)
550 {
551  int ret;
552  LDAPURLDesc *ldapurl = NULL;
553  char *who = NULL;
554  struct berval creds;
555 
556  log_info("LDAP rebind to '%s'", url);
557  if ((ret = ldap_url_parse(url, &ldapurl)) != LDAP_SUCCESS)
558  {
559  log_error ("Error: Can not parse ldap rebind url '%s': %s",
560  url, ldap_err2string(ret));
561  return ret;
562  }
563 
564 
565 #if defined (LDAP_USE_SSL)
566  if (strcasecmp(ldapurl->lud_scheme, "ldaps") == 0)
567  {
568  int opt = LDAP_OPT_X_TLS_HARD;
569  if ((ret = ldap_set_option (ld, LDAP_OPT_X_TLS, &opt)) != LDAP_SUCCESS)
570  {
571  log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
572  ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret));
573  return ret;
574  }
575  else
576  {
577  log_info ("LDAPS session successfully enabled to %s", ldap_server);
578  }
579  }
580  else
581  if (strcasecmp(ldapurl->lud_scheme, "ldap") == 0 &&
582  ldap_use_ssl != LDAP_SSL_OFF)
583  {
584  if ((ret = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS)
585  {
586  log_error ("Error: Cannot start TLS session to %s:%d: %s",
587  ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret));
588  return ret;
589  }
590  else
591  {
592  log_info ("TLS session successfully started to %s:%d",
593  ldapurl->lud_host, ldapurl->lud_port);
594  }
595  }
596 #endif
597 
598 
599  if (ldap_username != NULL || *ldap_username != '\0')
600  {
601  who = ldap_username;
602  creds.bv_val = strdup(ldap_password);
603  creds.bv_len = strlen(ldap_password);
604  }
605 
606  if ((ret = ldap_sasl_bind_s (ld, who, LDAP_SASL_SIMPLE, &creds,
607  NULL, NULL, NULL)) != LDAP_SUCCESS)
608  {
609  log_error ("Error: Cannot login into ldap server %s:%d: %s",
610  ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret));
611  }
612  return ret;
613 }
614 
615 static void
616 ldap_start (void)
617 {
618  struct option_state *options;
619  int ret, version;
620  char *uri = NULL;
621  struct berval creds;
622 
623  if (ld != NULL)
624  return;
625 
626  if (ldap_server == NULL)
627  {
628  options = NULL;
629  option_state_allocate (&options, MDL);
630 
631  execute_statements_in_scope (NULL, NULL, NULL, NULL, NULL,
632  options, &global_scope, root_group,
633  NULL, NULL);
634 
635  ldap_server = _do_lookup_dhcp_string_option (options, SV_LDAP_SERVER);
636  ldap_dhcp_server_cn = _do_lookup_dhcp_string_option (options,
637  SV_LDAP_DHCP_SERVER_CN);
638  ldap_port = _do_lookup_dhcp_int_option (options, SV_LDAP_PORT);
639  ldap_base_dn = _do_lookup_dhcp_string_option (options, SV_LDAP_BASE_DN);
640  ldap_method = _do_lookup_dhcp_enum_option (options, SV_LDAP_METHOD);
641  ldap_debug_file = _do_lookup_dhcp_string_option (options,
642  SV_LDAP_DEBUG_FILE);
643  ldap_referrals = _do_lookup_dhcp_enum_option (options, SV_LDAP_REFERRALS);
644 
645 #if defined (LDAP_USE_SSL)
646  ldap_use_ssl = _do_lookup_dhcp_enum_option (options, SV_LDAP_SSL);
647  if( ldap_use_ssl != LDAP_SSL_OFF)
648  {
649  ldap_tls_reqcert = _do_lookup_dhcp_enum_option (options, SV_LDAP_TLS_REQCERT);
650  ldap_tls_ca_file = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CA_FILE);
651  ldap_tls_ca_dir = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CA_DIR);
652  ldap_tls_cert = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CERT);
653  ldap_tls_key = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_KEY);
654  ldap_tls_crlcheck = _do_lookup_dhcp_enum_option (options, SV_LDAP_TLS_CRLCHECK);
655  ldap_tls_ciphers = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CIPHERS);
656  ldap_tls_randfile = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_RANDFILE);
657  }
658 #endif
659 
660 #if defined (LDAP_CASA_AUTH)
661  if (!load_uname_pwd_from_miCASA(&ldap_username,&ldap_password))
662  {
663 #if defined (DEBUG_LDAP)
664  log_info ("Authentication credential taken from file");
665 #endif
666 #endif
667 
668  ldap_username = _do_lookup_dhcp_string_option (options, SV_LDAP_USERNAME);
669  ldap_password = _do_lookup_dhcp_string_option (options, SV_LDAP_PASSWORD);
670 
671 #if defined (LDAP_CASA_AUTH)
672  }
673 #endif
674 
675  option_state_dereference (&options, MDL);
676  }
677 
678  if (ldap_server == NULL || ldap_base_dn == NULL)
679  {
680  log_info ("Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not specified in the config file");
681  ldap_method = LDAP_METHOD_STATIC;
682  return;
683  }
684 
685  if (ldap_debug_file != NULL && ldap_debug_fd == -1)
686  {
687  if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC,
688  S_IRUSR | S_IWUSR)) < 0)
689  log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file,
690  strerror (errno));
691  }
692 
693 #if defined (DEBUG_LDAP)
694  log_info ("Connecting to LDAP server %s:%d", ldap_server, ldap_port);
695 #endif
696 
697 #if defined (LDAP_USE_SSL)
698  if (ldap_use_ssl == -1)
699  {
700  /*
701  ** There was no "ldap-ssl" option in dhcpd.conf (also not "off").
702  ** Let's try, if we can use an anonymous TLS session without to
703  ** verify the server certificate -- if not continue without TLS.
704  */
705  int opt = LDAP_OPT_X_TLS_ALLOW;
706  if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
707  &opt)) != LDAP_SUCCESS)
708  {
709  log_error ("Warning: Cannot set LDAP TLS require cert option to 'allow': %s",
710  ldap_err2string (ret));
711  }
712  }
713 
714  if (ldap_use_ssl != LDAP_SSL_OFF)
715  {
716  if (ldap_tls_reqcert != -1)
717  {
718  if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
719  &ldap_tls_reqcert)) != LDAP_SUCCESS)
720  {
721  log_error ("Cannot set LDAP TLS require cert option: %s",
722  ldap_err2string (ret));
723  }
724  }
725 
726  if( ldap_tls_ca_file != NULL)
727  {
728  if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE,
729  ldap_tls_ca_file)) != LDAP_SUCCESS)
730  {
731  log_error ("Cannot set LDAP TLS CA certificate file %s: %s",
732  ldap_tls_ca_file, ldap_err2string (ret));
733  }
734  }
735  if( ldap_tls_ca_dir != NULL)
736  {
737  if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR,
738  ldap_tls_ca_dir)) != LDAP_SUCCESS)
739  {
740  log_error ("Cannot set LDAP TLS CA certificate dir %s: %s",
741  ldap_tls_ca_dir, ldap_err2string (ret));
742  }
743  }
744  if( ldap_tls_cert != NULL)
745  {
746  if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE,
747  ldap_tls_cert)) != LDAP_SUCCESS)
748  {
749  log_error ("Cannot set LDAP TLS client certificate file %s: %s",
750  ldap_tls_cert, ldap_err2string (ret));
751  }
752  }
753  if( ldap_tls_key != NULL)
754  {
755  if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE,
756  ldap_tls_key)) != LDAP_SUCCESS)
757  {
758  log_error ("Cannot set LDAP TLS certificate key file %s: %s",
759  ldap_tls_key, ldap_err2string (ret));
760  }
761  }
762  if( ldap_tls_crlcheck != -1)
763  {
764  int opt = ldap_tls_crlcheck;
765  if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CRLCHECK,
766  &opt)) != LDAP_SUCCESS)
767  {
768  log_error ("Cannot set LDAP TLS crl check option: %s",
769  ldap_err2string (ret));
770  }
771  }
772  if( ldap_tls_ciphers != NULL)
773  {
774  if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE,
775  ldap_tls_ciphers)) != LDAP_SUCCESS)
776  {
777  log_error ("Cannot set LDAP TLS cipher suite %s: %s",
778  ldap_tls_ciphers, ldap_err2string (ret));
779  }
780  }
781  if( ldap_tls_randfile != NULL)
782  {
783  if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE,
784  ldap_tls_randfile)) != LDAP_SUCCESS)
785  {
786  log_error ("Cannot set LDAP TLS random file %s: %s",
787  ldap_tls_randfile, ldap_err2string (ret));
788  }
789  }
790  }
791 #endif
792 
793  /* enough for 'ldap://+ + hostname + ':' + port number */
794  uri = malloc(strlen(ldap_server) + 16);
795  if (uri == NULL)
796  {
797  log_error ("Cannot build ldap init URI %s:%d", ldap_server, ldap_port);
798  return;
799  }
800 
801  sprintf(uri, "ldap://%s:%d", ldap_server, ldap_port);
802  ldap_initialize(&ld, uri);
803 
804  if (ld == NULL)
805  {
806  log_error ("Cannot init ldap session to %s:%d", ldap_server, ldap_port);
807  return;
808  }
809 
810  free(uri);
811 
812  version = LDAP_VERSION3;
813  if ((ret = ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version)) != LDAP_OPT_SUCCESS)
814  {
815  log_error ("Cannot set LDAP version to %d: %s", version,
816  ldap_err2string (ret));
817  }
818 
819  if (ldap_referrals != -1)
820  {
821  if ((ret = ldap_set_option (ld, LDAP_OPT_REFERRALS, ldap_referrals ?
822  LDAP_OPT_ON : LDAP_OPT_OFF)) != LDAP_OPT_SUCCESS)
823  {
824  log_error ("Cannot %s LDAP referrals option: %s",
825  (ldap_referrals ? "enable" : "disable"),
826  ldap_err2string (ret));
827  }
828  }
829 
830  if ((ret = ldap_set_rebind_proc(ld, ldap_rebind_cb, NULL)) != LDAP_SUCCESS)
831  {
832  log_error ("Warning: Cannot set ldap rebind procedure: %s",
833  ldap_err2string (ret));
834  }
835 
836 #if defined (LDAP_USE_SSL)
837  if (ldap_use_ssl == LDAP_SSL_LDAPS ||
838  (ldap_use_ssl == LDAP_SSL_ON && ldap_port == LDAPS_PORT))
839  {
840  int opt = LDAP_OPT_X_TLS_HARD;
841  if ((ret = ldap_set_option (ld, LDAP_OPT_X_TLS, &opt)) != LDAP_SUCCESS)
842  {
843  log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
844  ldap_server, ldap_port, ldap_err2string (ret));
845  ldap_stop();
846  return;
847  }
848  else
849  {
850  log_info ("LDAPS session successfully enabled to %s:%d",
851  ldap_server, ldap_port);
852  }
853  }
854  else if (ldap_use_ssl != LDAP_SSL_OFF)
855  {
856  if ((ret = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS)
857  {
858  log_error ("Error: Cannot start TLS session to %s:%d: %s",
859  ldap_server, ldap_port, ldap_err2string (ret));
860  ldap_stop();
861  return;
862  }
863  else
864  {
865  log_info ("TLS session successfully started to %s:%d",
866  ldap_server, ldap_port);
867  }
868  }
869 #endif
870 
871  if (ldap_username != NULL && *ldap_username != '\0')
872  {
873  creds.bv_val = strdup(ldap_password);
874  creds.bv_len = strlen(ldap_password);
875 
876  if ((ret = ldap_sasl_bind_s (ld, ldap_username, LDAP_SASL_SIMPLE,
877  &creds, NULL, NULL, NULL)) != LDAP_SUCCESS)
878  {
879  log_error ("Error: Cannot login into ldap server %s:%d: %s",
880  ldap_server, ldap_port, ldap_err2string (ret));
881  ldap_stop();
882  return;
883  }
884  }
885 
886 #if defined (DEBUG_LDAP)
887  log_info ("Successfully logged into LDAP server %s", ldap_server);
888 #endif
889 }
890 
891 
892 static void
893 parse_external_dns (LDAPMessage * ent)
894 {
895  char *search[] = {"dhcpFailOverPeerDN", "dhcpOptionsDN", "dhcpSharedNetworkDN", "dhcpSubnetDN",
896  "dhcpGroupDN", "dhcpHostDN", "dhcpClassesDN",
897  "dhcpPoolDN", NULL};
898  LDAPMessage * newres, * newent;
899  struct berval **tempbv;
900  int i, j, ret;
901 #if defined (DEBUG_LDAP)
902  char *dn;
903 
904  dn = ldap_get_dn (ld, ent);
905  if (dn != NULL)
906  {
907  log_info ("Parsing external DNs for '%s'", dn);
908  ldap_memfree (dn);
909  }
910 #endif
911 
912  if (ld == NULL)
913  ldap_start ();
914  if (ld == NULL)
915  return;
916 
917  for (i=0; search[i] != NULL; i++)
918  {
919  if ((tempbv = ldap_get_values_len (ld, ent, search[i])) == NULL)
920  continue;
921 
922  for (j=0; tempbv[j] != NULL; j++)
923  {
924  if (*tempbv[j]->bv_val == '\0')
925  continue;
926 
927  if ((ret = ldap_search_ext_s(ld, tempbv[j]->bv_val, LDAP_SCOPE_BASE,
928  "objectClass=*", NULL, 0, NULL,
929  NULL, NULL, 0, &newres)) != LDAP_SUCCESS)
930  {
931  ldap_value_free_len (tempbv);
932  ldap_stop();
933  return;
934  }
935 
936 #if defined (DEBUG_LDAP)
937  log_info ("Adding contents of subtree '%s' to config stack from '%s' reference", tempbv[j], search[i]);
938 #endif
939  for (newent = ldap_first_entry (ld, newres);
940  newent != NULL;
941  newent = ldap_next_entry (ld, newent))
942  {
943 #if defined (DEBUG_LDAP)
944  dn = ldap_get_dn (ld, newent);
945  if (dn != NULL)
946  {
947  log_info ("Adding LDAP result set starting with '%s' to config stack", dn);
948  ldap_memfree (dn);
949  }
950 #endif
951 
952  add_to_config_stack (newres, newent);
953  /* don't free newres here */
954  }
955  }
956 
957  ldap_value_free_len (tempbv);
958  }
959 }
960 
961 
962 static void
963 free_stack_entry (struct ldap_config_stack *item)
964 {
965  struct ldap_config_stack *look_ahead_pointer = item;
966  int may_free_msg = 1;
967 
968  while (look_ahead_pointer->next != NULL)
969  {
970  look_ahead_pointer = look_ahead_pointer->next;
971  if (look_ahead_pointer->res == item->res)
972  {
973  may_free_msg = 0;
974  break;
975  }
976  }
977 
978  if (may_free_msg)
979  ldap_msgfree (item->res);
980 
981  dfree (item, MDL);
982 }
983 
984 
985 static void
986 next_ldap_entry (struct parse *cfile)
987 {
988  struct ldap_config_stack *temp_stack;
989 
990  if (ldap_stack != NULL && ldap_stack->close_brace)
991  {
992  x_strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
993  ldap_stack->close_brace = 0;
994  }
995 
996  while (ldap_stack != NULL &&
997  (ldap_stack->ldent == NULL ||
998  (ldap_stack->ldent = ldap_next_entry (ld, ldap_stack->ldent)) == NULL))
999  {
1000  if (ldap_stack->close_brace)
1001  {
1002  x_strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
1003  ldap_stack->close_brace = 0;
1004  }
1005 
1006  temp_stack = ldap_stack;
1007  ldap_stack = ldap_stack->next;
1008  free_stack_entry (temp_stack);
1009  }
1010 
1011  if (ldap_stack != NULL && ldap_stack->close_brace)
1012  {
1013  x_strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
1014  ldap_stack->close_brace = 0;
1015  }
1016 }
1017 
1018 
1019 static char
1020 check_statement_end (const char *statement)
1021 {
1022  char *ptr;
1023 
1024  if (statement == NULL || *statement == '\0')
1025  return ('\0');
1026 
1027  /*
1028  ** check if it ends with "}", e.g.:
1029  ** "zone my.domain. { ... }"
1030  ** optionally followed by spaces
1031  */
1032  ptr = strrchr (statement, '}');
1033  if (ptr != NULL)
1034  {
1035  /* skip following white-spaces */
1036  for (++ptr; isspace ((int)*ptr); ptr++);
1037 
1038  /* check if we reached the end */
1039  if (*ptr == '\0')
1040  return ('}'); /* yes, block end */
1041  else
1042  return (*ptr);
1043  }
1044 
1045  /*
1046  ** this should not happen, but...
1047  ** check if it ends with ";", e.g.:
1048  ** "authoritative;"
1049  ** optionally followed by spaces
1050  */
1051  ptr = strrchr (statement, ';');
1052  if (ptr != NULL)
1053  {
1054  /* skip following white-spaces */
1055  for (++ptr; isspace ((int)*ptr); ptr++);
1056 
1057  /* check if we reached the end */
1058  if (*ptr == '\0')
1059  return (';'); /* ends with a ; */
1060  else
1061  return (*ptr);
1062  }
1063 
1064  return ('\0');
1065 }
1066 
1067 
1068 static isc_result_t
1069 ldap_parse_entry_options (LDAPMessage *ent, char *buffer, size_t size,
1070  int *lease_limit)
1071 {
1072  struct berval **tempbv;
1073  int i;
1074 
1075  if (ent == NULL || buffer == NULL || size == 0)
1076  return (ISC_R_FAILURE);
1077 
1078  if ((tempbv = ldap_get_values_len (ld, ent, "dhcpStatements")) != NULL)
1079  {
1080  for (i=0; tempbv[i] != NULL; i++)
1081  {
1082  if (lease_limit != NULL &&
1083  strncasecmp ("lease limit ", tempbv[i]->bv_val, 12) == 0)
1084  {
1085  *lease_limit = (int) strtol ((tempbv[i]->bv_val) + 12, NULL, 10);
1086  continue;
1087  }
1088 
1089  x_strncat (buffer, tempbv[i]->bv_val, size);
1090 
1091  switch((int) check_statement_end (tempbv[i]->bv_val))
1092  {
1093  case '}':
1094  case ';':
1095  x_strncat (buffer, "\n", size);
1096  break;
1097  default:
1098  x_strncat (buffer, ";\n", size);
1099  break;
1100  }
1101  }
1102  ldap_value_free_len (tempbv);
1103  }
1104 
1105  if ((tempbv = ldap_get_values_len (ld, ent, "dhcpOption")) != NULL)
1106  {
1107  for (i=0; tempbv[i] != NULL; i++)
1108  {
1109  x_strncat (buffer, "option ", size);
1110  x_strncat (buffer, tempbv[i]->bv_val, size);
1111  switch ((int) check_statement_end (tempbv[i]->bv_val))
1112  {
1113  case ';':
1114  x_strncat (buffer, "\n", size);
1115  break;
1116  default:
1117  x_strncat (buffer, ";\n", size);
1118  break;
1119  }
1120  }
1121  ldap_value_free_len (tempbv);
1122  }
1123 
1124  return (ISC_R_SUCCESS);
1125 }
1126 
1127 
1128 static void
1129 ldap_generate_config_string (struct parse *cfile)
1130 {
1131  struct berval **objectClass;
1132  char *dn;
1133  struct ldap_config_stack *entry;
1134  LDAPMessage * ent, * res;
1135  int i, ignore, found;
1136  int ret;
1137 
1138  if (ld == NULL)
1139  ldap_start ();
1140  if (ld == NULL)
1141  return;
1142 
1143  entry = ldap_stack;
1144  if ((objectClass = ldap_get_values_len (ld, entry->ldent,
1145  "objectClass")) == NULL)
1146  return;
1147 
1148  ignore = 0;
1149  found = 1;
1150  for (i=0; objectClass[i] != NULL; i++)
1151  {
1152  if (strcasecmp (objectClass[i]->bv_val, "dhcpSharedNetwork") == 0)
1153  ldap_parse_shared_network (entry, cfile);
1154  else if (strcasecmp (objectClass[i]->bv_val, "dhcpClass") == 0)
1155  ldap_parse_class (entry, cfile);
1156  else if (strcasecmp (objectClass[i]->bv_val, "dhcpSubnet") == 0)
1157  ldap_parse_subnet (entry, cfile);
1158  else if (strcasecmp (objectClass[i]->bv_val, "dhcpPool") == 0)
1159  ldap_parse_pool (entry, cfile);
1160  else if (strcasecmp (objectClass[i]->bv_val, "dhcpGroup") == 0)
1161  ldap_parse_group (entry, cfile);
1162  else if (strcasecmp (objectClass[i]->bv_val, "dhcpTSigKey") == 0)
1163  ldap_parse_key (entry, cfile);
1164  else if (strcasecmp (objectClass[i]->bv_val, "dhcpDnsZone") == 0)
1165  ldap_parse_zone (entry, cfile);
1166  else if (strcasecmp (objectClass[i]->bv_val, "dhcpHost") == 0)
1167  {
1168  if (ldap_method == LDAP_METHOD_STATIC)
1169  ldap_parse_host (entry, cfile);
1170  else
1171  {
1172  ignore = 1;
1173  break;
1174  }
1175  }
1176  else if (strcasecmp (objectClass[i]->bv_val, "dhcpSubClass") == 0)
1177  {
1178  if (ldap_method == LDAP_METHOD_STATIC)
1179  ldap_parse_subclass (entry, cfile);
1180  else
1181  {
1182  ignore = 1;
1183  break;
1184  }
1185  }
1186  else
1187  found = 0;
1188 
1189  if (found && cfile->inbuf[0] == '\0')
1190  {
1191  ignore = 1;
1192  break;
1193  }
1194  }
1195 
1196  ldap_value_free_len (objectClass);
1197 
1198  if (ignore)
1199  {
1200  next_ldap_entry (cfile);
1201  return;
1202  }
1203 
1204  ldap_parse_entry_options(entry->ldent, cfile->inbuf,
1205  LDAP_BUFFER_SIZE-1, NULL);
1206 
1207  dn = ldap_get_dn (ld, entry->ldent);
1208 
1209 #if defined(DEBUG_LDAP)
1210  if (dn != NULL)
1211  log_info ("Found LDAP entry '%s'", dn);
1212 #endif
1213 
1214  if (dn == NULL ||
1215  (ret = ldap_search_ext_s (ld, dn, LDAP_SCOPE_ONELEVEL,
1216  "objectClass=*", NULL, 0, NULL, NULL,
1217  NULL, 0, &res)) != LDAP_SUCCESS)
1218  {
1219  if (dn)
1220  ldap_memfree (dn);
1221 
1222  ldap_stop();
1223  return;
1224  }
1225 
1226  ldap_memfree (dn);
1227 
1228  if ((ent = ldap_first_entry (ld, res)) != NULL)
1229  {
1230  add_to_config_stack (res, ent);
1231  parse_external_dns (entry->ldent);
1232  }
1233  else
1234  {
1235  ldap_msgfree (res);
1236  parse_external_dns (entry->ldent);
1237  next_ldap_entry (cfile);
1238  }
1239 }
1240 
1241 
1242 static void
1243 ldap_close_debug_fd()
1244 {
1245  if (ldap_debug_fd != -1)
1246  {
1247  close (ldap_debug_fd);
1248  ldap_debug_fd = -1;
1249  }
1250 }
1251 
1252 
1253 static void
1254 ldap_write_debug (const void *buff, size_t size)
1255 {
1256  if (ldap_debug_fd != -1)
1257  {
1258  if (write (ldap_debug_fd, buff, size) < 0)
1259  {
1260  log_error ("Error writing to LDAP debug file %s: %s."
1261  " Disabling log file.", ldap_debug_file,
1262  strerror (errno));
1263  ldap_close_debug_fd();
1264  }
1265  }
1266 }
1267 
1268 static int
1269 ldap_read_function (struct parse *cfile)
1270 {
1271  cfile->inbuf[0] = '\0';
1272  cfile->buflen = 0;
1273 
1274  while (ldap_stack != NULL && *cfile->inbuf == '\0')
1275  ldap_generate_config_string (cfile);
1276 
1277  if (ldap_stack == NULL && *cfile->inbuf == '\0')
1278  return (EOF);
1279 
1280  cfile->bufix = 1;
1281  cfile->buflen = strlen (cfile->inbuf) - 1;
1282  if (cfile->buflen > 0)
1283  ldap_write_debug (cfile->inbuf, cfile->buflen);
1284 
1285 #if defined (DEBUG_LDAP)
1286  log_info ("Sending config line '%s'", cfile->inbuf);
1287 #endif
1288 
1289  return (cfile->inbuf[0]);
1290 }
1291 
1292 
1293 static char *
1294 ldap_get_host_name (LDAPMessage * ent)
1295 {
1296  struct berval **name;
1297  char *ret;
1298 
1299  ret = NULL;
1300  if ((name = ldap_get_values_len (ld, ent, "cn")) == NULL || name[0] == NULL)
1301  {
1302  if (name != NULL)
1303  ldap_value_free_len (name);
1304 
1305 #if defined (DEBUG_LDAP)
1306  ret = ldap_get_dn (ld, ent);
1307  if (ret != NULL)
1308  {
1309  log_info ("Cannot get cn attribute for LDAP entry %s", ret);
1310  ldap_memfree(ret);
1311  }
1312 #endif
1313  return (NULL);
1314  }
1315 
1316  ret = dmalloc (strlen (name[0]->bv_val) + 1, MDL);
1317  strcpy (ret, name[0]->bv_val);
1318  ldap_value_free_len (name);
1319 
1320  return (ret);
1321 }
1322 
1323 
1324 static int
1325 getfqhostname(char *fqhost, size_t size)
1326 {
1327 #if defined(MAXHOSTNAMELEN)
1328  char hname[MAXHOSTNAMELEN];
1329 #else
1330  char hname[65];
1331 #endif
1332  struct hostent *hp;
1333 
1334  if(NULL == fqhost || 1 >= size)
1335  return -1;
1336 
1337  memset(hname, 0, sizeof(hname));
1338  if( gethostname(hname, sizeof(hname)-1))
1339  return -1;
1340 
1341  if(NULL == (hp = gethostbyname(hname)))
1342  return -1;
1343 
1344  strncpy(fqhost, hp->h_name, size-1);
1345  fqhost[size-1] = '\0';
1346  return 0;
1347 }
1348 
1349 
1350 isc_result_t
1351 ldap_read_config (void)
1352 {
1353  LDAPMessage * ldres, * hostres, * ent, * hostent;
1354  char hfilter[1024], sfilter[1024], fqdn[257];
1355  char *buffer, *hostdn;
1356  ldap_dn_node *curr = NULL;
1357  struct parse *cfile;
1358  struct utsname unme;
1359  isc_result_t res;
1360  size_t length;
1361  int ret, cnt;
1362  struct berval **tempbv = NULL;
1363 
1364  if (ld == NULL)
1365  ldap_start ();
1366  if (ld == NULL)
1367  return (ldap_server == NULL ? ISC_R_SUCCESS : ISC_R_FAILURE);
1368 
1369  buffer = dmalloc (LDAP_BUFFER_SIZE+1, MDL);
1370  if (buffer == NULL)
1371  return (ISC_R_FAILURE);
1372 
1373  cfile = (struct parse *) NULL;
1374  res = new_parse (&cfile, -1, buffer, LDAP_BUFFER_SIZE, "LDAP", 0);
1375  if (res != ISC_R_SUCCESS)
1376  return (res);
1377 
1378  uname (&unme);
1379  if (ldap_dhcp_server_cn != NULL)
1380  {
1381  snprintf (hfilter, sizeof (hfilter),
1382  "(&(objectClass=dhcpServer)(cn=%s))", ldap_dhcp_server_cn);
1383  }
1384  else
1385  {
1386  if(0 == getfqhostname(fqdn, sizeof(fqdn)))
1387  {
1388  snprintf (hfilter, sizeof (hfilter),
1389  "(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))",
1390  unme.nodename, fqdn);
1391  }
1392  else
1393  {
1394  snprintf (hfilter, sizeof (hfilter),
1395  "(&(objectClass=dhcpServer)(cn=%s))", unme.nodename);
1396  }
1397 
1398  }
1399  hostres = NULL;
1400  if ((ret = ldap_search_ext_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE,
1401  hfilter, NULL, 0, NULL, NULL, NULL, 0,
1402  &hostres)) != LDAP_SUCCESS)
1403  {
1404  log_error ("Cannot find host LDAP entry %s %s",
1405  ((ldap_dhcp_server_cn == NULL)?(unme.nodename):(ldap_dhcp_server_cn)), hfilter);
1406  if(NULL != hostres)
1407  ldap_msgfree (hostres);
1408  ldap_stop();
1409  return (ISC_R_FAILURE);
1410  }
1411 
1412  if ((hostent = ldap_first_entry (ld, hostres)) == NULL)
1413  {
1414  log_error ("Error: Cannot find LDAP entry matching %s", hfilter);
1415  ldap_msgfree (hostres);
1416  ldap_stop();
1417  return (ISC_R_FAILURE);
1418  }
1419 
1420  hostdn = ldap_get_dn (ld, hostent);
1421 #if defined(DEBUG_LDAP)
1422  if (hostdn != NULL)
1423  log_info ("Found dhcpServer LDAP entry '%s'", hostdn);
1424 #endif
1425 
1426  if (hostdn == NULL ||
1427  (tempbv = ldap_get_values_len (ld, hostent, "dhcpServiceDN")) == NULL ||
1428  tempbv[0] == NULL)
1429  {
1430  log_error ("Error: Cannot find LDAP entry matching %s", hfilter);
1431 
1432  if (tempbv != NULL)
1433  ldap_value_free_len (tempbv);
1434 
1435  if (hostdn)
1436  ldap_memfree (hostdn);
1437  ldap_msgfree (hostres);
1438  ldap_stop();
1439  return (ISC_R_FAILURE);
1440  }
1441 
1442 #if defined(DEBUG_LDAP)
1443  log_info ("LDAP: Parsing dhcpServer options '%s' ...", hostdn);
1444 #endif
1445 
1446  cfile->inbuf[0] = '\0';
1447  ldap_parse_entry_options(hostent, cfile->inbuf, LDAP_BUFFER_SIZE, NULL);
1448  cfile->buflen = strlen (cfile->inbuf);
1449  if(cfile->buflen > 0)
1450  {
1451  ldap_write_debug (cfile->inbuf, cfile->buflen);
1452 
1453  res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
1454  if (res != ISC_R_SUCCESS)
1455  {
1456  log_error ("LDAP: cannot parse dhcpServer entry '%s'", hostdn);
1457  ldap_memfree (hostdn);
1458  ldap_stop();
1459  return res;
1460  }
1461  cfile->inbuf[0] = '\0';
1462  }
1463  ldap_msgfree (hostres);
1464 
1465  /*
1466  ** attach ldap (tree) read function now
1467  */
1468  cfile->bufix = cfile->buflen = 0;
1469  cfile->read_function = ldap_read_function;
1470 
1471  res = ISC_R_SUCCESS;
1472  for (cnt=0; tempbv[cnt] != NULL; cnt++)
1473  {
1474  snprintf(sfilter, sizeof(sfilter), "(&(objectClass=dhcpService)"
1475  "(|(dhcpPrimaryDN=%s)(dhcpSecondaryDN=%s)))",
1476  hostdn, hostdn);
1477  ldres = NULL;
1478  if ((ret = ldap_search_ext_s (ld, tempbv[cnt]->bv_val, LDAP_SCOPE_BASE,
1479  sfilter, NULL, 0, NULL, NULL, NULL,
1480  0, &ldres)) != LDAP_SUCCESS)
1481  {
1482  log_error ("Error searching for dhcpServiceDN '%s': %s. Please update the LDAP entry '%s'",
1483  tempbv[cnt]->bv_val, ldap_err2string (ret), hostdn);
1484  if(NULL != ldres)
1485  ldap_msgfree(ldres);
1486  res = ISC_R_FAILURE;
1487  break;
1488  }
1489 
1490  if ((ent = ldap_first_entry (ld, ldres)) == NULL)
1491  {
1492  log_error ("Error: Cannot find dhcpService DN '%s' with primary or secondary server reference. Please update the LDAP server entry '%s'",
1493  tempbv[cnt]->bv_val, hostdn);
1494 
1495  ldap_msgfree(ldres);
1496  res = ISC_R_FAILURE;
1497  break;
1498  }
1499 
1500  /*
1501  ** FIXME: how to free the remembered dn's on exit?
1502  ** This should be OK if dmalloc registers the
1503  ** memory it allocated and frees it on exit..
1504  */
1505 
1506  curr = dmalloc (sizeof (*curr), MDL);
1507  if (curr != NULL)
1508  {
1509  length = strlen (tempbv[cnt]->bv_val);
1510  curr->dn = dmalloc (length + 1, MDL);
1511  if (curr->dn == NULL)
1512  {
1513  dfree (curr, MDL);
1514  curr = NULL;
1515  }
1516  else
1517  strcpy (curr->dn, tempbv[cnt]->bv_val);
1518  }
1519 
1520  if (curr != NULL)
1521  {
1522  curr->refs++;
1523 
1524  /* append to service-dn list */
1525  if (ldap_service_dn_tail != NULL)
1526  ldap_service_dn_tail->next = curr;
1527  else
1528  ldap_service_dn_head = curr;
1529 
1530  ldap_service_dn_tail = curr;
1531  }
1532  else
1533  log_fatal ("no memory to remember ldap service dn");
1534 
1535 #if defined (DEBUG_LDAP)
1536  log_info ("LDAP: Parsing dhcpService DN '%s' ...", tempbv[cnt]);
1537 #endif
1538  add_to_config_stack (ldres, ent);
1539  res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
1540  if (res != ISC_R_SUCCESS)
1541  {
1542  log_error ("LDAP: cannot parse dhcpService entry '%s'", tempbv[cnt]->bv_val);
1543  break;
1544  }
1545  }
1546 
1547  end_parse (&cfile);
1548  ldap_close_debug_fd();
1549 
1550  ldap_memfree (hostdn);
1551  ldap_value_free_len (tempbv);
1552 
1553  if (res != ISC_R_SUCCESS)
1554  {
1555  struct ldap_config_stack *temp_stack;
1556 
1557  while ((curr = ldap_service_dn_head) != NULL)
1558  {
1559  ldap_service_dn_head = curr->next;
1560  dfree (curr->dn, MDL);
1561  dfree (curr, MDL);
1562  }
1563 
1564  ldap_service_dn_tail = NULL;
1565 
1566  while ((temp_stack = ldap_stack) != NULL)
1567  {
1568  ldap_stack = temp_stack->next;
1569  free_stack_entry (temp_stack);
1570  }
1571 
1572  ldap_stop();
1573  }
1574 
1575  /* Unbind from ldap immediately after reading config in static mode. */
1576  if (ldap_method == LDAP_METHOD_STATIC)
1577  ldap_stop();
1578 
1579  return (res);
1580 }
1581 
1582 
1583 /* This function will parse the dhcpOption and dhcpStatements field in the LDAP
1584  entry if it exists. Right now, type will be either HOST_DECL or CLASS_DECL.
1585  If we are parsing a HOST_DECL, this always returns 0. If we are parsing a
1586  CLASS_DECL, this will return what the current lease limit is in LDAP. If
1587  there is no lease limit specified, we return 0 */
1588 
1589 static int
1590 ldap_parse_options (LDAPMessage * ent, struct group *group,
1591  int type, struct host_decl *host,
1592  struct class **class)
1593 {
1594  int declaration, lease_limit;
1595  char option_buffer[8192];
1596  enum dhcp_token token;
1597  struct parse *cfile;
1598  isc_result_t res;
1599  const char *val;
1600 
1601  lease_limit = 0;
1602  *option_buffer = '\0';
1603 
1604  /* This block of code will try to find the parent of the host, and
1605  if it is a group object, fetch the options and apply to the host. */
1606  if (type == HOST_DECL)
1607  {
1608  char *hostdn, *basedn, *temp1, *temp2, filter[1024];
1609  LDAPMessage *groupdn, *entry;
1610  int ret;
1611 
1612  hostdn = ldap_get_dn (ld, ent);
1613  if( hostdn != NULL)
1614  {
1615  basedn = NULL;
1616 
1617  temp1 = strchr (hostdn, '=');
1618  if (temp1 != NULL)
1619  temp1 = strchr (++temp1, '=');
1620  if (temp1 != NULL)
1621  temp2 = strchr (++temp1, ',');
1622  else
1623  temp2 = NULL;
1624 
1625  if (temp2 != NULL)
1626  {
1627  snprintf (filter, sizeof(filter),
1628  "(&(cn=%.*s)(objectClass=dhcpGroup))",
1629  (int)(temp2 - temp1), temp1);
1630 
1631  basedn = strchr (temp1, ',');
1632  if (basedn != NULL)
1633  ++basedn;
1634  }
1635 
1636  if (basedn != NULL && *basedn != '\0')
1637  {
1638  ret = ldap_search_ext_s (ld, basedn, LDAP_SCOPE_SUBTREE, filter,
1639  NULL, 0, NULL, NULL, NULL, 0, &groupdn);
1640  if (ret == LDAP_SUCCESS)
1641  {
1642  if ((entry = ldap_first_entry (ld, groupdn)) != NULL)
1643  {
1644  res = ldap_parse_entry_options (entry, option_buffer,
1645  sizeof(option_buffer) - 1,
1646  &lease_limit);
1647  if (res != ISC_R_SUCCESS)
1648  {
1649  /* reset option buffer discarding any results */
1650  *option_buffer = '\0';
1651  lease_limit = 0;
1652  }
1653  }
1654  ldap_msgfree( groupdn);
1655  }
1656  }
1657  ldap_memfree( hostdn);
1658  }
1659  }
1660 
1661  res = ldap_parse_entry_options (ent, option_buffer, sizeof(option_buffer) - 1,
1662  &lease_limit);
1663  if (res != ISC_R_SUCCESS)
1664  return (lease_limit);
1665 
1666  option_buffer[sizeof(option_buffer) - 1] = '\0';
1667  if (*option_buffer == '\0')
1668  return (lease_limit);
1669 
1670  cfile = (struct parse *) NULL;
1671  res = new_parse (&cfile, -1, option_buffer, strlen (option_buffer),
1672  type == HOST_DECL ? "LDAP-HOST" : "LDAP-SUBCLASS", 0);
1673  if (res != ISC_R_SUCCESS)
1674  return (lease_limit);
1675 
1676 #if defined (DEBUG_LDAP)
1677  log_info ("Sending the following options: '%s'", option_buffer);
1678 #endif
1679 
1680  declaration = 0;
1681  do
1682  {
1683  token = peek_token (&val, NULL, cfile);
1684  if (token == END_OF_FILE)
1685  break;
1686  declaration = parse_statement (cfile, group, type, host, declaration);
1687  } while (1);
1688 
1689  end_parse (&cfile);
1690 
1691  return (lease_limit);
1692 }
1693 
1694 
1695 
1696 int
1697 find_haddr_in_ldap (struct host_decl **hp, int htype, unsigned hlen,
1698  const unsigned char *haddr, const char *file, int line)
1699 {
1700  char buf[128], *type_str;
1701  LDAPMessage * res, *ent;
1702  struct host_decl * host;
1703  isc_result_t status;
1704  ldap_dn_node *curr;
1705  int ret;
1706 
1707  if (ldap_method == LDAP_METHOD_STATIC)
1708  return (0);
1709 
1710  if (ld == NULL)
1711  ldap_start ();
1712  if (ld == NULL)
1713  return (0);
1714 
1715  switch (htype)
1716  {
1717  case HTYPE_ETHER:
1718  type_str = "ethernet";
1719  break;
1720  case HTYPE_IEEE802:
1721  type_str = "token-ring";
1722  break;
1723  case HTYPE_FDDI:
1724  type_str = "fddi";
1725  break;
1726  default:
1727  log_info ("Ignoring unknown type %d", htype);
1728  return (0);
1729  }
1730 
1731  /*
1732  ** FIXME: It is not guaranteed, that the dhcpHWAddress attribute
1733  ** contains _exactly_ "type addr" with one space between!
1734  */
1735  snprintf (buf, sizeof (buf),
1736  "(&(objectClass=dhcpHost)(dhcpHWAddress=%s %s))",
1737  type_str, print_hw_addr (htype, hlen, haddr));
1738 
1739  res = ent = NULL;
1740  for (curr = ldap_service_dn_head;
1741  curr != NULL && *curr->dn != '\0';
1742  curr = curr->next)
1743  {
1744 #if defined (DEBUG_LDAP)
1745  log_info ("Searching for %s in LDAP tree %s", buf, curr->dn);
1746 #endif
1747  ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL, 0,
1748  NULL, NULL, NULL, 0, &res);
1749 
1750  if(ret == LDAP_SERVER_DOWN)
1751  {
1752  log_info ("LDAP server was down, trying to reconnect...");
1753 
1754  ldap_stop();
1755  ldap_start();
1756  if(ld == NULL)
1757  {
1758  log_info ("LDAP reconnect failed - try again later...");
1759  return (0);
1760  }
1761 
1762  ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL,
1763  0, NULL, NULL, NULL, 0, &res);
1764  }
1765 
1766  if (ret == LDAP_SUCCESS)
1767  {
1768  if( (ent = ldap_first_entry (ld, res)) != NULL)
1769  break; /* search OK and have entry */
1770 
1771 #if defined (DEBUG_LDAP)
1772  log_info ("No host entry for %s in LDAP tree %s",
1773  buf, curr->dn);
1774 #endif
1775  if(res)
1776  {
1777  ldap_msgfree (res);
1778  res = NULL;
1779  }
1780  }
1781  else
1782  {
1783  if(res)
1784  {
1785  ldap_msgfree (res);
1786  res = NULL;
1787  }
1788 
1789  if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
1790  {
1791  log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
1792  curr->dn, ldap_err2string (ret));
1793  ldap_stop();
1794  return (0);
1795  }
1796 #if defined (DEBUG_LDAP)
1797  else
1798  {
1799  log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
1800  ldap_err2string (ret), buf, curr->dn);
1801  }
1802 #endif
1803  }
1804  }
1805 
1806  if (res && ent)
1807  {
1808 #if defined (DEBUG_LDAP)
1809  char *dn = ldap_get_dn (ld, ent);
1810  if (dn != NULL)
1811  {
1812  log_info ("Found dhcpHWAddress LDAP entry %s", dn);
1813  ldap_memfree(dn);
1814  }
1815 #endif
1816 
1817  host = (struct host_decl *)0;
1818  status = host_allocate (&host, MDL);
1819  if (status != ISC_R_SUCCESS)
1820  {
1821  log_fatal ("can't allocate host decl struct: %s",
1822  isc_result_totext (status));
1823  ldap_msgfree (res);
1824  return (0);
1825  }
1826 
1827  host->name = ldap_get_host_name (ent);
1828  if (host->name == NULL)
1829  {
1830  host_dereference (&host, MDL);
1831  ldap_msgfree (res);
1832  return (0);
1833  }
1834 
1835  if (!clone_group (&host->group, root_group, MDL))
1836  {
1837  log_fatal ("can't clone group for host %s", host->name);
1838  host_dereference (&host, MDL);
1839  ldap_msgfree (res);
1840  return (0);
1841  }
1842 
1843  ldap_parse_options (ent, host->group, HOST_DECL, host, NULL);
1844 
1845  *hp = host;
1846  ldap_msgfree (res);
1847  return (1);
1848  }
1849 
1850 
1851  if(res) ldap_msgfree (res);
1852  return (0);
1853 }
1854 
1855 
1856 int
1857 find_subclass_in_ldap (struct class *class, struct class **newclass,
1858  struct data_string *data)
1859 {
1860  LDAPMessage * res, * ent;
1861  int ret, lease_limit;
1862  isc_result_t status;
1863  ldap_dn_node *curr;
1864  char buf[1024];
1865 
1866  if (ldap_method == LDAP_METHOD_STATIC)
1867  return (0);
1868 
1869  if (ld == NULL)
1870  ldap_start ();
1871  if (ld == NULL)
1872  return (0);
1873 
1874  snprintf (buf, sizeof (buf),
1875  "(&(objectClass=dhcpSubClass)(cn=%s)(dhcpClassData=%s))",
1876  print_hex_1 (data->len, data->data, 60),
1877  print_hex_2 (strlen (class->name), (u_int8_t *) class->name, 60));
1878 #if defined (DEBUG_LDAP)
1879  log_info ("Searching LDAP for %s", buf);
1880 #endif
1881 
1882  res = ent = NULL;
1883  for (curr = ldap_service_dn_head;
1884  curr != NULL && *curr->dn != '\0';
1885  curr = curr->next)
1886  {
1887 #if defined (DEBUG_LDAP)
1888  log_info ("Searching for %s in LDAP tree %s", buf, curr->dn);
1889 #endif
1890  ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL, 0,
1891  NULL, NULL, NULL, 0, &res);
1892 
1893  if(ret == LDAP_SERVER_DOWN)
1894  {
1895  log_info ("LDAP server was down, trying to reconnect...");
1896 
1897  ldap_stop();
1898  ldap_start();
1899 
1900  if(ld == NULL)
1901  {
1902  log_info ("LDAP reconnect failed - try again later...");
1903  return (0);
1904  }
1905 
1906  ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf,
1907  NULL, 0, NULL, NULL, NULL, 0, &res);
1908  }
1909 
1910  if (ret == LDAP_SUCCESS)
1911  {
1912  if( (ent = ldap_first_entry (ld, res)) != NULL)
1913  break; /* search OK and have entry */
1914 
1915 #if defined (DEBUG_LDAP)
1916  log_info ("No subclass entry for %s in LDAP tree %s",
1917  buf, curr->dn);
1918 #endif
1919  if(res)
1920  {
1921  ldap_msgfree (res);
1922  res = NULL;
1923  }
1924  }
1925  else
1926  {
1927  if(res)
1928  {
1929  ldap_msgfree (res);
1930  res = NULL;
1931  }
1932 
1933  if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
1934  {
1935  log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
1936  curr->dn, ldap_err2string (ret));
1937  ldap_stop();
1938  return (0);
1939  }
1940 #if defined (DEBUG_LDAP)
1941  else
1942  {
1943  log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
1944  ldap_err2string (ret), buf, curr->dn);
1945  }
1946 #endif
1947  }
1948  }
1949 
1950  if (res && ent)
1951  {
1952 #if defined (DEBUG_LDAP)
1953  char *dn = ldap_get_dn (ld, ent);
1954  if (dn != NULL)
1955  {
1956  log_info ("Found subclass LDAP entry %s", dn);
1957  ldap_memfree(dn);
1958  }
1959 #endif
1960 
1961  status = class_allocate (newclass, MDL);
1962  if (status != ISC_R_SUCCESS)
1963  {
1964  log_error ("Cannot allocate memory for a new class");
1965  ldap_msgfree (res);
1966  return (0);
1967  }
1968 
1969  group_reference (&(*newclass)->group, class->group, MDL);
1970  class_reference (&(*newclass)->superclass, class, MDL);
1971  lease_limit = ldap_parse_options (ent, (*newclass)->group,
1972  CLASS_DECL, NULL, newclass);
1973  if (lease_limit == 0)
1974  (*newclass)->lease_limit = class->lease_limit;
1975  else
1976  class->lease_limit = lease_limit;
1977 
1978  if ((*newclass)->lease_limit)
1979  {
1980  (*newclass)->billed_leases =
1981  dmalloc ((*newclass)->lease_limit * sizeof (struct lease *), MDL);
1982  if (!(*newclass)->billed_leases)
1983  {
1984  log_error ("no memory for billing");
1985  class_dereference (newclass, MDL);
1986  ldap_msgfree (res);
1987  return (0);
1988  }
1989  memset ((*newclass)->billed_leases, 0,
1990  ((*newclass)->lease_limit * sizeof (struct lease *)));
1991  }
1992 
1993  data_string_copy (&(*newclass)->hash_string, data, MDL);
1994 
1995  ldap_msgfree (res);
1996  return (1);
1997  }
1998 
1999  if(res) ldap_msgfree (res);
2000  return (0);
2001 }
2002 
2003 #endif
const char int line
Definition: dhcpd.h:3557
struct binding_scope * global_scope
Definition: tree.c:39
Definition: dhcpd.h:507
unsigned len
Definition: tree.h:80
isc_result_t end_parse(struct parse **cfile)
Definition: conflex.c:103
void * dmalloc(unsigned, const char *, int)
Definition: alloc.c:56
struct universe server_universe
Definition: stables.c:175
size_t buflen
Definition: dhcpd.h:293
#define MDL
Definition: omapip.h:568
#define print_hex_1(len, data, limit)
Definition: dhcpd.h:2424
int group_reference(struct group **ptr, struct group *bp, const char *file, int line)
Definition: alloc.c:178
void data_string_forget(struct data_string *data, const char *file, int line)
Definition: alloc.c:1276
struct group * root_group
Definition: memory.c:31
int log_error(const char *,...) __attribute__((__format__(__printf__
enum dhcp_token peek_token(const char **rval, unsigned *rlen, struct parse *cfile)
Definition: conflex.c:429
Definition: dhcpd.h:252
char * name
Definition: dhcpd.h:983
void log_fatal(const char *,...) __attribute__((__format__(__printf__
#define HTYPE_ETHER
Definition: dhcp.h:76
void execute_statements_in_scope(struct binding_value **result, struct packet *packet, struct lease *lease, struct client_state *client_state, struct option_state *in_options, struct option_state *out_options, struct binding_scope **scope, struct group *group, struct group *limiting_group, struct on_star *on_star)
Definition: execute.c:555
int option_state_allocate(struct option_state **ptr, const char *file, int line)
Definition: alloc.c:847
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)
Definition: tree.c:2643
Definition: dhcpd.h:369
char * name
Definition: dhcpd.h:867
void dfree(void *, const char *, int)
Definition: alloc.c:131
struct option_cache * lookup_option(struct universe *universe, struct option_state *options, unsigned code)
Definition: options.c:2303
int int log_info(const char *,...) __attribute__((__format__(__printf__
#define CLASS_DECL
Definition: dhcpd.h:627
dhcp_token
Definition: dhctoken.h:35
#define ROOT_GROUP
Definition: dhcpd.h:623
#define HTYPE_FDDI
Definition: dhcp.h:78
int parse_statement(struct parse *, struct group *, int, struct host_decl *, int)
Definition: confpars.c:351
int option_state_dereference(struct option_state **ptr, const char *file, int line)
Definition: alloc.c:912
Definition: dhcpd.h:851
#define print_hex_2(len, data, limit)
Definition: dhcpd.h:2425
const char int
Definition: omapip.h:443
Definition: tree.h:61
size_t bufix
Definition: dhcpd.h:293
#define HOST_DECL
Definition: dhcpd.h:624
#define HTYPE_IEEE802
Definition: dhcp.h:77
const char * file
Definition: dhcpd.h:3557
char * inbuf
Definition: dhcpd.h:292
Definition: dhcpd.h:979
const unsigned char * data
Definition: tree.h:79
isc_result_t conf_file_subparse(struct parse *, struct group *, int)
Definition: confpars.c:239
void data_string_copy(struct data_string *dest, const struct data_string *src, const char *file, int line)
Definition: alloc.c:1260
int clone_group(struct group **gp, struct group *group, const char *file, int line)
Definition: memory.c:130
isc_result_t new_parse(struct parse **cfile, int file, char *inbuf, unsigned buflen, const char *name, int eolp)
Definition: conflex.c:41
struct group * group
Definition: dhcpd.h:877
struct group * group
Definition: dhcpd.h:1006