1 /* $NetBSD: ldap.c,v 1.1.1.4 2014/07/12 11:58:13 spz Exp $ */
4 Routines for reading the configuration from LDAP */
7 * Copyright (c) 2003-2006 Ntelos, Inc.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of The Internet Software Consortium nor the names
20 * of its contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
24 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
31 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * This LDAP module was written by Brian Masney <masneyb@ntelos.net>. Its
38 * development was sponsored by Ntelos, Inc. (www.ntelos.com).
41 #include <sys/cdefs.h>
42 __RCSID("$NetBSD: ldap.c,v 1.1.1.4 2014/07/12 11:58:13 spz Exp $");
48 #if defined(LDAP_CONFIGURATION)
50 #if defined(LDAP_CASA_AUTH)
51 #include "ldap_casa.h"
54 static LDAP
* ld
= NULL
;
55 static char *ldap_server
= NULL
,
56 *ldap_username
= NULL
,
57 *ldap_password
= NULL
,
59 *ldap_dhcp_server_cn
= NULL
,
60 *ldap_debug_file
= NULL
;
61 static int ldap_port
= LDAP_PORT
,
62 ldap_method
= LDAP_METHOD_DYNAMIC
,
65 #if defined (LDAP_USE_SSL)
66 static int ldap_use_ssl
= -1, /* try TLS if possible */
67 ldap_tls_reqcert
= -1,
68 ldap_tls_crlcheck
= -1;
69 static char *ldap_tls_ca_file
= NULL
,
70 *ldap_tls_ca_dir
= NULL
,
71 *ldap_tls_cert
= NULL
,
73 *ldap_tls_ciphers
= NULL
,
74 *ldap_tls_randfile
= NULL
;
76 static struct ldap_config_stack
*ldap_stack
= NULL
;
78 typedef struct ldap_dn_node
{
79 struct ldap_dn_node
*next
;
84 static ldap_dn_node
*ldap_service_dn_head
= NULL
;
85 static ldap_dn_node
*ldap_service_dn_tail
= NULL
;
89 x_strncat(char *dst
, const char *src
, size_t dst_size
)
91 size_t len
= strlen(dst
);
92 return strncat(dst
, src
, dst_size
> len
? dst_size
- len
- 1: 0);
96 ldap_parse_class (struct ldap_config_stack
*item
, struct parse
*cfile
)
98 struct berval
**tempbv
;
100 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) == NULL
||
104 ldap_value_free_len (tempbv
);
109 x_strncat (cfile
->inbuf
, "class \"", LDAP_BUFFER_SIZE
);
110 x_strncat (cfile
->inbuf
, tempbv
[0]->bv_val
, LDAP_BUFFER_SIZE
);
111 x_strncat (cfile
->inbuf
, "\" {\n", LDAP_BUFFER_SIZE
);
113 item
->close_brace
= 1;
114 ldap_value_free_len (tempbv
);
119 ldap_parse_subclass (struct ldap_config_stack
*item
, struct parse
*cfile
)
121 struct berval
**tempbv
, **classdata
;
123 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) == NULL
||
127 ldap_value_free_len (tempbv
);
132 if ((classdata
= ldap_get_values_len (ld
, item
->ldent
,
133 "dhcpClassData")) == NULL
||
134 classdata
[0] == NULL
)
136 if (classdata
!= NULL
)
137 ldap_value_free_len (classdata
);
138 ldap_value_free_len (tempbv
);
143 x_strncat (cfile
->inbuf
, "subclass ", LDAP_BUFFER_SIZE
);
144 x_strncat (cfile
->inbuf
, classdata
[0]->bv_val
, LDAP_BUFFER_SIZE
);
145 x_strncat (cfile
->inbuf
, " ", LDAP_BUFFER_SIZE
);
146 x_strncat (cfile
->inbuf
, tempbv
[0]->bv_val
, LDAP_BUFFER_SIZE
);
147 x_strncat (cfile
->inbuf
, " {\n", LDAP_BUFFER_SIZE
);
149 item
->close_brace
= 1;
150 ldap_value_free_len (tempbv
);
151 ldap_value_free_len (classdata
);
156 ldap_parse_host (struct ldap_config_stack
*item
, struct parse
*cfile
)
158 struct berval
**tempbv
, **hwaddr
;
160 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) == NULL
||
164 ldap_value_free_len (tempbv
);
169 hwaddr
= ldap_get_values_len (ld
, item
->ldent
, "dhcpHWAddress");
171 x_strncat (cfile
->inbuf
, "host ", LDAP_BUFFER_SIZE
);
172 x_strncat (cfile
->inbuf
, tempbv
[0]->bv_val
, LDAP_BUFFER_SIZE
);
174 if (hwaddr
!= NULL
&& hwaddr
[0] != NULL
)
176 x_strncat (cfile
->inbuf
, " {\nhardware ", LDAP_BUFFER_SIZE
);
177 x_strncat (cfile
->inbuf
, hwaddr
[0]->bv_val
, LDAP_BUFFER_SIZE
);
178 x_strncat (cfile
->inbuf
, ";\n", LDAP_BUFFER_SIZE
);
179 ldap_value_free_len (hwaddr
);
182 item
->close_brace
= 1;
183 ldap_value_free_len (tempbv
);
188 ldap_parse_shared_network (struct ldap_config_stack
*item
, struct parse
*cfile
)
190 struct berval
**tempbv
;
192 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) == NULL
||
196 ldap_value_free_len (tempbv
);
201 x_strncat (cfile
->inbuf
, "shared-network \"", LDAP_BUFFER_SIZE
);
202 x_strncat (cfile
->inbuf
, tempbv
[0]->bv_val
, LDAP_BUFFER_SIZE
);
203 x_strncat (cfile
->inbuf
, "\" {\n", LDAP_BUFFER_SIZE
);
205 item
->close_brace
= 1;
206 ldap_value_free_len (tempbv
);
211 parse_netmask (int netmask
, char *netmaskbuf
)
217 for (i
=1; i
<= netmask
; i
++)
222 sprintf (netmaskbuf
, "%d.%d.%d.%d", (int) (nm
>> 24) & 0xff,
223 (int) (nm
>> 16) & 0xff,
224 (int) (nm
>> 8) & 0xff,
230 ldap_parse_subnet (struct ldap_config_stack
*item
, struct parse
*cfile
)
232 struct berval
**tempbv
, **netmaskstr
;
233 char netmaskbuf
[sizeof("255.255.255.255")];
236 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) == NULL
||
240 ldap_value_free_len (tempbv
);
245 if ((netmaskstr
= ldap_get_values_len (ld
, item
->ldent
,
246 "dhcpNetmask")) == NULL
||
247 netmaskstr
[0] == NULL
)
249 if (netmaskstr
!= NULL
)
250 ldap_value_free_len (netmaskstr
);
251 ldap_value_free_len (tempbv
);
256 x_strncat (cfile
->inbuf
, "subnet ", LDAP_BUFFER_SIZE
);
257 x_strncat (cfile
->inbuf
, tempbv
[0]->bv_val
, LDAP_BUFFER_SIZE
);
259 x_strncat (cfile
->inbuf
, " netmask ", LDAP_BUFFER_SIZE
);
260 parse_netmask (strtol (netmaskstr
[0]->bv_val
, NULL
, 10), netmaskbuf
);
261 x_strncat (cfile
->inbuf
, netmaskbuf
, LDAP_BUFFER_SIZE
);
263 x_strncat (cfile
->inbuf
, " {\n", LDAP_BUFFER_SIZE
);
265 ldap_value_free_len (tempbv
);
266 ldap_value_free_len (netmaskstr
);
268 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpRange")) != NULL
)
270 for (i
=0; tempbv
[i
] != NULL
; i
++)
272 x_strncat (cfile
->inbuf
, "range", LDAP_BUFFER_SIZE
);
273 x_strncat (cfile
->inbuf
, " ", LDAP_BUFFER_SIZE
);
274 x_strncat (cfile
->inbuf
, tempbv
[i
]->bv_val
, LDAP_BUFFER_SIZE
);
275 x_strncat (cfile
->inbuf
, ";\n", LDAP_BUFFER_SIZE
);
279 item
->close_brace
= 1;
284 ldap_parse_pool (struct ldap_config_stack
*item
, struct parse
*cfile
)
286 struct berval
**tempbv
;
289 x_strncat (cfile
->inbuf
, "pool {\n", LDAP_BUFFER_SIZE
);
291 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpRange")) != NULL
)
293 x_strncat (cfile
->inbuf
, "range", LDAP_BUFFER_SIZE
);
294 for (i
=0; tempbv
[i
] != NULL
; i
++)
296 x_strncat (cfile
->inbuf
, " ", LDAP_BUFFER_SIZE
);
297 x_strncat (cfile
->inbuf
, tempbv
[i
]->bv_val
, LDAP_BUFFER_SIZE
);
299 x_strncat (cfile
->inbuf
, ";\n", LDAP_BUFFER_SIZE
);
300 ldap_value_free_len (tempbv
);
303 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpPermitList")) != NULL
)
305 for (i
=0; tempbv
[i
] != NULL
; i
++)
307 x_strncat (cfile
->inbuf
, tempbv
[i
]->bv_val
, LDAP_BUFFER_SIZE
);
308 x_strncat (cfile
->inbuf
, ";\n", LDAP_BUFFER_SIZE
);
310 ldap_value_free_len (tempbv
);
313 item
->close_brace
= 1;
318 ldap_parse_group (struct ldap_config_stack
*item
, struct parse
*cfile
)
320 x_strncat (cfile
->inbuf
, "group {\n", LDAP_BUFFER_SIZE
);
321 item
->close_brace
= 1;
326 ldap_parse_key (struct ldap_config_stack
*item
, struct parse
*cfile
)
328 struct berval
**tempbv
;
330 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) != NULL
)
332 x_strncat (cfile
->inbuf
, "key ", LDAP_BUFFER_SIZE
);
333 x_strncat (cfile
->inbuf
, tempbv
[0]->bv_val
, LDAP_BUFFER_SIZE
);
334 x_strncat (cfile
->inbuf
, " {\n", LDAP_BUFFER_SIZE
);
335 ldap_value_free_len (tempbv
);
338 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpKeyAlgorithm")) != NULL
)
340 x_strncat (cfile
->inbuf
, "algorithm ", LDAP_BUFFER_SIZE
);
341 x_strncat (cfile
->inbuf
, tempbv
[0]->bv_val
, LDAP_BUFFER_SIZE
);
342 x_strncat (cfile
->inbuf
, ";\n", LDAP_BUFFER_SIZE
);
343 ldap_value_free_len (tempbv
);
346 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpKeySecret")) != NULL
)
348 x_strncat (cfile
->inbuf
, "secret ", LDAP_BUFFER_SIZE
);
349 x_strncat (cfile
->inbuf
, tempbv
[0]->bv_val
, LDAP_BUFFER_SIZE
);
350 x_strncat (cfile
->inbuf
, ";\n", LDAP_BUFFER_SIZE
);
351 ldap_value_free_len (tempbv
);
354 item
->close_brace
= 1;
359 ldap_parse_zone (struct ldap_config_stack
*item
, struct parse
*cfile
)
361 char *cnFindStart
, *cnFindEnd
;
362 struct berval
**tempbv
;
366 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) != NULL
)
368 x_strncat (cfile
->inbuf
, "zone ", LDAP_BUFFER_SIZE
);
369 x_strncat (cfile
->inbuf
, tempbv
[0]->bv_val
, LDAP_BUFFER_SIZE
);
370 x_strncat (cfile
->inbuf
, " {\n", LDAP_BUFFER_SIZE
);
371 ldap_value_free_len (tempbv
);
374 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpDnsZoneServer")) != NULL
)
376 x_strncat (cfile
->inbuf
, "primary ", LDAP_BUFFER_SIZE
);
377 x_strncat (cfile
->inbuf
, tempbv
[0]->bv_val
, LDAP_BUFFER_SIZE
);
379 x_strncat (cfile
->inbuf
, ";\n", LDAP_BUFFER_SIZE
);
380 ldap_value_free_len (tempbv
);
383 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpKeyDN")) != NULL
)
385 cnFindStart
= strchr(tempbv
[0]->bv_val
,'=');
386 if (cnFindStart
!= NULL
)
387 cnFindEnd
= strchr(++cnFindStart
,',');
391 if (cnFindEnd
!= NULL
&& cnFindEnd
> cnFindStart
)
393 len
= cnFindEnd
- cnFindStart
;
394 keyCn
= dmalloc (len
+ 1, MDL
);
404 strncpy (keyCn
, cnFindStart
, len
);
407 x_strncat (cfile
->inbuf
, "key ", LDAP_BUFFER_SIZE
);
408 x_strncat (cfile
->inbuf
, keyCn
, LDAP_BUFFER_SIZE
);
409 x_strncat (cfile
->inbuf
, ";\n", LDAP_BUFFER_SIZE
);
414 ldap_value_free_len (tempbv
);
417 item
->close_brace
= 1;
422 add_to_config_stack (LDAPMessage
* res
, LDAPMessage
* ent
)
424 struct ldap_config_stack
*ns
;
426 ns
= dmalloc (sizeof (*ns
), MDL
);
431 ns
->next
= ldap_stack
;
439 struct sigaction old
, new;
445 ** ldap_unbind after a LDAP_SERVER_DOWN result
446 ** causes a SIGPIPE and dhcpd gets terminated,
447 ** since it doesn't handle it...
451 new.sa_handler
= SIG_IGN
;
452 sigemptyset (&new.sa_mask
);
453 sigaction (SIGPIPE
, &new, &old
);
455 ldap_unbind_ext_s (ld
, NULL
, NULL
);
458 sigaction (SIGPIPE
, &old
, &new);
463 _do_lookup_dhcp_string_option (struct option_state
*options
, int option_name
)
465 struct option_cache
*oc
;
466 struct data_string db
;
469 memset (&db
, 0, sizeof (db
));
470 oc
= lookup_option (&server_universe
, options
, option_name
);
472 evaluate_option_cache (&db
, (struct packet
*) NULL
,
473 (struct lease
*) NULL
,
474 (struct client_state
*) NULL
, options
,
475 (struct option_state
*) NULL
,
476 &global_scope
, oc
, MDL
) &&
477 db
.data
!= NULL
&& *db
.data
!= '\0')
480 ret
= dmalloc (db
.len
+ 1, MDL
);
482 log_fatal ("no memory for ldap option %d value", option_name
);
484 memcpy (ret
, db
.data
, db
.len
);
486 data_string_forget (&db
, MDL
);
496 _do_lookup_dhcp_int_option (struct option_state
*options
, int option_name
)
498 struct option_cache
*oc
;
499 struct data_string db
;
502 memset (&db
, 0, sizeof (db
));
503 oc
= lookup_option (&server_universe
, options
, option_name
);
505 evaluate_option_cache (&db
, (struct packet
*) NULL
,
506 (struct lease
*) NULL
,
507 (struct client_state
*) NULL
, options
,
508 (struct option_state
*) NULL
,
509 &global_scope
, oc
, MDL
) &&
510 db
.data
!= NULL
&& *db
.data
!= '\0')
512 ret
= strtol ((const char *) db
.data
, NULL
, 10);
513 data_string_forget (&db
, MDL
);
523 _do_lookup_dhcp_enum_option (struct option_state
*options
, int option_name
)
525 struct option_cache
*oc
;
526 struct data_string db
;
529 memset (&db
, 0, sizeof (db
));
530 oc
= lookup_option (&server_universe
, options
, option_name
);
532 evaluate_option_cache (&db
, (struct packet
*) NULL
,
533 (struct lease
*) NULL
,
534 (struct client_state
*) NULL
, options
,
535 (struct option_state
*) NULL
,
536 &global_scope
, oc
, MDL
) &&
537 db
.data
!= NULL
&& *db
.data
!= '\0')
542 log_fatal ("invalid option name %d", option_name
);
544 data_string_forget (&db
, MDL
);
553 ldap_rebind_cb (LDAP
*ld
, LDAP_CONST
char *url
, ber_tag_t request
, ber_int_t msgid
, void *parms
)
556 LDAPURLDesc
*ldapurl
= NULL
;
560 log_info("LDAP rebind to '%s'", url
);
561 if ((ret
= ldap_url_parse(url
, &ldapurl
)) != LDAP_SUCCESS
)
563 log_error ("Error: Can not parse ldap rebind url '%s': %s",
564 url
, ldap_err2string(ret
));
569 #if defined (LDAP_USE_SSL)
570 if (strcasecmp(ldapurl
->lud_scheme
, "ldaps") == 0)
572 int opt
= LDAP_OPT_X_TLS_HARD
;
573 if ((ret
= ldap_set_option (ld
, LDAP_OPT_X_TLS
, &opt
)) != LDAP_SUCCESS
)
575 log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
576 ldapurl
->lud_host
, ldapurl
->lud_port
, ldap_err2string (ret
));
581 log_info ("LDAPS session successfully enabled to %s", ldap_server
);
585 if (strcasecmp(ldapurl
->lud_scheme
, "ldap") == 0 &&
586 ldap_use_ssl
!= LDAP_SSL_OFF
)
588 if ((ret
= ldap_start_tls_s (ld
, NULL
, NULL
)) != LDAP_SUCCESS
)
590 log_error ("Error: Cannot start TLS session to %s:%d: %s",
591 ldapurl
->lud_host
, ldapurl
->lud_port
, ldap_err2string (ret
));
596 log_info ("TLS session successfully started to %s:%d",
597 ldapurl
->lud_host
, ldapurl
->lud_port
);
603 if (ldap_username
!= NULL
|| *ldap_username
!= '\0')
606 creds
.bv_val
= strdup(ldap_password
);
607 creds
.bv_len
= strlen(ldap_password
);
610 if ((ret
= ldap_sasl_bind_s (ld
, who
, LDAP_SASL_SIMPLE
, &creds
,
611 NULL
, NULL
, NULL
)) != LDAP_SUCCESS
)
613 log_error ("Error: Cannot login into ldap server %s:%d: %s",
614 ldapurl
->lud_host
, ldapurl
->lud_port
, ldap_err2string (ret
));
622 struct option_state
*options
;
630 if (ldap_server
== NULL
)
633 option_state_allocate (&options
, MDL
);
635 execute_statements_in_scope (NULL
, NULL
, NULL
, NULL
, NULL
,
636 options
, &global_scope
, root_group
,
639 ldap_server
= _do_lookup_dhcp_string_option (options
, SV_LDAP_SERVER
);
640 ldap_dhcp_server_cn
= _do_lookup_dhcp_string_option (options
,
641 SV_LDAP_DHCP_SERVER_CN
);
642 ldap_port
= _do_lookup_dhcp_int_option (options
, SV_LDAP_PORT
);
643 ldap_base_dn
= _do_lookup_dhcp_string_option (options
, SV_LDAP_BASE_DN
);
644 ldap_method
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_METHOD
);
645 ldap_debug_file
= _do_lookup_dhcp_string_option (options
,
647 ldap_referrals
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_REFERRALS
);
649 #if defined (LDAP_USE_SSL)
650 ldap_use_ssl
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_SSL
);
651 if( ldap_use_ssl
!= LDAP_SSL_OFF
)
653 ldap_tls_reqcert
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_TLS_REQCERT
);
654 ldap_tls_ca_file
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_CA_FILE
);
655 ldap_tls_ca_dir
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_CA_DIR
);
656 ldap_tls_cert
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_CERT
);
657 ldap_tls_key
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_KEY
);
658 ldap_tls_crlcheck
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_TLS_CRLCHECK
);
659 ldap_tls_ciphers
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_CIPHERS
);
660 ldap_tls_randfile
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_RANDFILE
);
664 #if defined (LDAP_CASA_AUTH)
665 if (!load_uname_pwd_from_miCASA(&ldap_username
,&ldap_password
))
667 #if defined (DEBUG_LDAP)
668 log_info ("Authentication credential taken from file");
672 ldap_username
= _do_lookup_dhcp_string_option (options
, SV_LDAP_USERNAME
);
673 ldap_password
= _do_lookup_dhcp_string_option (options
, SV_LDAP_PASSWORD
);
675 #if defined (LDAP_CASA_AUTH)
679 option_state_dereference (&options
, MDL
);
682 if (ldap_server
== NULL
|| ldap_base_dn
== NULL
)
684 log_info ("Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not specified in the config file");
685 ldap_method
= LDAP_METHOD_STATIC
;
689 if (ldap_debug_file
!= NULL
&& ldap_debug_fd
== -1)
691 if ((ldap_debug_fd
= open (ldap_debug_file
, O_CREAT
| O_TRUNC
| O_WRONLY
,
692 S_IRUSR
| S_IWUSR
)) < 0)
693 log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file
,
697 #if defined (DEBUG_LDAP)
698 log_info ("Connecting to LDAP server %s:%d", ldap_server
, ldap_port
);
701 #if defined (LDAP_USE_SSL)
702 if (ldap_use_ssl
== -1)
705 ** There was no "ldap-ssl" option in dhcpd.conf (also not "off").
706 ** Let's try, if we can use an anonymous TLS session without to
707 ** verify the server certificate -- if not continue without TLS.
709 int opt
= LDAP_OPT_X_TLS_ALLOW
;
710 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_REQUIRE_CERT
,
711 &opt
)) != LDAP_SUCCESS
)
713 log_error ("Warning: Cannot set LDAP TLS require cert option to 'allow': %s",
714 ldap_err2string (ret
));
718 if (ldap_use_ssl
!= LDAP_SSL_OFF
)
720 if (ldap_tls_reqcert
!= -1)
722 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_REQUIRE_CERT
,
723 &ldap_tls_reqcert
)) != LDAP_SUCCESS
)
725 log_error ("Cannot set LDAP TLS require cert option: %s",
726 ldap_err2string (ret
));
730 if( ldap_tls_ca_file
!= NULL
)
732 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CACERTFILE
,
733 ldap_tls_ca_file
)) != LDAP_SUCCESS
)
735 log_error ("Cannot set LDAP TLS CA certificate file %s: %s",
736 ldap_tls_ca_file
, ldap_err2string (ret
));
739 if( ldap_tls_ca_dir
!= NULL
)
741 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CACERTDIR
,
742 ldap_tls_ca_dir
)) != LDAP_SUCCESS
)
744 log_error ("Cannot set LDAP TLS CA certificate dir %s: %s",
745 ldap_tls_ca_dir
, ldap_err2string (ret
));
748 if( ldap_tls_cert
!= NULL
)
750 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CERTFILE
,
751 ldap_tls_cert
)) != LDAP_SUCCESS
)
753 log_error ("Cannot set LDAP TLS client certificate file %s: %s",
754 ldap_tls_cert
, ldap_err2string (ret
));
757 if( ldap_tls_key
!= NULL
)
759 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_KEYFILE
,
760 ldap_tls_key
)) != LDAP_SUCCESS
)
762 log_error ("Cannot set LDAP TLS certificate key file %s: %s",
763 ldap_tls_key
, ldap_err2string (ret
));
766 if( ldap_tls_crlcheck
!= -1)
768 int opt
= ldap_tls_crlcheck
;
769 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CRLCHECK
,
770 &opt
)) != LDAP_SUCCESS
)
772 log_error ("Cannot set LDAP TLS crl check option: %s",
773 ldap_err2string (ret
));
776 if( ldap_tls_ciphers
!= NULL
)
778 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CIPHER_SUITE
,
779 ldap_tls_ciphers
)) != LDAP_SUCCESS
)
781 log_error ("Cannot set LDAP TLS cipher suite %s: %s",
782 ldap_tls_ciphers
, ldap_err2string (ret
));
785 if( ldap_tls_randfile
!= NULL
)
787 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_RANDOM_FILE
,
788 ldap_tls_randfile
)) != LDAP_SUCCESS
)
790 log_error ("Cannot set LDAP TLS random file %s: %s",
791 ldap_tls_randfile
, ldap_err2string (ret
));
797 /* enough for 'ldap://+ + hostname + ':' + port number */
798 uri
= malloc(strlen(ldap_server
) + 16);
801 log_error ("Cannot build ldap init URI %s:%d", ldap_server
, ldap_port
);
805 sprintf(uri
, "ldap://%s:%d", ldap_server
, ldap_port
);
806 ldap_initialize(&ld
, uri
);
810 log_error ("Cannot init ldap session to %s:%d", ldap_server
, ldap_port
);
816 version
= LDAP_VERSION3
;
817 if ((ret
= ldap_set_option (ld
, LDAP_OPT_PROTOCOL_VERSION
, &version
)) != LDAP_OPT_SUCCESS
)
819 log_error ("Cannot set LDAP version to %d: %s", version
,
820 ldap_err2string (ret
));
823 if (ldap_referrals
!= -1)
825 if ((ret
= ldap_set_option (ld
, LDAP_OPT_REFERRALS
, ldap_referrals
?
826 LDAP_OPT_ON
: LDAP_OPT_OFF
)) != LDAP_OPT_SUCCESS
)
828 log_error ("Cannot %s LDAP referrals option: %s",
829 (ldap_referrals
? "enable" : "disable"),
830 ldap_err2string (ret
));
834 if ((ret
= ldap_set_rebind_proc(ld
, ldap_rebind_cb
, NULL
)) != LDAP_SUCCESS
)
836 log_error ("Warning: Cannot set ldap rebind procedure: %s",
837 ldap_err2string (ret
));
840 #if defined (LDAP_USE_SSL)
841 if (ldap_use_ssl
== LDAP_SSL_LDAPS
||
842 (ldap_use_ssl
== LDAP_SSL_ON
&& ldap_port
== LDAPS_PORT
))
844 int opt
= LDAP_OPT_X_TLS_HARD
;
845 if ((ret
= ldap_set_option (ld
, LDAP_OPT_X_TLS
, &opt
)) != LDAP_SUCCESS
)
847 log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
848 ldap_server
, ldap_port
, ldap_err2string (ret
));
854 log_info ("LDAPS session successfully enabled to %s:%d",
855 ldap_server
, ldap_port
);
858 else if (ldap_use_ssl
!= LDAP_SSL_OFF
)
860 if ((ret
= ldap_start_tls_s (ld
, NULL
, NULL
)) != LDAP_SUCCESS
)
862 log_error ("Error: Cannot start TLS session to %s:%d: %s",
863 ldap_server
, ldap_port
, ldap_err2string (ret
));
869 log_info ("TLS session successfully started to %s:%d",
870 ldap_server
, ldap_port
);
875 if (ldap_username
!= NULL
&& *ldap_username
!= '\0')
877 creds
.bv_val
= strdup(ldap_password
);
878 creds
.bv_len
= strlen(ldap_password
);
880 if ((ret
= ldap_sasl_bind_s (ld
, ldap_username
, LDAP_SASL_SIMPLE
,
881 &creds
, NULL
, NULL
, NULL
)) != LDAP_SUCCESS
)
883 log_error ("Error: Cannot login into ldap server %s:%d: %s",
884 ldap_server
, ldap_port
, ldap_err2string (ret
));
890 #if defined (DEBUG_LDAP)
891 log_info ("Successfully logged into LDAP server %s", ldap_server
);
897 parse_external_dns (LDAPMessage
* ent
)
899 char *search
[] = {"dhcpOptionsDN", "dhcpSharedNetworkDN", "dhcpSubnetDN",
900 "dhcpGroupDN", "dhcpHostDN", "dhcpClassesDN",
902 LDAPMessage
* newres
, * newent
;
903 struct berval
**tempbv
;
905 #if defined (DEBUG_LDAP)
908 dn
= ldap_get_dn (ld
, ent
);
911 log_info ("Parsing external DNs for '%s'", dn
);
921 for (i
=0; search
[i
] != NULL
; i
++)
923 if ((tempbv
= ldap_get_values_len (ld
, ent
, search
[i
])) == NULL
)
926 for (j
=0; tempbv
[j
] != NULL
; j
++)
928 if (*tempbv
[j
]->bv_val
== '\0')
931 if ((ret
= ldap_search_ext_s(ld
, tempbv
[j
]->bv_val
, LDAP_SCOPE_BASE
,
932 "objectClass=*", NULL
, 0, NULL
,
933 NULL
, NULL
, 0, &newres
)) != LDAP_SUCCESS
)
935 ldap_value_free_len (tempbv
);
940 #if defined (DEBUG_LDAP)
941 log_info ("Adding contents of subtree '%s' to config stack from '%s' reference", tempbv
[j
], search
[i
]);
943 for (newent
= ldap_first_entry (ld
, newres
);
945 newent
= ldap_next_entry (ld
, newent
))
947 #if defined (DEBUG_LDAP)
948 dn
= ldap_get_dn (ld
, newent
);
951 log_info ("Adding LDAP result set starting with '%s' to config stack", dn
);
956 add_to_config_stack (newres
, newent
);
957 /* don't free newres here */
961 ldap_value_free_len (tempbv
);
967 free_stack_entry (struct ldap_config_stack
*item
)
969 struct ldap_config_stack
*look_ahead_pointer
= item
;
970 int may_free_msg
= 1;
972 while (look_ahead_pointer
->next
!= NULL
)
974 look_ahead_pointer
= look_ahead_pointer
->next
;
975 if (look_ahead_pointer
->res
== item
->res
)
983 ldap_msgfree (item
->res
);
990 next_ldap_entry (struct parse
*cfile
)
992 struct ldap_config_stack
*temp_stack
;
994 if (ldap_stack
!= NULL
&& ldap_stack
->close_brace
)
996 x_strncat (cfile
->inbuf
, "}\n", LDAP_BUFFER_SIZE
);
997 ldap_stack
->close_brace
= 0;
1000 while (ldap_stack
!= NULL
&&
1001 (ldap_stack
->ldent
== NULL
||
1002 (ldap_stack
->ldent
= ldap_next_entry (ld
, ldap_stack
->ldent
)) == NULL
))
1004 if (ldap_stack
->close_brace
)
1006 x_strncat (cfile
->inbuf
, "}\n", LDAP_BUFFER_SIZE
);
1007 ldap_stack
->close_brace
= 0;
1010 temp_stack
= ldap_stack
;
1011 ldap_stack
= ldap_stack
->next
;
1012 free_stack_entry (temp_stack
);
1015 if (ldap_stack
!= NULL
&& ldap_stack
->close_brace
)
1017 x_strncat (cfile
->inbuf
, "}\n", LDAP_BUFFER_SIZE
);
1018 ldap_stack
->close_brace
= 0;
1024 check_statement_end (const char *statement
)
1028 if (statement
== NULL
|| *statement
== '\0')
1032 ** check if it ends with "}", e.g.:
1033 ** "zone my.domain. { ... }"
1034 ** optionally followed by spaces
1036 ptr
= strrchr (statement
, '}');
1039 /* skip following white-spaces */
1040 for (++ptr
; isspace ((int)*ptr
); ptr
++);
1042 /* check if we reached the end */
1044 return ('}'); /* yes, block end */
1050 ** this should not happen, but...
1051 ** check if it ends with ";", e.g.:
1053 ** optionally followed by spaces
1055 ptr
= strrchr (statement
, ';');
1058 /* skip following white-spaces */
1059 for (++ptr
; isspace ((int)*ptr
); ptr
++);
1061 /* check if we reached the end */
1063 return (';'); /* ends with a ; */
1073 ldap_parse_entry_options (LDAPMessage
*ent
, char *buffer
, size_t size
,
1076 struct berval
**tempbv
;
1079 if (ent
== NULL
|| buffer
== NULL
|| size
== 0)
1080 return (ISC_R_FAILURE
);
1082 if ((tempbv
= ldap_get_values_len (ld
, ent
, "dhcpStatements")) != NULL
)
1084 for (i
=0; tempbv
[i
] != NULL
; i
++)
1086 if (lease_limit
!= NULL
&&
1087 strncasecmp ("lease limit ", tempbv
[i
]->bv_val
, 12) == 0)
1089 *lease_limit
= (int) strtol ((tempbv
[i
]->bv_val
) + 12, NULL
, 10);
1093 x_strncat (buffer
, tempbv
[i
]->bv_val
, size
);
1095 switch((int) check_statement_end (tempbv
[i
]->bv_val
))
1099 x_strncat (buffer
, "\n", size
);
1102 x_strncat (buffer
, ";\n", size
);
1106 ldap_value_free_len (tempbv
);
1109 if ((tempbv
= ldap_get_values_len (ld
, ent
, "dhcpOption")) != NULL
)
1111 for (i
=0; tempbv
[i
] != NULL
; i
++)
1113 x_strncat (buffer
, "option ", size
);
1114 x_strncat (buffer
, tempbv
[i
]->bv_val
, size
);
1115 switch ((int) check_statement_end (tempbv
[i
]->bv_val
))
1118 x_strncat (buffer
, "\n", size
);
1121 x_strncat (buffer
, ";\n", size
);
1125 ldap_value_free_len (tempbv
);
1128 return (ISC_R_SUCCESS
);
1133 ldap_generate_config_string (struct parse
*cfile
)
1135 struct berval
**objectClass
;
1137 struct ldap_config_stack
*entry
;
1138 LDAPMessage
* ent
, * res
;
1139 int i
, ignore
, found
;
1148 if ((objectClass
= ldap_get_values_len (ld
, entry
->ldent
,
1149 "objectClass")) == NULL
)
1154 for (i
=0; objectClass
[i
] != NULL
; i
++)
1156 if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpSharedNetwork") == 0)
1157 ldap_parse_shared_network (entry
, cfile
);
1158 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpClass") == 0)
1159 ldap_parse_class (entry
, cfile
);
1160 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpSubnet") == 0)
1161 ldap_parse_subnet (entry
, cfile
);
1162 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpPool") == 0)
1163 ldap_parse_pool (entry
, cfile
);
1164 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpGroup") == 0)
1165 ldap_parse_group (entry
, cfile
);
1166 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpTSigKey") == 0)
1167 ldap_parse_key (entry
, cfile
);
1168 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpDnsZone") == 0)
1169 ldap_parse_zone (entry
, cfile
);
1170 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpHost") == 0)
1172 if (ldap_method
== LDAP_METHOD_STATIC
)
1173 ldap_parse_host (entry
, cfile
);
1180 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpSubClass") == 0)
1182 if (ldap_method
== LDAP_METHOD_STATIC
)
1183 ldap_parse_subclass (entry
, cfile
);
1193 if (found
&& cfile
->inbuf
[0] == '\0')
1200 ldap_value_free_len (objectClass
);
1204 next_ldap_entry (cfile
);
1208 ldap_parse_entry_options(entry
->ldent
, cfile
->inbuf
,
1209 LDAP_BUFFER_SIZE
-1, NULL
);
1211 dn
= ldap_get_dn (ld
, entry
->ldent
);
1213 #if defined(DEBUG_LDAP)
1215 log_info ("Found LDAP entry '%s'", dn
);
1219 (ret
= ldap_search_ext_s (ld
, dn
, LDAP_SCOPE_ONELEVEL
,
1220 "objectClass=*", NULL
, 0, NULL
, NULL
,
1221 NULL
, 0, &res
)) != LDAP_SUCCESS
)
1232 if ((ent
= ldap_first_entry (ld
, res
)) != NULL
)
1234 add_to_config_stack (res
, ent
);
1235 parse_external_dns (entry
->ldent
);
1240 parse_external_dns (entry
->ldent
);
1241 next_ldap_entry (cfile
);
1247 ldap_close_debug_fd()
1249 if (ldap_debug_fd
!= -1)
1251 close (ldap_debug_fd
);
1258 ldap_write_debug (const void *buff
, size_t size
)
1260 if (ldap_debug_fd
!= -1)
1262 if (write (ldap_debug_fd
, buff
, size
) < 0)
1264 log_error ("Error writing to LDAP debug file %s: %s."
1265 " Disabling log file.", ldap_debug_file
,
1267 ldap_close_debug_fd();
1273 ldap_read_function (struct parse
*cfile
)
1275 cfile
->inbuf
[0] = '\0';
1278 while (ldap_stack
!= NULL
&& *cfile
->inbuf
== '\0')
1279 ldap_generate_config_string (cfile
);
1281 if (ldap_stack
== NULL
&& *cfile
->inbuf
== '\0')
1285 cfile
->buflen
= strlen (cfile
->inbuf
) - 1;
1286 if (cfile
->buflen
> 0)
1287 ldap_write_debug (cfile
->inbuf
, cfile
->buflen
);
1289 #if defined (DEBUG_LDAP)
1290 log_info ("Sending config line '%s'", cfile
->inbuf
);
1293 return (cfile
->inbuf
[0]);
1298 ldap_get_host_name (LDAPMessage
* ent
)
1300 struct berval
**name
;
1304 if ((name
= ldap_get_values_len (ld
, ent
, "cn")) == NULL
|| name
[0] == NULL
)
1307 ldap_value_free_len (name
);
1309 #if defined (DEBUG_LDAP)
1310 ret
= ldap_get_dn (ld
, ent
);
1313 log_info ("Cannot get cn attribute for LDAP entry %s", ret
);
1320 ret
= dmalloc (strlen (name
[0]->bv_val
) + 1, MDL
);
1321 strcpy (ret
, name
[0]->bv_val
);
1322 ldap_value_free_len (name
);
1329 getfqhostname(char *fqhost
, size_t size
)
1331 #if defined(MAXHOSTNAMELEN)
1332 char hname
[MAXHOSTNAMELEN
];
1338 if(NULL
== fqhost
|| 1 >= size
)
1341 memset(hname
, 0, sizeof(hname
));
1342 if( gethostname(hname
, sizeof(hname
)-1))
1345 if(NULL
== (hp
= gethostbyname(hname
)))
1348 strncpy(fqhost
, hp
->h_name
, size
-1);
1349 fqhost
[size
-1] = '\0';
1355 ldap_read_config (void)
1357 LDAPMessage
* ldres
, * hostres
, * ent
, * hostent
;
1358 char hfilter
[1024], sfilter
[1024], fqdn
[257];
1359 char *buffer
, *hostdn
;
1360 ldap_dn_node
*curr
= NULL
;
1361 struct parse
*cfile
;
1362 struct utsname unme
;
1366 struct berval
**tempbv
= NULL
;
1371 return (ldap_server
== NULL
? ISC_R_SUCCESS
: ISC_R_FAILURE
);
1373 buffer
= dmalloc (LDAP_BUFFER_SIZE
+1, MDL
);
1375 return (ISC_R_FAILURE
);
1377 cfile
= (struct parse
*) NULL
;
1378 res
= new_parse (&cfile
, -1, buffer
, LDAP_BUFFER_SIZE
, "LDAP", 0);
1379 if (res
!= ISC_R_SUCCESS
)
1383 if (ldap_dhcp_server_cn
!= NULL
)
1385 snprintf (hfilter
, sizeof (hfilter
),
1386 "(&(objectClass=dhcpServer)(cn=%s))", ldap_dhcp_server_cn
);
1390 if(0 == getfqhostname(fqdn
, sizeof(fqdn
)))
1392 snprintf (hfilter
, sizeof (hfilter
),
1393 "(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))",
1394 unme
.nodename
, fqdn
);
1398 snprintf (hfilter
, sizeof (hfilter
),
1399 "(&(objectClass=dhcpServer)(cn=%s))", unme
.nodename
);
1404 if ((ret
= ldap_search_ext_s (ld
, ldap_base_dn
, LDAP_SCOPE_SUBTREE
,
1405 hfilter
, NULL
, 0, NULL
, NULL
, NULL
, 0,
1406 &hostres
)) != LDAP_SUCCESS
)
1408 log_error ("Cannot find host LDAP entry %s %s",
1409 ((ldap_dhcp_server_cn
== NULL
)?(unme
.nodename
):(ldap_dhcp_server_cn
)), hfilter
);
1411 ldap_msgfree (hostres
);
1413 return (ISC_R_FAILURE
);
1416 if ((hostent
= ldap_first_entry (ld
, hostres
)) == NULL
)
1418 log_error ("Error: Cannot find LDAP entry matching %s", hfilter
);
1419 ldap_msgfree (hostres
);
1421 return (ISC_R_FAILURE
);
1424 hostdn
= ldap_get_dn (ld
, hostent
);
1425 #if defined(DEBUG_LDAP)
1427 log_info ("Found dhcpServer LDAP entry '%s'", hostdn
);
1430 if (hostdn
== NULL
||
1431 (tempbv
= ldap_get_values_len (ld
, hostent
, "dhcpServiceDN")) == NULL
||
1434 log_error ("Error: Cannot find LDAP entry matching %s", hfilter
);
1437 ldap_value_free_len (tempbv
);
1440 ldap_memfree (hostdn
);
1441 ldap_msgfree (hostres
);
1443 return (ISC_R_FAILURE
);
1446 #if defined(DEBUG_LDAP)
1447 log_info ("LDAP: Parsing dhcpServer options '%s' ...", hostdn
);
1450 cfile
->inbuf
[0] = '\0';
1451 ldap_parse_entry_options(hostent
, cfile
->inbuf
, LDAP_BUFFER_SIZE
, NULL
);
1452 cfile
->buflen
= strlen (cfile
->inbuf
);
1453 if(cfile
->buflen
> 0)
1455 ldap_write_debug (cfile
->inbuf
, cfile
->buflen
);
1457 res
= conf_file_subparse (cfile
, root_group
, ROOT_GROUP
);
1458 if (res
!= ISC_R_SUCCESS
)
1460 log_error ("LDAP: cannot parse dhcpServer entry '%s'", hostdn
);
1461 ldap_memfree (hostdn
);
1465 cfile
->inbuf
[0] = '\0';
1467 ldap_msgfree (hostres
);
1470 ** attach ldap (tree) read function now
1472 cfile
->bufix
= cfile
->buflen
= 0;
1473 cfile
->read_function
= ldap_read_function
;
1475 res
= ISC_R_SUCCESS
;
1476 for (cnt
=0; tempbv
[cnt
] != NULL
; cnt
++)
1478 snprintf(sfilter
, sizeof(sfilter
), "(&(objectClass=dhcpService)"
1479 "(|(dhcpPrimaryDN=%s)(dhcpSecondaryDN=%s)))",
1482 if ((ret
= ldap_search_ext_s (ld
, tempbv
[cnt
]->bv_val
, LDAP_SCOPE_BASE
,
1483 sfilter
, NULL
, 0, NULL
, NULL
, NULL
,
1484 0, &ldres
)) != LDAP_SUCCESS
)
1486 log_error ("Error searching for dhcpServiceDN '%s': %s. Please update the LDAP entry '%s'",
1487 tempbv
[cnt
]->bv_val
, ldap_err2string (ret
), hostdn
);
1489 ldap_msgfree(ldres
);
1490 res
= ISC_R_FAILURE
;
1494 if ((ent
= ldap_first_entry (ld
, ldres
)) == NULL
)
1496 log_error ("Error: Cannot find dhcpService DN '%s' with primary or secondary server reference. Please update the LDAP server entry '%s'",
1497 tempbv
[cnt
]->bv_val
, hostdn
);
1499 ldap_msgfree(ldres
);
1500 res
= ISC_R_FAILURE
;
1505 ** FIXME: how to free the remembered dn's on exit?
1506 ** This should be OK if dmalloc registers the
1507 ** memory it allocated and frees it on exit..
1510 curr
= dmalloc (sizeof (*curr
), MDL
);
1513 length
= strlen (tempbv
[cnt
]->bv_val
);
1514 curr
->dn
= dmalloc (length
+ 1, MDL
);
1515 if (curr
->dn
== NULL
)
1521 strcpy (curr
->dn
, tempbv
[cnt
]->bv_val
);
1528 /* append to service-dn list */
1529 if (ldap_service_dn_tail
!= NULL
)
1530 ldap_service_dn_tail
->next
= curr
;
1532 ldap_service_dn_head
= curr
;
1534 ldap_service_dn_tail
= curr
;
1537 log_fatal ("no memory to remember ldap service dn");
1539 #if defined (DEBUG_LDAP)
1540 log_info ("LDAP: Parsing dhcpService DN '%s' ...", tempbv
[cnt
]);
1542 add_to_config_stack (ldres
, ent
);
1543 res
= conf_file_subparse (cfile
, root_group
, ROOT_GROUP
);
1544 if (res
!= ISC_R_SUCCESS
)
1546 log_error ("LDAP: cannot parse dhcpService entry '%s'", tempbv
[cnt
]->bv_val
);
1552 ldap_close_debug_fd();
1554 ldap_memfree (hostdn
);
1555 ldap_value_free_len (tempbv
);
1557 if (res
!= ISC_R_SUCCESS
)
1559 struct ldap_config_stack
*temp_stack
;
1561 while ((curr
= ldap_service_dn_head
) != NULL
)
1563 ldap_service_dn_head
= curr
->next
;
1564 dfree (curr
->dn
, MDL
);
1568 ldap_service_dn_tail
= NULL
;
1570 while ((temp_stack
= ldap_stack
) != NULL
)
1572 ldap_stack
= temp_stack
->next
;
1573 free_stack_entry (temp_stack
);
1579 /* Unbind from ldap immediately after reading config in static mode. */
1580 if (ldap_method
== LDAP_METHOD_STATIC
)
1587 /* This function will parse the dhcpOption and dhcpStatements field in the LDAP
1588 entry if it exists. Right now, type will be either HOST_DECL or CLASS_DECL.
1589 If we are parsing a HOST_DECL, this always returns 0. If we are parsing a
1590 CLASS_DECL, this will return what the current lease limit is in LDAP. If
1591 there is no lease limit specified, we return 0 */
1594 ldap_parse_options (LDAPMessage
* ent
, struct group
*group
,
1595 int type
, struct host_decl
*host
,
1596 struct class **class)
1598 int declaration
, lease_limit
;
1599 char option_buffer
[8192];
1600 enum dhcp_token token
;
1601 struct parse
*cfile
;
1606 *option_buffer
= '\0';
1608 /* This block of code will try to find the parent of the host, and
1609 if it is a group object, fetch the options and apply to the host. */
1610 if (type
== HOST_DECL
)
1612 char *hostdn
, *basedn
, *temp1
, *temp2
, filter
[1024];
1613 LDAPMessage
*groupdn
, *entry
;
1616 hostdn
= ldap_get_dn (ld
, ent
);
1621 temp1
= strchr (hostdn
, '=');
1623 temp1
= strchr (++temp1
, '=');
1625 temp2
= strchr (++temp1
, ',');
1631 snprintf (filter
, sizeof(filter
),
1632 "(&(cn=%.*s)(objectClass=dhcpGroup))",
1633 (int)(temp2
- temp1
), temp1
);
1635 basedn
= strchr (temp1
, ',');
1640 if (basedn
!= NULL
&& *basedn
!= '\0')
1642 ret
= ldap_search_ext_s (ld
, basedn
, LDAP_SCOPE_SUBTREE
, filter
,
1643 NULL
, 0, NULL
, NULL
, NULL
, 0, &groupdn
);
1644 if (ret
== LDAP_SUCCESS
)
1646 if ((entry
= ldap_first_entry (ld
, groupdn
)) != NULL
)
1648 res
= ldap_parse_entry_options (entry
, option_buffer
,
1649 sizeof(option_buffer
) - 1,
1651 if (res
!= ISC_R_SUCCESS
)
1653 /* reset option buffer discarding any results */
1654 *option_buffer
= '\0';
1658 ldap_msgfree( groupdn
);
1661 ldap_memfree( hostdn
);
1665 res
= ldap_parse_entry_options (ent
, option_buffer
, sizeof(option_buffer
) - 1,
1667 if (res
!= ISC_R_SUCCESS
)
1668 return (lease_limit
);
1670 option_buffer
[sizeof(option_buffer
) - 1] = '\0';
1671 if (*option_buffer
== '\0')
1672 return (lease_limit
);
1674 cfile
= (struct parse
*) NULL
;
1675 res
= new_parse (&cfile
, -1, option_buffer
, strlen (option_buffer
),
1676 type
== HOST_DECL
? "LDAP-HOST" : "LDAP-SUBCLASS", 0);
1677 if (res
!= ISC_R_SUCCESS
)
1678 return (lease_limit
);
1680 #if defined (DEBUG_LDAP)
1681 log_info ("Sending the following options: '%s'", option_buffer
);
1687 token
= peek_token (&val
, NULL
, cfile
);
1688 if (token
== END_OF_FILE
)
1690 declaration
= parse_statement (cfile
, group
, type
, host
, declaration
);
1695 return (lease_limit
);
1701 find_haddr_in_ldap (struct host_decl
**hp
, int htype
, unsigned hlen
,
1702 const unsigned char *haddr
, const char *file
, int line
)
1704 char buf
[128], *type_str
;
1705 LDAPMessage
* res
, *ent
;
1706 struct host_decl
* host
;
1707 isc_result_t status
;
1711 if (ldap_method
== LDAP_METHOD_STATIC
)
1722 type_str
= "ethernet";
1725 type_str
= "token-ring";
1731 log_info ("Ignoring unknown type %d", htype
);
1736 ** FIXME: It is not guaranteed, that the dhcpHWAddress attribute
1737 ** contains _exactly_ "type addr" with one space between!
1739 snprintf (buf
, sizeof (buf
),
1740 "(&(objectClass=dhcpHost)(dhcpHWAddress=%s %s))",
1741 type_str
, print_hw_addr (htype
, hlen
, haddr
));
1744 for (curr
= ldap_service_dn_head
;
1745 curr
!= NULL
&& *curr
->dn
!= '\0';
1748 #if defined (DEBUG_LDAP)
1749 log_info ("Searching for %s in LDAP tree %s", buf
, curr
->dn
);
1751 ret
= ldap_search_ext_s (ld
, curr
->dn
, LDAP_SCOPE_SUBTREE
, buf
, NULL
, 0,
1752 NULL
, NULL
, NULL
, 0, &res
);
1754 if(ret
== LDAP_SERVER_DOWN
)
1756 log_info ("LDAP server was down, trying to reconnect...");
1762 log_info ("LDAP reconnect failed - try again later...");
1766 ret
= ldap_search_ext_s (ld
, curr
->dn
, LDAP_SCOPE_SUBTREE
, buf
, NULL
,
1767 0, NULL
, NULL
, NULL
, 0, &res
);
1770 if (ret
== LDAP_SUCCESS
)
1772 if( (ent
= ldap_first_entry (ld
, res
)) != NULL
)
1773 break; /* search OK and have entry */
1775 #if defined (DEBUG_LDAP)
1776 log_info ("No host entry for %s in LDAP tree %s",
1793 if (ret
!= LDAP_NO_SUCH_OBJECT
&& ret
!= LDAP_SUCCESS
)
1795 log_error ("Cannot search for %s in LDAP tree %s: %s", buf
,
1796 curr
->dn
, ldap_err2string (ret
));
1800 #if defined (DEBUG_LDAP)
1803 log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
1804 ldap_err2string (ret
), buf
, curr
->dn
);
1812 #if defined (DEBUG_LDAP)
1813 char *dn
= ldap_get_dn (ld
, ent
);
1816 log_info ("Found dhcpHWAddress LDAP entry %s", dn
);
1821 host
= (struct host_decl
*)0;
1822 status
= host_allocate (&host
, MDL
);
1823 if (status
!= ISC_R_SUCCESS
)
1825 log_fatal ("can't allocate host decl struct: %s",
1826 isc_result_totext (status
));
1831 host
->name
= ldap_get_host_name (ent
);
1832 if (host
->name
== NULL
)
1834 host_dereference (&host
, MDL
);
1839 if (!clone_group (&host
->group
, root_group
, MDL
))
1841 log_fatal ("can't clone group for host %s", host
->name
);
1842 host_dereference (&host
, MDL
);
1847 ldap_parse_options (ent
, host
->group
, HOST_DECL
, host
, NULL
);
1855 if(res
) ldap_msgfree (res
);
1861 find_subclass_in_ldap (struct class *class, struct class **newclass
,
1862 struct data_string
*data
)
1864 LDAPMessage
* res
, * ent
;
1865 int ret
, lease_limit
;
1866 isc_result_t status
;
1870 if (ldap_method
== LDAP_METHOD_STATIC
)
1878 snprintf (buf
, sizeof (buf
),
1879 "(&(objectClass=dhcpSubClass)(cn=%s)(dhcpClassData=%s))",
1880 print_hex_1 (data
->len
, data
->data
, 60),
1881 print_hex_2 (strlen (class->name
), (u_int8_t
*) class->name
, 60));
1882 #if defined (DEBUG_LDAP)
1883 log_info ("Searching LDAP for %s", buf
);
1887 for (curr
= ldap_service_dn_head
;
1888 curr
!= NULL
&& *curr
->dn
!= '\0';
1891 #if defined (DEBUG_LDAP)
1892 log_info ("Searching for %s in LDAP tree %s", buf
, curr
->dn
);
1894 ret
= ldap_search_ext_s (ld
, curr
->dn
, LDAP_SCOPE_SUBTREE
, buf
, NULL
, 0,
1895 NULL
, NULL
, NULL
, 0, &res
);
1897 if(ret
== LDAP_SERVER_DOWN
)
1899 log_info ("LDAP server was down, trying to reconnect...");
1906 log_info ("LDAP reconnect failed - try again later...");
1910 ret
= ldap_search_ext_s (ld
, curr
->dn
, LDAP_SCOPE_SUBTREE
, buf
,
1911 NULL
, 0, NULL
, NULL
, NULL
, 0, &res
);
1914 if (ret
== LDAP_SUCCESS
)
1916 if( (ent
= ldap_first_entry (ld
, res
)) != NULL
)
1917 break; /* search OK and have entry */
1919 #if defined (DEBUG_LDAP)
1920 log_info ("No subclass entry for %s in LDAP tree %s",
1937 if (ret
!= LDAP_NO_SUCH_OBJECT
&& ret
!= LDAP_SUCCESS
)
1939 log_error ("Cannot search for %s in LDAP tree %s: %s", buf
,
1940 curr
->dn
, ldap_err2string (ret
));
1944 #if defined (DEBUG_LDAP)
1947 log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
1948 ldap_err2string (ret
), buf
, curr
->dn
);
1956 #if defined (DEBUG_LDAP)
1957 char *dn
= ldap_get_dn (ld
, ent
);
1960 log_info ("Found subclass LDAP entry %s", dn
);
1965 status
= class_allocate (newclass
, MDL
);
1966 if (status
!= ISC_R_SUCCESS
)
1968 log_error ("Cannot allocate memory for a new class");
1973 group_reference (&(*newclass
)->group
, class->group
, MDL
);
1974 class_reference (&(*newclass
)->superclass
, class, MDL
);
1975 lease_limit
= ldap_parse_options (ent
, (*newclass
)->group
,
1976 CLASS_DECL
, NULL
, newclass
);
1977 if (lease_limit
== 0)
1978 (*newclass
)->lease_limit
= class->lease_limit
;
1980 class->lease_limit
= lease_limit
;
1982 if ((*newclass
)->lease_limit
)
1984 (*newclass
)->billed_leases
=
1985 dmalloc ((*newclass
)->lease_limit
* sizeof (struct lease
*), MDL
);
1986 if (!(*newclass
)->billed_leases
)
1988 log_error ("no memory for billing");
1989 class_dereference (newclass
, MDL
);
1993 memset ((*newclass
)->billed_leases
, 0,
1994 ((*newclass
)->lease_limit
* sizeof (struct lease
*)));
1997 data_string_copy (&(*newclass
)->hash_string
, data
, MDL
);
2003 if(res
) ldap_msgfree (res
);