3 Routines for reading the configuration from LDAP */
6 * Copyright (c) 2010-2017 by Internet Systems Consortium, Inc. ("ISC")
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).
42 #if defined(LDAP_CONFIGURATION)
48 #if defined(HAVE_IFADDRS_H)
53 #if defined(LDAP_CASA_AUTH)
54 #include "ldap_casa.h"
57 #if defined(LDAP_USE_GSSAPI)
58 #include <sasl/sasl.h>
59 #include "ldap_krb_helper.h"
62 static LDAP
* ld
= NULL
;
63 static char *ldap_server
= NULL
,
64 *ldap_username
= NULL
,
65 *ldap_password
= NULL
,
67 *ldap_dhcp_server_cn
= NULL
,
68 *ldap_debug_file
= NULL
;
69 static int ldap_port
= LDAP_PORT
,
70 ldap_method
= LDAP_METHOD_DYNAMIC
,
73 ldap_enable_retry
= -1,
75 #if defined (LDAP_USE_SSL)
76 static int ldap_use_ssl
= -1, /* try TLS if possible */
77 ldap_tls_reqcert
= -1,
78 ldap_tls_crlcheck
= -1;
79 static char *ldap_tls_ca_file
= NULL
,
80 *ldap_tls_ca_dir
= NULL
,
81 *ldap_tls_cert
= NULL
,
83 *ldap_tls_ciphers
= NULL
,
84 *ldap_tls_randfile
= NULL
;
87 #if defined (LDAP_USE_GSSAPI)
88 static char *ldap_gssapi_keytab
= NULL
,
89 *ldap_gssapi_principal
= NULL
;
91 struct ldap_sasl_instance
{
99 static struct ldap_sasl_instance
*ldap_sasl_inst
= NULL
;
102 _ldap_sasl_interact(LDAP
*ld
, unsigned flags
, void *defaults
, void *sin
) ;
105 static struct ldap_config_stack
*ldap_stack
= NULL
;
107 typedef struct ldap_dn_node
{
108 struct ldap_dn_node
*next
;
113 static ldap_dn_node
*ldap_service_dn_head
= NULL
;
114 static ldap_dn_node
*ldap_service_dn_tail
= NULL
;
116 static int ldap_read_function (struct parse
*cfile
);
118 static struct parse
*
119 x_parser_init(const char *name
)
125 inbuf
= dmalloc (LDAP_BUFFER_SIZE
, MDL
);
129 cfile
= (struct parse
*) NULL
;
130 res
= new_parse (&cfile
, -1, inbuf
, LDAP_BUFFER_SIZE
, name
, 0);
131 if (res
!= ISC_R_SUCCESS
)
136 /* the buffer is still empty */
137 cfile
->bufsiz
= LDAP_BUFFER_SIZE
;
138 cfile
->buflen
= cfile
->bufix
= 0;
139 /* attach ldap read function */
140 cfile
->read_function
= ldap_read_function
;
145 x_parser_free(struct parse
**cfile
)
150 dfree((*cfile
)->inbuf
, MDL
);
151 (*cfile
)->inbuf
= NULL
;
152 (*cfile
)->bufsiz
= 0;
153 return end_parse(cfile
);
155 return ISC_R_SUCCESS
;
159 x_parser_resize(struct parse
*cfile
, size_t len
)
164 /* grow by len rounded up at LDAP_BUFFER_SIZE */
165 size
= cfile
->bufsiz
+ (len
| (LDAP_BUFFER_SIZE
-1)) + 1;
167 /* realloc would be better, but there isn't any */
168 if ((temp
= dmalloc (size
, MDL
)) != NULL
)
170 #if defined (DEBUG_LDAP)
171 log_info ("Reallocated %s buffer from %zu to %zu",
172 cfile
->tlname
, cfile
->bufsiz
, size
);
174 memcpy(temp
, cfile
->inbuf
, cfile
->bufsiz
);
175 dfree(cfile
->inbuf
, MDL
);
177 cfile
->bufsiz
= size
;
182 * Hmm... what is worser, consider it as fatal error and
183 * bail out completely or discard config data in hope it
184 * is "only" an option in dynamic host lookup?
186 log_error("Unable to reallocated %s buffer from %zu to %zu",
187 cfile
->tlname
, cfile
->bufsiz
, size
);
192 x_parser_strcat(struct parse
*cfile
, const char *str
)
194 size_t cur
= strlen(cfile
->inbuf
);
195 size_t len
= strlen(str
);
198 if (cur
+ len
>= cfile
->bufsiz
&& !x_parser_resize(cfile
, len
))
201 cnt
= cfile
->bufsiz
> cur
? cfile
->bufsiz
- cur
- 1 : 0;
202 return strncat(cfile
->inbuf
, str
, cnt
);
206 x_parser_reset(struct parse
*cfile
)
208 cfile
->inbuf
[0] = '\0';
209 cfile
->bufix
= cfile
->buflen
= 0;
213 x_parser_length(struct parse
*cfile
)
215 cfile
->buflen
= strlen(cfile
->inbuf
);
216 return cfile
->buflen
;
220 x_strxform(char *dst
, const char *src
, size_t dst_size
,
223 if(dst
&& src
&& dst_size
)
228 for(pos
=0; pos
< len
&& pos
+ 1 < dst_size
; pos
++)
229 dst
[pos
] = xform((int)src
[pos
]);
238 get_host_entry(char *fqdnname
, size_t fqdnname_size
,
239 char *hostaddr
, size_t hostaddr_size
)
241 #if defined(MAXHOSTNAMELEN)
242 char hname
[MAXHOSTNAMELEN
+1];
248 if (NULL
== fqdnname
|| 1 >= fqdnname_size
)
251 memset(hname
, 0, sizeof(hname
));
252 if (gethostname(hname
, sizeof(hname
)-1))
255 if (NULL
== (hp
= gethostbyname(hname
)))
258 strncpy(fqdnname
, hp
->h_name
, fqdnname_size
-1);
259 fqdnname
[fqdnname_size
-1] = '\0';
261 if (hostaddr
!= NULL
)
263 if (hp
->h_addr
!= NULL
)
265 struct in_addr
*aptr
= (struct in_addr
*)hp
->h_addr
;
266 #if defined(HAVE_INET_NTOP)
267 if (hostaddr_size
>= INET_ADDRSTRLEN
&&
268 inet_ntop(AF_INET
, aptr
, hostaddr
, hostaddr_size
) != NULL
)
273 char *astr
= inet_ntoa(*aptr
);
274 size_t alen
= strlen(astr
);
275 if (astr
&& alen
> 0 && hostaddr_size
> alen
)
277 strncpy(hostaddr
, astr
, hostaddr_size
-1);
278 hostaddr
[hostaddr_size
-1] = '\0';
288 #if defined(HAVE_IFADDRS_H)
290 is_iface_address(struct ifaddrs
*addrs
, struct in_addr
*addr
)
293 struct sockaddr_in
*sa
;
296 if(addrs
== NULL
|| addr
== NULL
)
299 for (ia
= addrs
; ia
!= NULL
; ia
= ia
->ifa_next
)
302 if (ia
->ifa_addr
&& (ia
->ifa_flags
& IFF_UP
) &&
303 ia
->ifa_addr
->sa_family
== AF_INET
)
305 sa
= (struct sockaddr_in
*)(ia
->ifa_addr
);
306 if (addr
->s_addr
== sa
->sin_addr
.s_addr
)
314 get_host_address(const char *hostname
, char *hostaddr
, size_t hostaddr_size
, struct ifaddrs
*addrs
)
316 if (hostname
&& *hostname
&& hostaddr
&& hostaddr_size
)
320 #if defined(HAVE_INET_PTON)
321 if (inet_pton(AF_INET
, hostname
, &addr
) == 1)
323 if (inet_aton(hostname
, &addr
) != 0)
326 /* it is already IP address string */
327 if(strlen(hostname
) < hostaddr_size
)
329 strncpy(hostaddr
, hostname
, hostaddr_size
-1);
330 hostaddr
[hostaddr_size
-1] = '\0';
332 if (addrs
!= NULL
&& is_iface_address (addrs
, &addr
) > 0)
341 if ((hp
= gethostbyname(hostname
)) != NULL
&& hp
->h_addr
!= NULL
)
343 struct in_addr
*aptr
= (struct in_addr
*)hp
->h_addr
;
349 for (h
=hp
->h_addr_list
; *h
; h
++)
351 struct in_addr
*haddr
= (struct in_addr
*)*h
;
352 if (is_iface_address (addrs
, haddr
) > 0)
360 #if defined(HAVE_INET_NTOP)
361 if (hostaddr_size
>= INET_ADDRSTRLEN
&&
362 inet_ntop(AF_INET
, aptr
, hostaddr
, hostaddr_size
) != NULL
)
367 char *astr
= inet_ntoa(*aptr
);
368 size_t alen
= strlen(astr
);
369 if (astr
&& alen
> 0 && alen
< hostaddr_size
)
371 strncpy(hostaddr
, astr
, hostaddr_size
-1);
372 hostaddr
[hostaddr_size
-1] = '\0';
381 #endif /* HAVE_IFADDRS_H */
384 ldap_parse_class (struct ldap_config_stack
*item
, struct parse
*cfile
)
386 struct berval
**tempbv
;
388 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) == NULL
||
392 ldap_value_free_len (tempbv
);
397 x_parser_strcat (cfile
, "class \"");
398 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
399 x_parser_strcat (cfile
, "\" {\n");
401 item
->close_brace
= 1;
402 ldap_value_free_len (tempbv
);
406 is_hex_string(const char *str
)
418 for (i
=0; str
[i
]; ++i
)
426 else if(isxdigit((unsigned char)str
[i
]))
435 return i
> 0 && !colon
;
439 ldap_parse_subclass (struct ldap_config_stack
*item
, struct parse
*cfile
)
441 struct berval
**tempbv
, **classdata
;
444 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) == NULL
||
448 ldap_value_free_len (tempbv
);
453 if ((classdata
= ldap_get_values_len (ld
, item
->ldent
,
454 "dhcpClassData")) == NULL
||
455 classdata
[0] == NULL
)
457 if (classdata
!= NULL
)
458 ldap_value_free_len (classdata
);
459 ldap_value_free_len (tempbv
);
464 x_parser_strcat (cfile
, "subclass \"");
465 x_parser_strcat (cfile
, classdata
[0]->bv_val
);
466 if (is_hex_string(tempbv
[0]->bv_val
))
468 x_parser_strcat (cfile
, "\" ");
469 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
470 x_parser_strcat (cfile
, " {\n");
474 tmp
= quotify_string(tempbv
[0]->bv_val
, MDL
);
475 x_parser_strcat (cfile
, "\" \"");
476 x_parser_strcat (cfile
, tmp
);
477 x_parser_strcat (cfile
, "\" {\n");
481 item
->close_brace
= 1;
482 ldap_value_free_len (tempbv
);
483 ldap_value_free_len (classdata
);
488 ldap_parse_host (struct ldap_config_stack
*item
, struct parse
*cfile
)
490 struct berval
**tempbv
, **hwaddr
;
492 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) == NULL
||
496 ldap_value_free_len (tempbv
);
501 hwaddr
= ldap_get_values_len (ld
, item
->ldent
, "dhcpHWAddress");
503 x_parser_strcat (cfile
, "host ");
504 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
505 x_parser_strcat (cfile
, " {\n");
509 if (hwaddr
[0] != NULL
)
511 x_parser_strcat (cfile
, "hardware ");
512 x_parser_strcat (cfile
, hwaddr
[0]->bv_val
);
513 x_parser_strcat (cfile
, ";\n");
515 ldap_value_free_len (hwaddr
);
518 item
->close_brace
= 1;
519 ldap_value_free_len (tempbv
);
524 ldap_parse_shared_network (struct ldap_config_stack
*item
, struct parse
*cfile
)
526 struct berval
**tempbv
;
528 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) == NULL
||
532 ldap_value_free_len (tempbv
);
537 x_parser_strcat (cfile
, "shared-network \"");
538 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
539 x_parser_strcat (cfile
, "\" {\n");
541 item
->close_brace
= 1;
542 ldap_value_free_len (tempbv
);
547 parse_netmask (int netmask
, char *netmaskbuf
)
553 for (i
=1; i
<= netmask
; i
++)
558 sprintf (netmaskbuf
, "%d.%d.%d.%d", (int) (nm
>> 24) & 0xff,
559 (int) (nm
>> 16) & 0xff,
560 (int) (nm
>> 8) & 0xff,
566 ldap_parse_subnet (struct ldap_config_stack
*item
, struct parse
*cfile
)
568 struct berval
**tempbv
, **netmaskstr
;
569 char netmaskbuf
[sizeof("255.255.255.255")];
572 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) == NULL
||
576 ldap_value_free_len (tempbv
);
581 if ((netmaskstr
= ldap_get_values_len (ld
, item
->ldent
,
582 "dhcpNetmask")) == NULL
||
583 netmaskstr
[0] == NULL
)
585 if (netmaskstr
!= NULL
)
586 ldap_value_free_len (netmaskstr
);
587 ldap_value_free_len (tempbv
);
592 x_parser_strcat (cfile
, "subnet ");
593 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
595 x_parser_strcat (cfile
, " netmask ");
596 parse_netmask (strtol (netmaskstr
[0]->bv_val
, NULL
, 10), netmaskbuf
);
597 x_parser_strcat (cfile
, netmaskbuf
);
599 x_parser_strcat (cfile
, " {\n");
601 ldap_value_free_len (tempbv
);
602 ldap_value_free_len (netmaskstr
);
604 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpRange")) != NULL
)
606 for (i
=0; tempbv
[i
] != NULL
; i
++)
608 x_parser_strcat (cfile
, "range");
609 x_parser_strcat (cfile
, " ");
610 x_parser_strcat (cfile
, tempbv
[i
]->bv_val
);
611 x_parser_strcat (cfile
, ";\n");
613 ldap_value_free_len (tempbv
);
616 item
->close_brace
= 1;
620 ldap_parse_subnet6 (struct ldap_config_stack
*item
, struct parse
*cfile
)
622 struct berval
**tempbv
;
625 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) == NULL
||
629 ldap_value_free_len (tempbv
);
634 x_parser_strcat (cfile
, "subnet6 ");
635 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
637 x_parser_strcat (cfile
, " {\n");
639 ldap_value_free_len (tempbv
);
641 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpRange6")) != NULL
)
643 for (i
=0; tempbv
[i
] != NULL
; i
++)
645 x_parser_strcat (cfile
, "range6");
646 x_parser_strcat (cfile
, " ");
647 x_parser_strcat (cfile
, tempbv
[i
]->bv_val
);
648 x_parser_strcat (cfile
, ";\n");
650 ldap_value_free_len (tempbv
);
653 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpPermitList")) != NULL
)
655 for (i
=0; tempbv
[i
] != NULL
; i
++)
657 x_parser_strcat (cfile
, tempbv
[i
]->bv_val
);
658 x_parser_strcat (cfile
, ";\n");
660 ldap_value_free_len (tempbv
);
663 item
->close_brace
= 1;
667 ldap_parse_pool (struct ldap_config_stack
*item
, struct parse
*cfile
)
669 struct berval
**tempbv
;
672 x_parser_strcat (cfile
, "pool {\n");
674 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpRange")) != NULL
)
676 x_parser_strcat (cfile
, "range");
677 for (i
=0; tempbv
[i
] != NULL
; i
++)
679 x_parser_strcat (cfile
, " ");
680 x_parser_strcat (cfile
, tempbv
[i
]->bv_val
);
682 x_parser_strcat (cfile
, ";\n");
683 ldap_value_free_len (tempbv
);
686 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpPermitList")) != NULL
)
688 for (i
=0; tempbv
[i
] != NULL
; i
++)
690 x_parser_strcat (cfile
, tempbv
[i
]->bv_val
);
691 x_parser_strcat (cfile
, ";\n");
693 ldap_value_free_len (tempbv
);
696 item
->close_brace
= 1;
700 ldap_parse_pool6 (struct ldap_config_stack
*item
, struct parse
*cfile
)
702 struct berval
**tempbv
;
705 x_parser_strcat (cfile
, "pool6 {\n");
707 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpRange6")) != NULL
)
709 x_parser_strcat (cfile
, "range6");
710 for (i
=0; tempbv
[i
] != NULL
; i
++)
712 x_parser_strcat (cfile
, " ");
713 x_parser_strcat (cfile
, tempbv
[i
]->bv_val
);
715 x_parser_strcat (cfile
, ";\n");
716 ldap_value_free_len (tempbv
);
719 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpPermitList")) != NULL
)
721 for (i
=0; tempbv
[i
] != NULL
; i
++)
723 x_parser_strcat(cfile
, tempbv
[i
]->bv_val
);
724 x_parser_strcat (cfile
, ";\n");
726 ldap_value_free_len (tempbv
);
729 item
->close_brace
= 1;
733 ldap_parse_group (struct ldap_config_stack
*item
, struct parse
*cfile
)
735 x_parser_strcat (cfile
, "group {\n");
736 item
->close_brace
= 1;
741 ldap_parse_key (struct ldap_config_stack
*item
, struct parse
*cfile
)
743 struct berval
**tempbv
;
745 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) != NULL
)
747 x_parser_strcat (cfile
, "key ");
748 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
749 x_parser_strcat (cfile
, " {\n");
750 ldap_value_free_len (tempbv
);
753 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpKeyAlgorithm")) != NULL
)
755 x_parser_strcat (cfile
, "algorithm ");
756 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
757 x_parser_strcat (cfile
, ";\n");
758 ldap_value_free_len (tempbv
);
761 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpKeySecret")) != NULL
)
763 x_parser_strcat (cfile
, "secret ");
764 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
765 x_parser_strcat (cfile
, ";\n");
766 ldap_value_free_len (tempbv
);
769 item
->close_brace
= 1;
774 ldap_parse_zone (struct ldap_config_stack
*item
, struct parse
*cfile
)
776 char *cnFindStart
, *cnFindEnd
;
777 struct berval
**tempbv
;
781 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "cn")) != NULL
)
783 x_parser_strcat (cfile
, "zone ");
784 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
785 x_parser_strcat (cfile
, " {\n");
786 ldap_value_free_len (tempbv
);
789 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpDnsZoneServer")) != NULL
)
791 x_parser_strcat (cfile
, "primary ");
792 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
794 x_parser_strcat (cfile
, ";\n");
795 ldap_value_free_len (tempbv
);
798 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpKeyDN")) != NULL
)
800 cnFindStart
= strchr(tempbv
[0]->bv_val
,'=');
801 if (cnFindStart
!= NULL
)
802 cnFindEnd
= strchr(++cnFindStart
,',');
806 if (cnFindEnd
!= NULL
&& cnFindEnd
> cnFindStart
)
808 len
= cnFindEnd
- cnFindStart
;
809 keyCn
= dmalloc (len
+ 1, MDL
);
819 strncpy (keyCn
, cnFindStart
, len
);
822 x_parser_strcat (cfile
, "key ");
823 x_parser_strcat (cfile
, keyCn
);
824 x_parser_strcat (cfile
, ";\n");
829 ldap_value_free_len (tempbv
);
832 item
->close_brace
= 1;
835 #if defined(HAVE_IFADDRS_H)
837 ldap_parse_failover (struct ldap_config_stack
*item
, struct parse
*cfile
)
839 struct berval
**tempbv
, **peername
;
840 struct ifaddrs
*addrs
= NULL
;
841 char srvaddr
[2][64] = {"\0", "\0"};
842 int primary
, split
= 0, match
;
844 if ((peername
= ldap_get_values_len (ld
, item
->ldent
, "cn")) == NULL
||
847 if (peername
!= NULL
)
848 ldap_value_free_len (peername
);
850 // ldap with disabled schema checks? fail to avoid syntax error.
851 log_error("Unable to find mandatory failover peering name attribute");
855 /* Get all interface addresses */
859 ** when dhcpFailOverPrimaryServer or dhcpFailOverSecondaryServer
860 ** matches one of our IP address, the following valiables are set:
861 ** - primary is 1 when we are primary or 0 when we are secondary
862 ** - srvaddr[0] contains ip address of the primary
863 ** - srvaddr[1] contains ip address of the secondary
866 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpFailOverPrimaryServer")) != NULL
&&
869 match
= get_host_address (tempbv
[0]->bv_val
, srvaddr
[0], sizeof(srvaddr
[0]), addrs
);
872 /* we are the primary */
878 log_info("Can't resolve address of the primary failover '%s' server %s",
879 peername
[0]->bv_val
, tempbv
[0]->bv_val
);
880 ldap_value_free_len (tempbv
);
881 ldap_value_free_len (peername
);
888 ldap_value_free_len (tempbv
);
890 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpFailOverSecondaryServer")) != NULL
&&
893 match
= get_host_address (tempbv
[0]->bv_val
, srvaddr
[1], sizeof(srvaddr
[1]), addrs
);
900 log_info("Both, primary and secondary failover '%s' server"
901 " attributes match our local address", peername
[0]->bv_val
);
902 ldap_value_free_len (tempbv
);
903 ldap_value_free_len (peername
);
909 /* we are the secondary */
915 log_info("Can't resolve address of the secondary failover '%s' server %s",
916 peername
[0]->bv_val
, tempbv
[0]->bv_val
);
917 ldap_value_free_len (tempbv
);
918 ldap_value_free_len (peername
);
925 ldap_value_free_len (tempbv
);
928 if (primary
== -1 || srvaddr
[0] == '\0' || srvaddr
[1] == '\0')
930 log_error("Could not decide if the server type is primary"
931 " or secondary for failover peering '%s'.", peername
[0]->bv_val
);
932 ldap_value_free_len (peername
);
938 x_parser_strcat (cfile
, "failover peer \"");
939 x_parser_strcat (cfile
, peername
[0]->bv_val
);
940 x_parser_strcat (cfile
, "\" {\n");
943 x_parser_strcat (cfile
, "primary;\n");
945 x_parser_strcat (cfile
, "secondary;\n");
947 x_parser_strcat (cfile
, "address ");
949 x_parser_strcat (cfile
, srvaddr
[0]);
951 x_parser_strcat (cfile
, srvaddr
[1]);
952 x_parser_strcat (cfile
, ";\n");
954 x_parser_strcat (cfile
, "peer address ");
956 x_parser_strcat (cfile
, srvaddr
[1]);
958 x_parser_strcat (cfile
, srvaddr
[0]);
959 x_parser_strcat (cfile
, ";\n");
961 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpFailOverPrimaryPort")) != NULL
&&
965 x_parser_strcat (cfile
, "port ");
967 x_parser_strcat (cfile
, "peer port ");
968 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
969 x_parser_strcat (cfile
, ";\n");
972 ldap_value_free_len (tempbv
);
974 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpFailOverSecondaryPort")) != NULL
&&
978 x_parser_strcat (cfile
, "peer port ");
980 x_parser_strcat (cfile
, "port ");
981 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
982 x_parser_strcat (cfile
, ";\n");
985 ldap_value_free_len (tempbv
);
987 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpFailOverResponseDelay")) != NULL
&&
990 x_parser_strcat (cfile
, "max-response-delay ");
991 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
992 x_parser_strcat (cfile
, ";\n");
995 ldap_value_free_len (tempbv
);
997 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpFailOverUnackedUpdates")) != NULL
&&
1000 x_parser_strcat (cfile
, "max-unacked-updates ");
1001 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
1002 x_parser_strcat (cfile
, ";\n");
1005 ldap_value_free_len (tempbv
);
1007 if ((tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpFailOverLoadBalanceTime")) != NULL
&&
1010 x_parser_strcat (cfile
, "load balance max seconds ");
1011 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
1012 x_parser_strcat (cfile
, ";\n");
1015 ldap_value_free_len (tempbv
);
1019 (tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpMaxClientLeadTime")) != NULL
&&
1022 x_parser_strcat (cfile
, "mclt ");
1023 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
1024 x_parser_strcat (cfile
, ";\n");
1027 ldap_value_free_len (tempbv
);
1031 (tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpFailOverSplit")) != NULL
&&
1034 x_parser_strcat (cfile
, "split ");
1035 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
1036 x_parser_strcat (cfile
, ";\n");
1040 ldap_value_free_len (tempbv
);
1043 if (primary
&& !split
&&
1044 (tempbv
= ldap_get_values_len (ld
, item
->ldent
, "dhcpFailOverHashBucketAssignment")) != NULL
&&
1047 x_parser_strcat (cfile
, "hba ");
1048 x_parser_strcat (cfile
, tempbv
[0]->bv_val
);
1049 x_parser_strcat (cfile
, ";\n");
1052 ldap_value_free_len (tempbv
);
1054 item
->close_brace
= 1;
1056 #endif /* HAVE_IFADDRS_H */
1059 add_to_config_stack (LDAPMessage
* res
, LDAPMessage
* ent
)
1061 struct ldap_config_stack
*ns
;
1063 ns
= dmalloc (sizeof (*ns
), MDL
);
1065 log_fatal ("no memory for add_to_config_stack()");
1070 ns
->close_brace
= 0;
1072 ns
->next
= ldap_stack
;
1079 struct sigaction old
, new;
1085 ** ldap_unbind after a LDAP_SERVER_DOWN result
1086 ** causes a SIGPIPE and dhcpd gets terminated,
1087 ** since it doesn't handle it...
1091 new.sa_handler
= SIG_IGN
;
1092 sigemptyset (&new.sa_mask
);
1093 sigaction (SIGPIPE
, &new, &old
);
1095 ldap_unbind_ext_s (ld
, NULL
, NULL
);
1098 sigaction (SIGPIPE
, &old
, &new);
1103 _do_lookup_dhcp_string_option (struct option_state
*options
, int option_name
)
1105 struct option_cache
*oc
;
1106 struct data_string db
;
1109 memset (&db
, 0, sizeof (db
));
1110 oc
= lookup_option (&server_universe
, options
, option_name
);
1112 evaluate_option_cache (&db
, (struct packet
*) NULL
,
1113 (struct lease
*) NULL
,
1114 (struct client_state
*) NULL
, options
,
1115 (struct option_state
*) NULL
,
1116 &global_scope
, oc
, MDL
) &&
1117 db
.data
!= NULL
&& *db
.data
!= '\0')
1120 ret
= dmalloc (db
.len
+ 1, MDL
);
1122 log_fatal ("no memory for ldap option %d value", option_name
);
1124 memcpy (ret
, db
.data
, db
.len
);
1126 data_string_forget (&db
, MDL
);
1136 _do_lookup_dhcp_int_option (struct option_state
*options
, int option_name
)
1138 struct option_cache
*oc
;
1139 struct data_string db
;
1142 memset (&db
, 0, sizeof (db
));
1143 oc
= lookup_option (&server_universe
, options
, option_name
);
1145 evaluate_option_cache (&db
, (struct packet
*) NULL
,
1146 (struct lease
*) NULL
,
1147 (struct client_state
*) NULL
, options
,
1148 (struct option_state
*) NULL
,
1149 &global_scope
, oc
, MDL
) &&
1150 db
.data
!= NULL
&& *db
.data
!= '\0')
1152 ret
= strtol ((const char *) db
.data
, NULL
, 10);
1153 data_string_forget (&db
, MDL
);
1163 _do_lookup_dhcp_enum_option (struct option_state
*options
, int option_name
)
1165 struct option_cache
*oc
;
1166 struct data_string db
;
1169 memset (&db
, 0, sizeof (db
));
1170 oc
= lookup_option (&server_universe
, options
, option_name
);
1172 evaluate_option_cache (&db
, (struct packet
*) NULL
,
1173 (struct lease
*) NULL
,
1174 (struct client_state
*) NULL
, options
,
1175 (struct option_state
*) NULL
,
1176 &global_scope
, oc
, MDL
) &&
1177 db
.data
!= NULL
&& *db
.data
!= '\0')
1182 log_fatal ("invalid option name %d", option_name
);
1184 data_string_forget (&db
, MDL
);
1193 ldap_rebind_cb (LDAP
*ld
, LDAP_CONST
char *url
, ber_tag_t request
, ber_int_t msgid
, void *parms
)
1196 LDAPURLDesc
*ldapurl
= NULL
;
1198 struct berval creds
;
1200 log_info("LDAP rebind to '%s'", url
);
1201 if ((ret
= ldap_url_parse(url
, &ldapurl
)) != LDAP_SUCCESS
)
1203 log_error ("Error: Can not parse ldap rebind url '%s': %s",
1204 url
, ldap_err2string(ret
));
1209 #if defined (LDAP_USE_SSL)
1210 if (strcasecmp(ldapurl
->lud_scheme
, "ldaps") == 0)
1212 int opt
= LDAP_OPT_X_TLS_HARD
;
1213 if ((ret
= ldap_set_option (ld
, LDAP_OPT_X_TLS
, &opt
)) != LDAP_SUCCESS
)
1215 log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
1216 ldapurl
->lud_host
, ldapurl
->lud_port
, ldap_err2string (ret
));
1217 ldap_free_urldesc(ldapurl
);
1222 log_info ("LDAPS session successfully enabled to %s", ldap_server
);
1226 if (strcasecmp(ldapurl
->lud_scheme
, "ldap") == 0 &&
1227 ldap_use_ssl
!= LDAP_SSL_OFF
)
1229 if ((ret
= ldap_start_tls_s (ld
, NULL
, NULL
)) != LDAP_SUCCESS
)
1231 log_error ("Error: Cannot start TLS session to %s:%d: %s",
1232 ldapurl
->lud_host
, ldapurl
->lud_port
, ldap_err2string (ret
));
1233 ldap_free_urldesc(ldapurl
);
1238 log_info ("TLS session successfully started to %s:%d",
1239 ldapurl
->lud_host
, ldapurl
->lud_port
);
1244 #if defined(LDAP_USE_GSSAPI)
1245 if (ldap_gssapi_principal
!= NULL
) {
1246 krb5_get_tgt(ldap_gssapi_principal
, ldap_gssapi_keytab
);
1247 if ((ret
= ldap_sasl_interactive_bind_s(ld
, NULL
, ldap_sasl_inst
->sasl_mech
,
1248 NULL
, NULL
, LDAP_SASL_AUTOMATIC
,
1249 _ldap_sasl_interact
, ldap_sasl_inst
)
1252 log_error ("Error: Cannot SASL bind to ldap server %s:%d: %s",
1253 ldap_server
, ldap_port
, ldap_err2string (ret
));
1255 ldap_get_option( ld
, LDAP_OPT_DIAGNOSTIC_MESSAGE
, (void*)&msg
);
1256 log_error ("\tAdditional info: %s", msg
);
1261 ldap_free_urldesc(ldapurl
);
1266 if (ldap_username
!= NULL
&& *ldap_username
!= '\0' && ldap_password
!= NULL
)
1268 who
= ldap_username
;
1269 creds
.bv_val
= strdup(ldap_password
);
1270 if (creds
.bv_val
== NULL
)
1271 log_fatal ("Error: Unable to allocate memory to duplicate ldap_password");
1273 creds
.bv_len
= strlen(ldap_password
);
1275 if ((ret
= ldap_sasl_bind_s (ld
, who
, LDAP_SASL_SIMPLE
, &creds
,
1276 NULL
, NULL
, NULL
)) != LDAP_SUCCESS
)
1278 log_error ("Error: Cannot login into ldap server %s:%d: %s",
1279 ldapurl
->lud_host
, ldapurl
->lud_port
, ldap_err2string (ret
));
1286 ldap_free_urldesc(ldapurl
);
1291 _do_ldap_retry(int ret
, const char *server
, int port
)
1293 static int inform
= 1;
1295 if (ldap_enable_retry
> 0 && ret
== LDAP_SERVER_DOWN
&& ldap_init_retry
> 0)
1297 if (inform
|| (ldap_init_retry
% 10) == 0)
1300 log_info ("Can't contact LDAP server %s:%d: retrying for %d sec",
1301 server
, port
, ldap_init_retry
);
1304 return ldap_init_retry
--;
1309 static struct berval
*
1310 _do_ldap_str2esc_filter_bv(const char *str
, ber_len_t len
, struct berval
*bv_o
)
1314 if (!str
|| !bv_o
|| (ber_str2bv(str
, len
, 0, &bv_i
) == NULL
) ||
1315 (ldap_bv2escaped_filter_value(&bv_i
, bv_o
) != 0))
1323 struct option_state
*options
;
1326 struct berval creds
;
1327 #if defined(LDAP_USE_GSSAPI)
1328 char *gssapi_realm
= NULL
;
1329 char *gssapi_user
= NULL
;
1330 char *running
= NULL
;
1331 const char *gssapi_delim
= "@";
1337 if (ldap_server
== NULL
)
1340 option_state_allocate (&options
, MDL
);
1342 execute_statements_in_scope (NULL
, NULL
, NULL
, NULL
, NULL
,
1343 options
, &global_scope
, root_group
,
1346 ldap_server
= _do_lookup_dhcp_string_option (options
, SV_LDAP_SERVER
);
1347 ldap_dhcp_server_cn
= _do_lookup_dhcp_string_option (options
,
1348 SV_LDAP_DHCP_SERVER_CN
);
1349 ldap_port
= _do_lookup_dhcp_int_option (options
, SV_LDAP_PORT
);
1350 ldap_base_dn
= _do_lookup_dhcp_string_option (options
, SV_LDAP_BASE_DN
);
1351 ldap_method
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_METHOD
);
1352 ldap_debug_file
= _do_lookup_dhcp_string_option (options
,
1353 SV_LDAP_DEBUG_FILE
);
1354 ldap_referrals
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_REFERRALS
);
1355 ldap_init_retry
= _do_lookup_dhcp_int_option (options
, SV_LDAP_INIT_RETRY
);
1357 #if defined (LDAP_USE_SSL)
1358 ldap_use_ssl
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_SSL
);
1359 if( ldap_use_ssl
!= LDAP_SSL_OFF
)
1361 ldap_tls_reqcert
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_TLS_REQCERT
);
1362 ldap_tls_ca_file
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_CA_FILE
);
1363 ldap_tls_ca_dir
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_CA_DIR
);
1364 ldap_tls_cert
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_CERT
);
1365 ldap_tls_key
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_KEY
);
1366 ldap_tls_crlcheck
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_TLS_CRLCHECK
);
1367 ldap_tls_ciphers
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_CIPHERS
);
1368 ldap_tls_randfile
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_RANDFILE
);
1372 #if defined (LDAP_USE_GSSAPI)
1373 ldap_gssapi_principal
= _do_lookup_dhcp_string_option (options
,
1374 SV_LDAP_GSSAPI_PRINCIPAL
);
1376 if (ldap_gssapi_principal
== NULL
) {
1377 log_error("ldap_gssapi_principal is not set,"
1378 "GSSAPI Authentication for LDAP will not be used");
1380 ldap_gssapi_keytab
= _do_lookup_dhcp_string_option (options
,
1381 SV_LDAP_GSSAPI_KEYTAB
);
1382 if (ldap_gssapi_keytab
== NULL
) {
1383 log_fatal("ldap_gssapi_keytab must be specified");
1386 running
= strdup(ldap_gssapi_principal
);
1387 if (running
== NULL
)
1388 log_fatal("Could not allocate memory to duplicate gssapi principal");
1390 gssapi_user
= strtok(running
, gssapi_delim
);
1391 if (!gssapi_user
|| strlen(gssapi_user
) == 0) {
1392 log_fatal ("GSSAPI principal must specify user: user@realm");
1395 gssapi_realm
= strtok(NULL
, gssapi_delim
);
1396 if (!gssapi_realm
|| strlen(gssapi_realm
) == 0) {
1397 log_fatal ("GSSAPI principal must specify realm: user@realm");
1400 ldap_sasl_inst
= malloc(sizeof(struct ldap_sasl_instance
));
1401 if (ldap_sasl_inst
== NULL
)
1402 log_fatal("Could not allocate memory for sasl instance! Can not run!");
1404 ldap_sasl_inst
->sasl_mech
= ber_strdup("GSSAPI");
1405 if (ldap_sasl_inst
->sasl_mech
== NULL
)
1406 log_fatal("Could not allocate memory to duplicate gssapi mechanism");
1408 ldap_sasl_inst
->sasl_realm
= ber_strdup(gssapi_realm
);
1409 if (ldap_sasl_inst
->sasl_realm
== NULL
)
1410 log_fatal("Could not allocate memory to duplicate gssapi realm");
1412 ldap_sasl_inst
->sasl_authz_id
= ber_strdup(gssapi_user
);
1413 if (ldap_sasl_inst
->sasl_authz_id
== NULL
)
1414 log_fatal("Could not allocate memory to duplicate gssapi user");
1416 ldap_sasl_inst
->sasl_authc_id
= NULL
;
1417 ldap_sasl_inst
->sasl_password
= NULL
; //"" before
1422 #if defined (LDAP_CASA_AUTH)
1423 if (!load_uname_pwd_from_miCASA(&ldap_username
,&ldap_password
))
1425 #if defined (DEBUG_LDAP)
1426 log_info ("Authentication credential taken from file");
1430 ldap_username
= _do_lookup_dhcp_string_option (options
, SV_LDAP_USERNAME
);
1431 ldap_password
= _do_lookup_dhcp_string_option (options
, SV_LDAP_PASSWORD
);
1433 #if defined (LDAP_CASA_AUTH)
1437 option_state_dereference (&options
, MDL
);
1440 if (ldap_server
== NULL
|| ldap_base_dn
== NULL
)
1442 log_info ("Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not specified in the config file");
1443 ldap_method
= LDAP_METHOD_STATIC
;
1447 if (ldap_debug_file
!= NULL
&& ldap_debug_fd
== -1)
1449 if ((ldap_debug_fd
= open (ldap_debug_file
, O_CREAT
| O_TRUNC
| O_WRONLY
,
1450 S_IRUSR
| S_IWUSR
)) < 0)
1451 log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file
,
1455 #if defined (DEBUG_LDAP)
1456 log_info ("Connecting to LDAP server %s:%d", ldap_server
, ldap_port
);
1459 #if defined (LDAP_USE_SSL)
1460 if (ldap_use_ssl
== -1)
1463 ** There was no "ldap-ssl" option in dhcpd.conf (also not "off").
1464 ** Let's try, if we can use an anonymous TLS session without to
1465 ** verify the server certificate -- if not continue without TLS.
1467 int opt
= LDAP_OPT_X_TLS_ALLOW
;
1468 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_REQUIRE_CERT
,
1469 &opt
)) != LDAP_SUCCESS
)
1471 log_error ("Warning: Cannot set LDAP TLS require cert option to 'allow': %s",
1472 ldap_err2string (ret
));
1476 if (ldap_use_ssl
!= LDAP_SSL_OFF
)
1478 if (ldap_tls_reqcert
!= -1)
1480 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_REQUIRE_CERT
,
1481 &ldap_tls_reqcert
)) != LDAP_SUCCESS
)
1483 log_error ("Cannot set LDAP TLS require cert option: %s",
1484 ldap_err2string (ret
));
1488 if( ldap_tls_ca_file
!= NULL
)
1490 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CACERTFILE
,
1491 ldap_tls_ca_file
)) != LDAP_SUCCESS
)
1493 log_error ("Cannot set LDAP TLS CA certificate file %s: %s",
1494 ldap_tls_ca_file
, ldap_err2string (ret
));
1497 if( ldap_tls_ca_dir
!= NULL
)
1499 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CACERTDIR
,
1500 ldap_tls_ca_dir
)) != LDAP_SUCCESS
)
1502 log_error ("Cannot set LDAP TLS CA certificate dir %s: %s",
1503 ldap_tls_ca_dir
, ldap_err2string (ret
));
1506 if( ldap_tls_cert
!= NULL
)
1508 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CERTFILE
,
1509 ldap_tls_cert
)) != LDAP_SUCCESS
)
1511 log_error ("Cannot set LDAP TLS client certificate file %s: %s",
1512 ldap_tls_cert
, ldap_err2string (ret
));
1515 if( ldap_tls_key
!= NULL
)
1517 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_KEYFILE
,
1518 ldap_tls_key
)) != LDAP_SUCCESS
)
1520 log_error ("Cannot set LDAP TLS certificate key file %s: %s",
1521 ldap_tls_key
, ldap_err2string (ret
));
1524 if( ldap_tls_crlcheck
!= -1)
1526 int opt
= ldap_tls_crlcheck
;
1527 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CRLCHECK
,
1528 &opt
)) != LDAP_SUCCESS
)
1530 log_error ("Cannot set LDAP TLS crl check option: %s",
1531 ldap_err2string (ret
));
1534 if( ldap_tls_ciphers
!= NULL
)
1536 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CIPHER_SUITE
,
1537 ldap_tls_ciphers
)) != LDAP_SUCCESS
)
1539 log_error ("Cannot set LDAP TLS cipher suite %s: %s",
1540 ldap_tls_ciphers
, ldap_err2string (ret
));
1543 if( ldap_tls_randfile
!= NULL
)
1545 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_RANDOM_FILE
,
1546 ldap_tls_randfile
)) != LDAP_SUCCESS
)
1548 log_error ("Cannot set LDAP TLS random file %s: %s",
1549 ldap_tls_randfile
, ldap_err2string (ret
));
1555 /* enough for 'ldap://+ + hostname + ':' + port number */
1556 uri
= malloc(strlen(ldap_server
) + 16);
1559 log_error ("Cannot build ldap init URI %s:%d", ldap_server
, ldap_port
);
1563 sprintf(uri
, "ldap://%s:%d", ldap_server
, ldap_port
);
1564 ldap_initialize(&ld
, uri
);
1568 log_error ("Cannot init ldap session to %s:%d", ldap_server
, ldap_port
);
1574 version
= LDAP_VERSION3
;
1575 if ((ret
= ldap_set_option (ld
, LDAP_OPT_PROTOCOL_VERSION
, &version
)) != LDAP_OPT_SUCCESS
)
1577 log_error ("Cannot set LDAP version to %d: %s", version
,
1578 ldap_err2string (ret
));
1581 if (ldap_referrals
!= -1)
1583 if ((ret
= ldap_set_option (ld
, LDAP_OPT_REFERRALS
, ldap_referrals
?
1584 LDAP_OPT_ON
: LDAP_OPT_OFF
)) != LDAP_OPT_SUCCESS
)
1586 log_error ("Cannot %s LDAP referrals option: %s",
1587 (ldap_referrals
? "enable" : "disable"),
1588 ldap_err2string (ret
));
1592 if ((ret
= ldap_set_rebind_proc(ld
, ldap_rebind_cb
, NULL
)) != LDAP_SUCCESS
)
1594 log_error ("Warning: Cannot set ldap rebind procedure: %s",
1595 ldap_err2string (ret
));
1598 #if defined (LDAP_USE_SSL)
1599 if (ldap_use_ssl
== LDAP_SSL_LDAPS
||
1600 (ldap_use_ssl
== LDAP_SSL_ON
&& ldap_port
== LDAPS_PORT
))
1602 int opt
= LDAP_OPT_X_TLS_HARD
;
1603 if ((ret
= ldap_set_option (ld
, LDAP_OPT_X_TLS
, &opt
)) != LDAP_SUCCESS
)
1605 log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
1606 ldap_server
, ldap_port
, ldap_err2string (ret
));
1612 log_info ("LDAPS session successfully enabled to %s:%d",
1613 ldap_server
, ldap_port
);
1616 else if (ldap_use_ssl
!= LDAP_SSL_OFF
)
1620 ret
= ldap_start_tls_s (ld
, NULL
, NULL
);
1622 while(_do_ldap_retry(ret
, ldap_server
, ldap_port
) > 0);
1624 if (ret
!= LDAP_SUCCESS
)
1626 log_error ("Error: Cannot start TLS session to %s:%d: %s",
1627 ldap_server
, ldap_port
, ldap_err2string (ret
));
1633 log_info ("TLS session successfully started to %s:%d",
1634 ldap_server
, ldap_port
);
1639 #if defined(LDAP_USE_GSSAPI)
1640 if (ldap_gssapi_principal
!= NULL
) {
1641 krb5_get_tgt(ldap_gssapi_principal
, ldap_gssapi_keytab
);
1642 if ((ret
= ldap_sasl_interactive_bind_s(ld
, NULL
, ldap_sasl_inst
->sasl_mech
,
1643 NULL
, NULL
, LDAP_SASL_AUTOMATIC
,
1644 _ldap_sasl_interact
, ldap_sasl_inst
)
1647 log_error ("Error: Cannot SASL bind to ldap server %s:%d: %s",
1648 ldap_server
, ldap_port
, ldap_err2string (ret
));
1650 ldap_get_option( ld
, LDAP_OPT_DIAGNOSTIC_MESSAGE
, (void*)&msg
);
1651 log_error ("\tAdditional info: %s", msg
);
1659 if (ldap_username
!= NULL
&& *ldap_username
!= '\0' && ldap_password
!= NULL
)
1661 creds
.bv_val
= strdup(ldap_password
);
1662 if (creds
.bv_val
== NULL
)
1663 log_fatal ("Error: Unable to allocate memory to duplicate ldap_password");
1665 creds
.bv_len
= strlen(ldap_password
);
1669 ret
= ldap_sasl_bind_s (ld
, ldap_username
, LDAP_SASL_SIMPLE
,
1670 &creds
, NULL
, NULL
, NULL
);
1672 while(_do_ldap_retry(ret
, ldap_server
, ldap_port
) > 0);
1675 if (ret
!= LDAP_SUCCESS
)
1677 log_error ("Error: Cannot login into ldap server %s:%d: %s",
1678 ldap_server
, ldap_port
, ldap_err2string (ret
));
1684 #if defined (DEBUG_LDAP)
1685 log_info ("Successfully logged into LDAP server %s", ldap_server
);
1691 parse_external_dns (LDAPMessage
* ent
)
1693 char *search
[] = {"dhcpOptionsDN", "dhcpSharedNetworkDN", "dhcpSubnetDN",
1694 "dhcpGroupDN", "dhcpHostDN", "dhcpClassesDN",
1695 "dhcpPoolDN", "dhcpZoneDN", "dhcpFailOverPeerDN", NULL
};
1697 /* TODO: dhcpKeyDN can't be added. It is referenced in dhcpDnsZone to
1698 retrive the key name (cn). Adding keyDN will reflect adding a key
1699 declaration inside the zone configuration.
1701 dhcpSubClassesDN cant be added. It is also similar to the above.
1702 Needs schema change.
1704 LDAPMessage
* newres
, * newent
;
1705 struct berval
**tempbv
;
1707 #if defined (DEBUG_LDAP)
1710 dn
= ldap_get_dn (ld
, ent
);
1713 log_info ("Parsing external DNs for '%s'", dn
);
1723 for (i
=0; search
[i
] != NULL
; i
++)
1725 if ((tempbv
= ldap_get_values_len (ld
, ent
, search
[i
])) == NULL
)
1728 for (j
=0; tempbv
[j
] != NULL
; j
++)
1730 if (*tempbv
[j
]->bv_val
== '\0')
1733 if ((ret
= ldap_search_ext_s(ld
, tempbv
[j
]->bv_val
, LDAP_SCOPE_BASE
,
1734 "objectClass=*", NULL
, 0, NULL
,
1735 NULL
, NULL
, 0, &newres
)) != LDAP_SUCCESS
)
1737 ldap_value_free_len (tempbv
);
1742 #if defined (DEBUG_LDAP)
1743 log_info ("Adding contents of subtree '%s' to config stack from '%s' reference", tempbv
[j
]->bv_val
, search
[i
]);
1745 for (newent
= ldap_first_entry (ld
, newres
);
1747 newent
= ldap_next_entry (ld
, newent
))
1749 #if defined (DEBUG_LDAP)
1750 dn
= ldap_get_dn (ld
, newent
);
1753 log_info ("Adding LDAP result set starting with '%s' to config stack", dn
);
1758 add_to_config_stack (newres
, newent
);
1759 /* don't free newres here */
1763 ldap_value_free_len (tempbv
);
1769 free_stack_entry (struct ldap_config_stack
*item
)
1771 struct ldap_config_stack
*look_ahead_pointer
= item
;
1772 int may_free_msg
= 1;
1774 while (look_ahead_pointer
->next
!= NULL
)
1776 look_ahead_pointer
= look_ahead_pointer
->next
;
1777 if (look_ahead_pointer
->res
== item
->res
)
1785 ldap_msgfree (item
->res
);
1792 next_ldap_entry (struct parse
*cfile
)
1794 struct ldap_config_stack
*temp_stack
;
1796 if (ldap_stack
!= NULL
&& ldap_stack
->close_brace
)
1798 x_parser_strcat (cfile
, "}\n");
1799 ldap_stack
->close_brace
= 0;
1802 while (ldap_stack
!= NULL
&&
1803 (ldap_stack
->ldent
== NULL
|| ( ldap_stack
->processed
&&
1804 (ldap_stack
->ldent
= ldap_next_entry (ld
, ldap_stack
->ldent
)) == NULL
)))
1806 if (ldap_stack
->close_brace
)
1808 x_parser_strcat (cfile
, "}\n");
1809 ldap_stack
->close_brace
= 0;
1812 temp_stack
= ldap_stack
;
1813 ldap_stack
= ldap_stack
->next
;
1814 free_stack_entry (temp_stack
);
1817 if (ldap_stack
!= NULL
&& ldap_stack
->close_brace
)
1819 x_parser_strcat (cfile
, "}\n");
1820 ldap_stack
->close_brace
= 0;
1826 check_statement_end (const char *statement
)
1830 if (statement
== NULL
|| *statement
== '\0')
1834 ** check if it ends with "}", e.g.:
1835 ** "zone my.domain. { ... }"
1836 ** optionally followed by spaces
1838 ptr
= strrchr (statement
, '}');
1841 /* skip following white-spaces */
1842 for (++ptr
; isspace ((int)*ptr
); ptr
++);
1844 /* check if we reached the end */
1846 return ('}'); /* yes, block end */
1852 ** this should not happen, but...
1853 ** check if it ends with ";", e.g.:
1855 ** optionally followed by spaces
1857 ptr
= strrchr (statement
, ';');
1860 /* skip following white-spaces */
1861 for (++ptr
; isspace ((int)*ptr
); ptr
++);
1863 /* check if we reached the end */
1865 return (';'); /* ends with a ; */
1875 ldap_parse_entry_options (LDAPMessage
*ent
, struct parse
*cfile
,
1878 struct berval
**tempbv
;
1881 if (ent
== NULL
|| cfile
== NULL
)
1882 return (ISC_R_FAILURE
);
1884 if ((tempbv
= ldap_get_values_len (ld
, ent
, "dhcpStatements")) != NULL
)
1886 for (i
=0; tempbv
[i
] != NULL
; i
++)
1888 if (lease_limit
!= NULL
&&
1889 strncasecmp ("lease limit ", tempbv
[i
]->bv_val
, 12) == 0)
1891 *lease_limit
= (int) strtol ((tempbv
[i
]->bv_val
) + 12, NULL
, 10);
1895 x_parser_strcat (cfile
, tempbv
[i
]->bv_val
);
1897 switch((int) check_statement_end (tempbv
[i
]->bv_val
))
1901 x_parser_strcat (cfile
, "\n");
1904 x_parser_strcat (cfile
, ";\n");
1908 ldap_value_free_len (tempbv
);
1911 if ((tempbv
= ldap_get_values_len (ld
, ent
, "dhcpOption")) != NULL
)
1913 for (i
=0; tempbv
[i
] != NULL
; i
++)
1915 x_parser_strcat (cfile
, "option ");
1916 x_parser_strcat (cfile
, tempbv
[i
]->bv_val
);
1917 switch ((int) check_statement_end (tempbv
[i
]->bv_val
))
1920 x_parser_strcat (cfile
, "\n");
1923 x_parser_strcat (cfile
, ";\n");
1927 ldap_value_free_len (tempbv
);
1930 return (ISC_R_SUCCESS
);
1935 ldap_generate_config_string (struct parse
*cfile
)
1937 struct berval
**objectClass
;
1939 struct ldap_config_stack
*entry
;
1940 LDAPMessage
* ent
, * res
, *entfirst
, *resfirst
;
1941 int i
, ignore
, found
;
1942 int ret
, parsedn
= 1;
1943 size_t len
= cfile
->buflen
;
1951 if ((objectClass
= ldap_get_values_len (ld
, entry
->ldent
,
1952 "objectClass")) == NULL
)
1955 entry
->processed
= 1;
1958 for (i
=0; objectClass
[i
] != NULL
; i
++)
1960 if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpSharedNetwork") == 0)
1961 ldap_parse_shared_network (entry
, cfile
);
1962 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpClass") == 0)
1963 ldap_parse_class (entry
, cfile
);
1964 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpSubnet") == 0)
1965 ldap_parse_subnet (entry
, cfile
);
1966 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpSubnet6") == 0)
1967 ldap_parse_subnet6 (entry
, cfile
);
1968 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpPool") == 0)
1969 ldap_parse_pool (entry
, cfile
);
1970 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpPool6") == 0)
1971 ldap_parse_pool6 (entry
, cfile
);
1972 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpGroup") == 0)
1973 ldap_parse_group (entry
, cfile
);
1974 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpTSigKey") == 0)
1975 ldap_parse_key (entry
, cfile
);
1976 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpDnsZone") == 0)
1977 ldap_parse_zone (entry
, cfile
);
1978 #if defined(HAVE_IFADDRS_H)
1979 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpFailOverPeer") == 0)
1980 ldap_parse_failover (entry
, cfile
);
1982 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpHost") == 0)
1984 if (ldap_method
== LDAP_METHOD_STATIC
)
1985 ldap_parse_host (entry
, cfile
);
1992 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpSubClass") == 0)
1994 if (ldap_method
== LDAP_METHOD_STATIC
)
1995 ldap_parse_subclass (entry
, cfile
);
2005 if (found
&& x_parser_length(cfile
) <= len
)
2012 ldap_value_free_len (objectClass
);
2016 next_ldap_entry (cfile
);
2020 ldap_parse_entry_options(entry
->ldent
, cfile
, NULL
);
2022 dn
= ldap_get_dn (ld
, entry
->ldent
);
2028 #if defined(DEBUG_LDAP)
2029 log_info ("Found LDAP entry '%s'", dn
);
2032 if ((ret
= ldap_search_ext_s (ld
, dn
, LDAP_SCOPE_ONELEVEL
,
2033 "(!(|(|(objectClass=dhcpTSigKey)(objectClass=dhcpClass)) (objectClass=dhcpFailOverPeer)))",
2034 NULL
, 0, NULL
, NULL
,
2035 NULL
, 0, &res
)) != LDAP_SUCCESS
)
2043 if ((ret
= ldap_search_ext_s (ld
, dn
, LDAP_SCOPE_ONELEVEL
,
2044 "(|(|(objectClass=dhcpTSigKey)(objectClass=dhcpClass)) (objectClass=dhcpFailOverPeer))",
2045 NULL
, 0, NULL
, NULL
,
2046 NULL
, 0, &resfirst
)) != LDAP_SUCCESS
)
2057 ent
= ldap_first_entry(ld
, res
);
2058 entfirst
= ldap_first_entry(ld
, resfirst
);
2060 if (ent
== NULL
&& entfirst
== NULL
)
2062 parse_external_dns (entry
->ldent
);
2063 next_ldap_entry (cfile
);
2068 add_to_config_stack (res
, ent
);
2069 parse_external_dns (entry
->ldent
);
2075 if (entfirst
!= NULL
)
2077 add_to_config_stack (resfirst
, entfirst
);
2079 parse_external_dns (entry
->ldent
);
2083 ldap_msgfree (resfirst
);
2088 ldap_close_debug_fd()
2090 if (ldap_debug_fd
!= -1)
2092 close (ldap_debug_fd
);
2099 ldap_write_debug (const void *buff
, size_t size
)
2101 if (ldap_debug_fd
!= -1)
2103 if (write (ldap_debug_fd
, buff
, size
) < 0)
2105 log_error ("Error writing to LDAP debug file %s: %s."
2106 " Disabling log file.", ldap_debug_file
,
2108 ldap_close_debug_fd();
2114 ldap_read_function (struct parse
*cfile
)
2118 /* append when in saved state */
2119 if (cfile
->saved_state
== NULL
)
2121 cfile
->inbuf
[0] = '\0';
2125 len
= cfile
->buflen
;
2127 while (ldap_stack
!= NULL
&& x_parser_length(cfile
) <= len
)
2128 ldap_generate_config_string (cfile
);
2130 if (x_parser_length(cfile
) <= len
&& ldap_stack
== NULL
)
2133 if (cfile
->buflen
> len
)
2134 ldap_write_debug (cfile
->inbuf
+ len
, cfile
->buflen
- len
);
2135 #if defined (DEBUG_LDAP)
2136 log_info ("Sending config portion '%s'", cfile
->inbuf
+ len
);
2139 return (cfile
->inbuf
[cfile
->bufix
++]);
2144 ldap_get_host_name (LDAPMessage
* ent
)
2146 struct berval
**name
;
2150 if ((name
= ldap_get_values_len (ld
, ent
, "cn")) == NULL
|| name
[0] == NULL
)
2153 ldap_value_free_len (name
);
2155 #if defined (DEBUG_LDAP)
2156 ret
= ldap_get_dn (ld
, ent
);
2159 log_info ("Cannot get cn attribute for LDAP entry %s", ret
);
2166 ret
= dmalloc (strlen (name
[0]->bv_val
) + 1, MDL
);
2167 strcpy (ret
, name
[0]->bv_val
);
2168 ldap_value_free_len (name
);
2175 ldap_read_config (void)
2177 LDAPMessage
* ldres
, * hostres
, * ent
, * hostent
;
2178 char hfilter
[1024], sfilter
[1024], fqdn
[257];
2180 ldap_dn_node
*curr
= NULL
;
2181 struct parse
*cfile
;
2182 struct utsname unme
;
2186 struct berval
**tempbv
= NULL
;
2187 struct berval bv_o
[2];
2189 cfile
= x_parser_init("LDAP");
2191 return (ISC_R_NOMEMORY
);
2193 ldap_enable_retry
= 1;
2196 ldap_enable_retry
= 0;
2200 x_parser_free(&cfile
);
2201 return (ldap_server
== NULL
? ISC_R_SUCCESS
: ISC_R_FAILURE
);
2205 if (ldap_dhcp_server_cn
!= NULL
)
2207 if (_do_ldap_str2esc_filter_bv(ldap_dhcp_server_cn
, 0, &bv_o
[0]) == NULL
)
2209 log_error ("Cannot escape ldap filter value %s: %m", ldap_dhcp_server_cn
);
2210 x_parser_free(&cfile
);
2211 return (ISC_R_FAILURE
);
2214 snprintf (hfilter
, sizeof (hfilter
),
2215 "(&(objectClass=dhcpServer)(cn=%s))", bv_o
[0].bv_val
);
2217 ber_memfree(bv_o
[0].bv_val
);
2221 if (_do_ldap_str2esc_filter_bv(unme
.nodename
, 0, &bv_o
[0]) == NULL
)
2223 log_error ("Cannot escape ldap filter value %s: %m", unme
.nodename
);
2224 x_parser_free(&cfile
);
2225 return (ISC_R_FAILURE
);
2229 if(0 == get_host_entry(fqdn
, sizeof(fqdn
), NULL
, 0))
2231 if (_do_ldap_str2esc_filter_bv(fqdn
, 0, &bv_o
[1]) == NULL
)
2233 log_error ("Cannot escape ldap filter value %s: %m", fqdn
);
2234 ber_memfree(bv_o
[0].bv_val
);
2235 x_parser_free(&cfile
);
2236 return (ISC_R_FAILURE
);
2240 // If we have fqdn and it isn't the same as nodename, use it in filter
2241 // otherwise just use nodename
2242 if ((*fqdn
) && (strcmp(unme
.nodename
, fqdn
))) {
2243 snprintf (hfilter
, sizeof (hfilter
),
2244 "(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))",
2245 bv_o
[0].bv_val
, bv_o
[1].bv_val
);
2247 ber_memfree(bv_o
[1].bv_val
);
2251 snprintf (hfilter
, sizeof (hfilter
),
2252 "(&(objectClass=dhcpServer)(cn=%s))",
2256 ber_memfree(bv_o
[0].bv_val
);
2259 ldap_enable_retry
= 1;
2263 ret
= ldap_search_ext_s (ld
, ldap_base_dn
, LDAP_SCOPE_SUBTREE
,
2264 hfilter
, NULL
, 0, NULL
, NULL
, NULL
, 0,
2267 while(_do_ldap_retry(ret
, ldap_server
, ldap_port
) > 0);
2268 ldap_enable_retry
= 0;
2270 if(ret
!= LDAP_SUCCESS
)
2272 log_error ("Cannot find host LDAP entry %s %s",
2273 ((ldap_dhcp_server_cn
== NULL
)?(unme
.nodename
):(ldap_dhcp_server_cn
)), hfilter
);
2275 ldap_msgfree (hostres
);
2277 x_parser_free(&cfile
);
2278 return (ISC_R_FAILURE
);
2281 if ((hostent
= ldap_first_entry (ld
, hostres
)) == NULL
)
2283 log_error ("Error: Cannot find LDAP entry matching %s", hfilter
);
2284 ldap_msgfree (hostres
);
2286 x_parser_free(&cfile
);
2287 return (ISC_R_FAILURE
);
2290 hostdn
= ldap_get_dn (ld
, hostent
);
2291 #if defined(DEBUG_LDAP)
2293 log_info ("Found dhcpServer LDAP entry '%s'", hostdn
);
2296 if (hostdn
== NULL
||
2297 (tempbv
= ldap_get_values_len (ld
, hostent
, "dhcpServiceDN")) == NULL
||
2300 log_error ("Error: No dhcp service is associated with the server %s %s",
2301 (hostdn
? "dn" : "name"), (hostdn
? hostdn
:
2302 (ldap_dhcp_server_cn
? ldap_dhcp_server_cn
: unme
.nodename
)));
2305 ldap_value_free_len (tempbv
);
2308 ldap_memfree (hostdn
);
2309 ldap_msgfree (hostres
);
2311 x_parser_free(&cfile
);
2312 return (ISC_R_FAILURE
);
2315 #if defined(DEBUG_LDAP)
2316 log_info ("LDAP: Parsing dhcpServer options '%s' ...", hostdn
);
2319 res
= ldap_parse_entry_options(hostent
, cfile
, NULL
);
2320 if (res
!= ISC_R_SUCCESS
)
2322 ldap_value_free_len (tempbv
);
2323 ldap_msgfree (hostres
);
2324 ldap_memfree (hostdn
);
2326 x_parser_free(&cfile
);
2330 if (x_parser_length(cfile
) > 0)
2332 ldap_write_debug(cfile
->inbuf
, cfile
->buflen
);
2334 res
= conf_file_subparse (cfile
, root_group
, ROOT_GROUP
);
2335 if (res
!= ISC_R_SUCCESS
)
2337 log_error ("LDAP: cannot parse dhcpServer entry '%s'", hostdn
);
2338 ldap_value_free_len (tempbv
);
2339 ldap_msgfree (hostres
);
2340 ldap_memfree (hostdn
);
2342 x_parser_free(&cfile
);
2345 x_parser_reset(cfile
);
2347 ldap_msgfree (hostres
);
2349 res
= ISC_R_SUCCESS
;
2350 for (cnt
=0; tempbv
[cnt
] != NULL
; cnt
++)
2353 if (_do_ldap_str2esc_filter_bv(hostdn
, 0, &bv_o
[0]) == NULL
)
2355 log_error ("Cannot escape ldap filter value %s: %m", hostdn
);
2356 res
= ISC_R_FAILURE
;
2360 snprintf(sfilter
, sizeof(sfilter
), "(&(objectClass=dhcpService)"
2361 "(|(|(dhcpPrimaryDN=%s)(dhcpSecondaryDN=%s))(dhcpServerDN=%s)))",
2362 bv_o
[0].bv_val
, bv_o
[0].bv_val
, bv_o
[0].bv_val
);
2364 ber_memfree(bv_o
[0].bv_val
);
2367 if ((ret
= ldap_search_ext_s (ld
, tempbv
[cnt
]->bv_val
, LDAP_SCOPE_BASE
,
2368 sfilter
, NULL
, 0, NULL
, NULL
, NULL
,
2369 0, &ldres
)) != LDAP_SUCCESS
)
2371 log_error ("Error searching for dhcpServiceDN '%s': %s. Please update the LDAP entry '%s'",
2372 tempbv
[cnt
]->bv_val
, ldap_err2string (ret
), hostdn
);
2374 ldap_msgfree(ldres
);
2375 res
= ISC_R_FAILURE
;
2379 if ((ent
= ldap_first_entry (ld
, ldres
)) == NULL
)
2381 log_error ("Error: Cannot find dhcpService DN '%s' with server reference. Please update the LDAP server entry '%s'",
2382 tempbv
[cnt
]->bv_val
, hostdn
);
2384 ldap_msgfree(ldres
);
2385 res
= ISC_R_FAILURE
;
2390 ** FIXME: how to free the remembered dn's on exit?
2391 ** This should be OK if dmalloc registers the
2392 ** memory it allocated and frees it on exit..
2395 curr
= dmalloc (sizeof (*curr
), MDL
);
2398 length
= strlen (tempbv
[cnt
]->bv_val
);
2399 curr
->dn
= dmalloc (length
+ 1, MDL
);
2400 if (curr
->dn
== NULL
)
2406 strcpy (curr
->dn
, tempbv
[cnt
]->bv_val
);
2413 /* append to service-dn list */
2414 if (ldap_service_dn_tail
!= NULL
)
2415 ldap_service_dn_tail
->next
= curr
;
2417 ldap_service_dn_head
= curr
;
2419 ldap_service_dn_tail
= curr
;
2422 log_fatal ("no memory to remember ldap service dn");
2424 #if defined (DEBUG_LDAP)
2425 log_info ("LDAP: Parsing dhcpService DN '%s' ...", tempbv
[cnt
]->bv_val
);
2427 add_to_config_stack (ldres
, ent
);
2428 res
= conf_file_subparse (cfile
, root_group
, ROOT_GROUP
);
2429 if (res
!= ISC_R_SUCCESS
)
2431 log_error ("LDAP: cannot parse dhcpService entry '%s'", tempbv
[cnt
]->bv_val
);
2436 x_parser_free(&cfile
);
2437 ldap_close_debug_fd();
2439 ldap_memfree (hostdn
);
2440 ldap_value_free_len (tempbv
);
2442 if (res
!= ISC_R_SUCCESS
)
2444 struct ldap_config_stack
*temp_stack
;
2446 while ((curr
= ldap_service_dn_head
) != NULL
)
2448 ldap_service_dn_head
= curr
->next
;
2449 dfree (curr
->dn
, MDL
);
2453 ldap_service_dn_tail
= NULL
;
2455 while ((temp_stack
= ldap_stack
) != NULL
)
2457 ldap_stack
= temp_stack
->next
;
2458 free_stack_entry (temp_stack
);
2464 /* Unbind from ldap immediately after reading config in static mode. */
2465 if (ldap_method
== LDAP_METHOD_STATIC
)
2472 /* This function will parse the dhcpOption and dhcpStatements field in the LDAP
2473 entry if it exists. Right now, type will be either HOST_DECL or CLASS_DECL.
2474 If we are parsing a HOST_DECL, this always returns 0. If we are parsing a
2475 CLASS_DECL, this will return what the current lease limit is in LDAP. If
2476 there is no lease limit specified, we return 0 */
2479 ldap_parse_options (LDAPMessage
* ent
, struct group
*group
,
2480 int type
, struct host_decl
*host
,
2481 struct class **class)
2483 int declaration
, lease_limit
;
2484 enum dhcp_token token
;
2485 struct parse
*cfile
;
2490 cfile
= x_parser_init(type
== HOST_DECL
? "LDAP-HOST" : "LDAP-SUBCLASS");
2492 return (lease_limit
);
2494 /* This block of code will try to find the parent of the host, and
2495 if it is a group object, fetch the options and apply to the host. */
2496 if (type
== HOST_DECL
)
2498 char *hostdn
, *basedn
, *temp1
, *temp2
, filter
[1024];
2499 LDAPMessage
*groupdn
, *entry
;
2502 hostdn
= ldap_get_dn (ld
, ent
);
2507 temp1
= strchr (hostdn
, '=');
2509 temp1
= strchr (++temp1
, '=');
2511 temp2
= strchr (++temp1
, ',');
2519 if (_do_ldap_str2esc_filter_bv(temp1
, (temp2
- temp1
), &bv_o
) == NULL
)
2521 log_error ("Cannot escape ldap filter value %.*s: %m",
2522 (int)(temp2
- temp1
), temp1
);
2527 snprintf (filter
, sizeof(filter
),
2528 "(&(cn=%s)(objectClass=dhcpGroup))",
2531 ber_memfree(bv_o
.bv_val
);
2534 basedn
= strchr (temp1
, ',');
2539 if (basedn
!= NULL
&& *basedn
!= '\0' && filter
[0] != '\0')
2541 ret
= ldap_search_ext_s (ld
, basedn
, LDAP_SCOPE_SUBTREE
, filter
,
2542 NULL
, 0, NULL
, NULL
, NULL
, 0, &groupdn
);
2543 if (ret
== LDAP_SUCCESS
)
2545 if ((entry
= ldap_first_entry (ld
, groupdn
)) != NULL
)
2547 res
= ldap_parse_entry_options (entry
, cfile
, &lease_limit
);
2548 if (res
!= ISC_R_SUCCESS
)
2550 /* reset option buffer discarding any results */
2551 x_parser_reset(cfile
);
2555 ldap_msgfree( groupdn
);
2558 ldap_memfree( hostdn
);
2562 res
= ldap_parse_entry_options (ent
, cfile
, &lease_limit
);
2563 if (res
!= ISC_R_SUCCESS
)
2565 x_parser_free(&cfile
);
2566 return (lease_limit
);
2569 if (x_parser_length(cfile
) == 0)
2571 x_parser_free(&cfile
);
2572 return (lease_limit
);
2578 token
= peek_token (&val
, NULL
, cfile
);
2579 if (token
== END_OF_FILE
)
2581 declaration
= parse_statement (cfile
, group
, type
, host
, declaration
);
2584 x_parser_free(&cfile
);
2586 return (lease_limit
);
2592 find_haddr_in_ldap (struct host_decl
**hp
, int htype
, unsigned hlen
,
2593 const unsigned char *haddr
, const char *file
, int line
)
2595 char buf
[128], *type_str
;
2596 LDAPMessage
* res
, *ent
;
2597 struct host_decl
* host
;
2598 isc_result_t status
;
2603 struct berval bv_o
[2];
2608 if (ldap_method
== LDAP_METHOD_STATIC
)
2619 type_str
= "ethernet";
2622 type_str
= "token-ring";
2628 log_info ("Ignoring unknown type %d", htype
);
2633 ** FIXME: It is not guaranteed, that the dhcpHWAddress attribute
2634 ** contains _exactly_ "type addr" with one space between!
2636 snprintf(lo_hwaddr
, sizeof(lo_hwaddr
), "%s",
2637 print_hw_addr (htype
, hlen
, haddr
));
2638 x_strxform(up_hwaddr
, lo_hwaddr
, sizeof(up_hwaddr
), toupper
);
2640 if (_do_ldap_str2esc_filter_bv(lo_hwaddr
, 0, &bv_o
[0]) == NULL
)
2642 log_error ("Cannot escape ldap filter value %s: %m", lo_hwaddr
);
2645 if (_do_ldap_str2esc_filter_bv(up_hwaddr
, 0, &bv_o
[1]) == NULL
)
2647 log_error ("Cannot escape ldap filter value %s: %m", up_hwaddr
);
2648 ber_memfree(bv_o
[0].bv_val
);
2652 snprintf (buf
, sizeof (buf
),
2653 "(&(objectClass=dhcpHost)(|(dhcpHWAddress=%s %s)(dhcpHWAddress=%s %s)))",
2654 type_str
, bv_o
[0].bv_val
, type_str
, bv_o
[1].bv_val
);
2656 ber_memfree(bv_o
[0].bv_val
);
2657 ber_memfree(bv_o
[1].bv_val
);
2660 for (curr
= ldap_service_dn_head
;
2661 curr
!= NULL
&& *curr
->dn
!= '\0';
2664 #if defined (DEBUG_LDAP)
2665 log_info ("Searching for %s in LDAP tree %s", buf
, curr
->dn
);
2667 ret
= ldap_search_ext_s (ld
, curr
->dn
, LDAP_SCOPE_SUBTREE
, buf
, NULL
, 0,
2668 NULL
, NULL
, NULL
, 0, &res
);
2670 if(ret
== LDAP_SERVER_DOWN
)
2672 log_info ("LDAP server was down, trying to reconnect...");
2678 log_info ("LDAP reconnect failed - try again later...");
2682 ret
= ldap_search_ext_s (ld
, curr
->dn
, LDAP_SCOPE_SUBTREE
, buf
, NULL
,
2683 0, NULL
, NULL
, NULL
, 0, &res
);
2686 if (ret
== LDAP_SUCCESS
)
2688 ent
= ldap_first_entry (ld
, res
);
2689 #if defined (DEBUG_LDAP)
2691 log_info ("No host entry for %s in LDAP tree %s",
2695 while (ent
!= NULL
) {
2696 #if defined (DEBUG_LDAP)
2697 char *dn
= ldap_get_dn (ld
, ent
);
2700 log_info ("Found dhcpHWAddress LDAP entry %s", dn
);
2705 host
= (struct host_decl
*)0;
2706 status
= host_allocate (&host
, MDL
);
2707 if (status
!= ISC_R_SUCCESS
)
2709 log_fatal ("can't allocate host decl struct: %s",
2710 isc_result_totext (status
));
2715 host
->name
= ldap_get_host_name (ent
);
2716 if (host
->name
== NULL
)
2718 host_dereference (&host
, MDL
);
2723 if (!clone_group (&host
->group
, root_group
, MDL
))
2725 log_fatal ("can't clone group for host %s", host
->name
);
2726 host_dereference (&host
, MDL
);
2731 ldap_parse_options (ent
, host
->group
, HOST_DECL
, host
, NULL
);
2733 host
->n_ipaddr
= *hp
;
2735 ent
= ldap_next_entry (ld
, ent
);
2742 return (*hp
!= NULL
);
2752 if (ret
!= LDAP_NO_SUCH_OBJECT
&& ret
!= LDAP_SUCCESS
)
2754 log_error ("Cannot search for %s in LDAP tree %s: %s", buf
,
2755 curr
->dn
, ldap_err2string (ret
));
2759 #if defined (DEBUG_LDAP)
2762 log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
2763 ldap_err2string (ret
), buf
, curr
->dn
);
2774 find_subclass_in_ldap (struct class *class, struct class **newclass
,
2775 struct data_string
*data
)
2777 LDAPMessage
* res
, * ent
;
2778 int ret
, lease_limit
;
2779 isc_result_t status
;
2782 struct berval bv_class
;
2783 struct berval bv_cdata
;
2786 if (ldap_method
== LDAP_METHOD_STATIC
)
2794 hex_1
= print_hex_1 (data
->len
, data
->data
, 1024);
2797 /* result is a quotted not hex string: ldap escape the original string */
2798 if (_do_ldap_str2esc_filter_bv((const char*)data
->data
, data
->len
, &bv_cdata
) == NULL
)
2800 log_error ("Cannot escape ldap filter value %s: %m", hex_1
);
2805 if (_do_ldap_str2esc_filter_bv(class->name
, strlen (class->name
), &bv_class
) == NULL
)
2807 log_error ("Cannot escape ldap filter value %s: %m", class->name
);
2809 ber_memfree(bv_cdata
.bv_val
);
2813 snprintf (buf
, sizeof (buf
),
2814 "(&(objectClass=dhcpSubClass)(cn=%s)(dhcpClassData=%s))",
2815 (hex_1
== NULL
? bv_cdata
.bv_val
: hex_1
), bv_class
.bv_val
);
2818 ber_memfree(bv_cdata
.bv_val
);
2819 ber_memfree(bv_class
.bv_val
);
2821 #if defined (DEBUG_LDAP)
2822 log_info ("Searching LDAP for %s", buf
);
2826 for (curr
= ldap_service_dn_head
;
2827 curr
!= NULL
&& *curr
->dn
!= '\0';
2830 #if defined (DEBUG_LDAP)
2831 log_info ("Searching for %s in LDAP tree %s", buf
, curr
->dn
);
2833 ret
= ldap_search_ext_s (ld
, curr
->dn
, LDAP_SCOPE_SUBTREE
, buf
, NULL
, 0,
2834 NULL
, NULL
, NULL
, 0, &res
);
2836 if(ret
== LDAP_SERVER_DOWN
)
2838 log_info ("LDAP server was down, trying to reconnect...");
2845 log_info ("LDAP reconnect failed - try again later...");
2849 ret
= ldap_search_ext_s (ld
, curr
->dn
, LDAP_SCOPE_SUBTREE
, buf
,
2850 NULL
, 0, NULL
, NULL
, NULL
, 0, &res
);
2853 if (ret
== LDAP_SUCCESS
)
2855 if( (ent
= ldap_first_entry (ld
, res
)) != NULL
)
2856 break; /* search OK and have entry */
2858 #if defined (DEBUG_LDAP)
2859 log_info ("No subclass entry for %s in LDAP tree %s",
2876 if (ret
!= LDAP_NO_SUCH_OBJECT
&& ret
!= LDAP_SUCCESS
)
2878 log_error ("Cannot search for %s in LDAP tree %s: %s", buf
,
2879 curr
->dn
, ldap_err2string (ret
));
2883 #if defined (DEBUG_LDAP)
2886 log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
2887 ldap_err2string (ret
), buf
, curr
->dn
);
2895 #if defined (DEBUG_LDAP)
2896 char *dn
= ldap_get_dn (ld
, ent
);
2899 log_info ("Found subclass LDAP entry %s", dn
);
2904 status
= class_allocate (newclass
, MDL
);
2905 if (status
!= ISC_R_SUCCESS
)
2907 log_error ("Cannot allocate memory for a new class");
2912 group_reference (&(*newclass
)->group
, class->group
, MDL
);
2913 class_reference (&(*newclass
)->superclass
, class, MDL
);
2914 lease_limit
= ldap_parse_options (ent
, (*newclass
)->group
,
2915 CLASS_DECL
, NULL
, newclass
);
2916 if (lease_limit
== 0)
2917 (*newclass
)->lease_limit
= class->lease_limit
;
2919 class->lease_limit
= lease_limit
;
2921 if ((*newclass
)->lease_limit
)
2923 (*newclass
)->billed_leases
=
2924 dmalloc ((*newclass
)->lease_limit
* sizeof (struct lease
*), MDL
);
2925 if (!(*newclass
)->billed_leases
)
2927 log_error ("no memory for billing");
2928 class_dereference (newclass
, MDL
);
2932 memset ((*newclass
)->billed_leases
, 0,
2933 ((*newclass
)->lease_limit
* sizeof (struct lease
*)));
2936 data_string_copy (&(*newclass
)->hash_string
, data
, MDL
);
2942 if(res
) ldap_msgfree (res
);
2946 int find_client_in_ldap (struct host_decl
**hp
, struct packet
*packet
,
2947 struct option_state
*state
, const char *file
, int line
)
2949 LDAPMessage
* res
, * ent
;
2951 struct host_decl
* host
;
2952 isc_result_t status
;
2953 struct data_string client_id
;
2954 char buf
[1024], buf1
[1024];
2957 if (ldap_method
== LDAP_METHOD_STATIC
)
2965 memset(&client_id
, 0, sizeof(client_id
));
2966 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
)
2968 snprintf(buf
, sizeof(buf
),
2969 "(&(objectClass=dhcpHost)(dhcpClientId=%s))",
2970 print_hw_addr(0, client_id
.len
, client_id
.data
));
2972 /* log_info ("Searching LDAP for %s (%s)", buf, packet->interface->shared_network->name); */
2975 for (curr
= ldap_service_dn_head
;
2976 curr
!= NULL
&& *curr
->dn
!= '\0';
2979 snprintf(buf1
, sizeof(buf1
), "cn=%s,%s", packet
->interface
->shared_network
->name
, curr
->dn
);
2980 #if defined (DEBUG_LDAP)
2981 log_info ("Searching for %s in LDAP tree %s", buf
, buf1
);
2983 ret
= ldap_search_ext_s (ld
, buf1
, LDAP_SCOPE_SUBTREE
, buf
, NULL
, 0,
2984 NULL
, NULL
, NULL
, 0, &res
);
2986 if(ret
== LDAP_SERVER_DOWN
)
2988 log_info ("LDAP server was down, trying to reconnect...");
2995 log_info ("LDAP reconnect failed - try again later...");
2999 ret
= ldap_search_ext_s (ld
, buf1
, LDAP_SCOPE_SUBTREE
, buf
,
3000 NULL
, 0, NULL
, NULL
, NULL
, 0, &res
);
3003 if (ret
== LDAP_SUCCESS
)
3005 if( (ent
= ldap_first_entry (ld
, res
)) != NULL
) {
3006 log_info ("found entry in search %s", buf1
);
3007 break; /* search OK and have entry */
3010 #if defined (DEBUG_LDAP)
3011 log_info ("No subclass entry for %s in LDAP tree %s", buf
, curr
->dn
);
3027 if (ret
!= LDAP_NO_SUCH_OBJECT
&& ret
!= LDAP_SUCCESS
)
3029 log_error ("Cannot search for %s in LDAP tree %s: %s", buf
,
3030 curr
->dn
, ldap_err2string (ret
));
3036 log_info ("did not find: %s", buf
);
3043 #if defined (DEBUG_LDAP)
3044 log_info ("ldap_get_dn %s", curr
->dn
);
3045 char *dn
= ldap_get_dn (ld
, ent
);
3048 log_info ("Found subclass LDAP entry %s", dn
);
3051 log_info ("DN is null %s", dn
);
3055 host
= (struct host_decl
*)0;
3056 status
= host_allocate (&host
, MDL
);
3057 if (status
!= ISC_R_SUCCESS
)
3059 log_fatal ("can't allocate host decl struct: %s",
3060 isc_result_totext (status
));
3065 host
->name
= ldap_get_host_name (ent
);
3066 if (host
->name
== NULL
)
3068 host_dereference (&host
, MDL
);
3072 /* log_info ("Host name %s", host->name); */
3074 if (!clone_group (&host
->group
, root_group
, MDL
))
3076 log_fatal ("can't clone group for host %s", host
->name
);
3077 host_dereference (&host
, MDL
);
3082 ldap_parse_options (ent
, host
->group
, HOST_DECL
, host
, NULL
);
3090 log_info ("did not find clientid: %s", buf
);
3093 if(res
) ldap_msgfree (res
);
3098 #if defined(LDAP_USE_GSSAPI)
3100 _ldap_sasl_interact(LDAP
*ld
, unsigned flags
, void *defaults
, void *sin
)
3102 sasl_interact_t
*in
;
3103 struct ldap_sasl_instance
*ldap_inst
= defaults
;
3104 int ret
= LDAP_OTHER
;
3107 if (ld
== NULL
|| sin
== NULL
)
3108 return LDAP_PARAM_ERROR
;
3110 log_info("doing interactive bind");
3111 for (in
= sin
; in
!= NULL
&& in
->id
!= SASL_CB_LIST_END
; in
++) {
3114 log_info("got request for SASL_CB_USER %s", ldap_inst
->sasl_authz_id
);
3115 size
= strlen(ldap_inst
->sasl_authz_id
);
3116 in
->result
= ldap_inst
->sasl_authz_id
;
3120 case SASL_CB_GETREALM
:
3121 log_info("got request for SASL_CB_GETREALM %s", ldap_inst
->sasl_realm
);
3122 size
= strlen(ldap_inst
->sasl_realm
);
3123 in
->result
= ldap_inst
->sasl_realm
;
3127 case SASL_CB_AUTHNAME
:
3128 log_info("got request for SASL_CB_AUTHNAME %s", ldap_inst
->sasl_authc_id
);
3129 size
= strlen(ldap_inst
->sasl_authc_id
);
3130 in
->result
= ldap_inst
->sasl_authc_id
;
3135 log_info("got request for SASL_CB_PASS %s", ldap_inst
->sasl_password
);
3136 size
= strlen(ldap_inst
->sasl_password
);
3137 in
->result
= ldap_inst
->sasl_password
;
3152 #endif /* LDAP_USE_GSSAPI */