3 Routines for reading the configuration from LDAP */
6 * Copyright (c) 2010-2019 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
) &&
1153 ret
= getULong(db
.data
);
1156 data_string_forget (&db
, MDL
);
1164 _do_lookup_dhcp_enum_option (struct option_state
*options
, int option_name
)
1166 struct option_cache
*oc
;
1167 struct data_string db
;
1170 memset (&db
, 0, sizeof (db
));
1171 oc
= lookup_option (&server_universe
, options
, option_name
);
1173 evaluate_option_cache (&db
, (struct packet
*) NULL
,
1174 (struct lease
*) NULL
,
1175 (struct client_state
*) NULL
, options
,
1176 (struct option_state
*) NULL
,
1177 &global_scope
, oc
, MDL
) &&
1178 db
.data
!= NULL
&& *db
.data
!= '\0')
1183 log_fatal ("invalid option name %d", option_name
);
1185 data_string_forget (&db
, MDL
);
1194 ldap_rebind_cb (LDAP
*ld
, LDAP_CONST
char *url
, ber_tag_t request
, ber_int_t msgid
, void *parms
)
1197 LDAPURLDesc
*ldapurl
= NULL
;
1199 struct berval creds
;
1201 log_info("LDAP rebind to '%s'", url
);
1202 if ((ret
= ldap_url_parse(url
, &ldapurl
)) != LDAP_SUCCESS
)
1204 log_error ("Error: Can not parse ldap rebind url '%s': %s",
1205 url
, ldap_err2string(ret
));
1210 #if defined (LDAP_USE_SSL)
1211 if (strcasecmp(ldapurl
->lud_scheme
, "ldaps") == 0)
1213 int opt
= LDAP_OPT_X_TLS_HARD
;
1214 if ((ret
= ldap_set_option (ld
, LDAP_OPT_X_TLS
, &opt
)) != LDAP_SUCCESS
)
1216 log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
1217 ldapurl
->lud_host
, ldapurl
->lud_port
, ldap_err2string (ret
));
1218 ldap_free_urldesc(ldapurl
);
1223 log_info ("LDAPS session successfully enabled to %s", ldap_server
);
1227 if (strcasecmp(ldapurl
->lud_scheme
, "ldap") == 0 &&
1228 ldap_use_ssl
!= LDAP_SSL_OFF
)
1230 if ((ret
= ldap_start_tls_s (ld
, NULL
, NULL
)) != LDAP_SUCCESS
)
1232 log_error ("Error: Cannot start TLS session to %s:%d: %s",
1233 ldapurl
->lud_host
, ldapurl
->lud_port
, ldap_err2string (ret
));
1234 ldap_free_urldesc(ldapurl
);
1239 log_info ("TLS session successfully started to %s:%d",
1240 ldapurl
->lud_host
, ldapurl
->lud_port
);
1245 #if defined(LDAP_USE_GSSAPI)
1246 if (ldap_gssapi_principal
!= NULL
) {
1247 krb5_get_tgt(ldap_gssapi_principal
, ldap_gssapi_keytab
);
1248 if ((ret
= ldap_sasl_interactive_bind_s(ld
, NULL
, ldap_sasl_inst
->sasl_mech
,
1249 NULL
, NULL
, LDAP_SASL_AUTOMATIC
,
1250 _ldap_sasl_interact
, ldap_sasl_inst
)
1253 log_error ("Error: Cannot SASL bind to ldap server %s:%d: %s",
1254 ldap_server
, ldap_port
, ldap_err2string (ret
));
1256 ldap_get_option( ld
, LDAP_OPT_DIAGNOSTIC_MESSAGE
, (void*)&msg
);
1257 log_error ("\tAdditional info: %s", msg
);
1262 ldap_free_urldesc(ldapurl
);
1267 if (ldap_username
!= NULL
&& *ldap_username
!= '\0' && ldap_password
!= NULL
)
1269 who
= ldap_username
;
1270 creds
.bv_val
= strdup(ldap_password
);
1271 if (creds
.bv_val
== NULL
)
1272 log_fatal ("Error: Unable to allocate memory to duplicate ldap_password");
1274 creds
.bv_len
= strlen(ldap_password
);
1276 if ((ret
= ldap_sasl_bind_s (ld
, who
, LDAP_SASL_SIMPLE
, &creds
,
1277 NULL
, NULL
, NULL
)) != LDAP_SUCCESS
)
1279 log_error ("Error: Cannot login into ldap server %s:%d: %s",
1280 ldapurl
->lud_host
, ldapurl
->lud_port
, ldap_err2string (ret
));
1287 ldap_free_urldesc(ldapurl
);
1292 _do_ldap_retry(int ret
, const char *server
, int port
)
1294 static int inform
= 1;
1296 if (ldap_enable_retry
> 0 && ret
== LDAP_SERVER_DOWN
&& ldap_init_retry
> 0)
1298 if (inform
|| (ldap_init_retry
% 10) == 0)
1301 log_info ("Can't contact LDAP server %s:%d: retrying for %d sec",
1302 server
, port
, ldap_init_retry
);
1305 return ldap_init_retry
--;
1310 static struct berval
*
1311 _do_ldap_str2esc_filter_bv(const char *str
, ber_len_t len
, struct berval
*bv_o
)
1315 if (!str
|| !bv_o
|| (ber_str2bv(str
, len
, 0, &bv_i
) == NULL
) ||
1316 (ldap_bv2escaped_filter_value(&bv_i
, bv_o
) != 0))
1324 struct option_state
*options
;
1327 struct berval creds
;
1328 #if defined(LDAP_USE_GSSAPI)
1329 char *gssapi_realm
= NULL
;
1330 char *gssapi_user
= NULL
;
1331 char *running
= NULL
;
1332 const char *gssapi_delim
= "@";
1338 if (ldap_server
== NULL
)
1341 option_state_allocate (&options
, MDL
);
1343 execute_statements_in_scope (NULL
, NULL
, NULL
, NULL
, NULL
,
1344 options
, &global_scope
, root_group
,
1347 ldap_server
= _do_lookup_dhcp_string_option (options
, SV_LDAP_SERVER
);
1348 ldap_dhcp_server_cn
= _do_lookup_dhcp_string_option (options
,
1349 SV_LDAP_DHCP_SERVER_CN
);
1350 ldap_port
= _do_lookup_dhcp_int_option (options
, SV_LDAP_PORT
);
1351 ldap_base_dn
= _do_lookup_dhcp_string_option (options
, SV_LDAP_BASE_DN
);
1352 ldap_method
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_METHOD
);
1353 ldap_debug_file
= _do_lookup_dhcp_string_option (options
,
1354 SV_LDAP_DEBUG_FILE
);
1355 ldap_referrals
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_REFERRALS
);
1356 ldap_init_retry
= _do_lookup_dhcp_int_option (options
, SV_LDAP_INIT_RETRY
);
1358 #if defined (LDAP_USE_SSL)
1359 ldap_use_ssl
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_SSL
);
1360 if( ldap_use_ssl
!= LDAP_SSL_OFF
)
1362 ldap_tls_reqcert
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_TLS_REQCERT
);
1363 ldap_tls_ca_file
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_CA_FILE
);
1364 ldap_tls_ca_dir
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_CA_DIR
);
1365 ldap_tls_cert
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_CERT
);
1366 ldap_tls_key
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_KEY
);
1367 ldap_tls_crlcheck
= _do_lookup_dhcp_enum_option (options
, SV_LDAP_TLS_CRLCHECK
);
1368 ldap_tls_ciphers
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_CIPHERS
);
1369 ldap_tls_randfile
= _do_lookup_dhcp_string_option (options
, SV_LDAP_TLS_RANDFILE
);
1373 #if defined (LDAP_USE_GSSAPI)
1374 ldap_gssapi_principal
= _do_lookup_dhcp_string_option (options
,
1375 SV_LDAP_GSSAPI_PRINCIPAL
);
1377 if (ldap_gssapi_principal
== NULL
) {
1378 log_info("ldap-gssapi-principal is not set,"
1379 "GSSAPI Authentication for LDAP will not be used");
1381 ldap_gssapi_keytab
= _do_lookup_dhcp_string_option (options
,
1382 SV_LDAP_GSSAPI_KEYTAB
);
1383 if (ldap_gssapi_keytab
== NULL
) {
1384 log_fatal("ldap-gssapi-keytab must be specified");
1387 running
= strdup(ldap_gssapi_principal
);
1388 if (running
== NULL
)
1389 log_fatal("Could not allocate memory to duplicate gssapi principal");
1391 gssapi_user
= strtok(running
, gssapi_delim
);
1392 if (!gssapi_user
|| strlen(gssapi_user
) == 0) {
1393 log_fatal ("GSSAPI principal must specify user: user@realm");
1396 gssapi_realm
= strtok(NULL
, gssapi_delim
);
1397 if (!gssapi_realm
|| strlen(gssapi_realm
) == 0) {
1398 log_fatal ("GSSAPI principal must specify realm: user@realm");
1401 ldap_sasl_inst
= malloc(sizeof(struct ldap_sasl_instance
));
1402 if (ldap_sasl_inst
== NULL
)
1403 log_fatal("Could not allocate memory for sasl instance! Can not run!");
1405 ldap_sasl_inst
->sasl_mech
= ber_strdup("GSSAPI");
1406 if (ldap_sasl_inst
->sasl_mech
== NULL
)
1407 log_fatal("Could not allocate memory to duplicate gssapi mechanism");
1409 ldap_sasl_inst
->sasl_realm
= ber_strdup(gssapi_realm
);
1410 if (ldap_sasl_inst
->sasl_realm
== NULL
)
1411 log_fatal("Could not allocate memory to duplicate gssapi realm");
1413 ldap_sasl_inst
->sasl_authz_id
= ber_strdup(gssapi_user
);
1414 if (ldap_sasl_inst
->sasl_authz_id
== NULL
)
1415 log_fatal("Could not allocate memory to duplicate gssapi user");
1417 ldap_sasl_inst
->sasl_authc_id
= NULL
;
1418 ldap_sasl_inst
->sasl_password
= NULL
; //"" before
1423 #if defined (LDAP_CASA_AUTH)
1424 if (!load_uname_pwd_from_miCASA(&ldap_username
,&ldap_password
))
1426 #if defined (DEBUG_LDAP)
1427 log_info ("Authentication credential taken from file");
1431 ldap_username
= _do_lookup_dhcp_string_option (options
, SV_LDAP_USERNAME
);
1432 ldap_password
= _do_lookup_dhcp_string_option (options
, SV_LDAP_PASSWORD
);
1434 #if defined (LDAP_CASA_AUTH)
1438 option_state_dereference (&options
, MDL
);
1441 if (ldap_server
== NULL
|| ldap_base_dn
== NULL
)
1443 log_info ("Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not specified in the config file");
1444 ldap_method
= LDAP_METHOD_STATIC
;
1448 if (ldap_debug_file
!= NULL
&& ldap_debug_fd
== -1)
1450 if ((ldap_debug_fd
= open (ldap_debug_file
, O_CREAT
| O_TRUNC
| O_WRONLY
,
1451 S_IRUSR
| S_IWUSR
)) < 0)
1452 log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file
,
1456 #if defined (DEBUG_LDAP)
1457 log_info ("Connecting to LDAP server %s:%d", ldap_server
, ldap_port
);
1460 #if defined (LDAP_USE_SSL)
1461 if (ldap_use_ssl
== -1)
1464 ** There was no "ldap-ssl" option in dhcpd.conf (also not "off").
1465 ** Let's try, if we can use an anonymous TLS session without to
1466 ** verify the server certificate -- if not continue without TLS.
1468 int opt
= LDAP_OPT_X_TLS_ALLOW
;
1469 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_REQUIRE_CERT
,
1470 &opt
)) != LDAP_SUCCESS
)
1472 log_error ("Warning: Cannot set LDAP TLS require cert option to 'allow': %s",
1473 ldap_err2string (ret
));
1477 if (ldap_use_ssl
!= LDAP_SSL_OFF
)
1479 if (ldap_tls_reqcert
!= -1)
1481 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_REQUIRE_CERT
,
1482 &ldap_tls_reqcert
)) != LDAP_SUCCESS
)
1484 log_error ("Cannot set LDAP TLS require cert option: %s",
1485 ldap_err2string (ret
));
1489 if( ldap_tls_ca_file
!= NULL
)
1491 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CACERTFILE
,
1492 ldap_tls_ca_file
)) != LDAP_SUCCESS
)
1494 log_error ("Cannot set LDAP TLS CA certificate file %s: %s",
1495 ldap_tls_ca_file
, ldap_err2string (ret
));
1498 if( ldap_tls_ca_dir
!= NULL
)
1500 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CACERTDIR
,
1501 ldap_tls_ca_dir
)) != LDAP_SUCCESS
)
1503 log_error ("Cannot set LDAP TLS CA certificate dir %s: %s",
1504 ldap_tls_ca_dir
, ldap_err2string (ret
));
1507 if( ldap_tls_cert
!= NULL
)
1509 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CERTFILE
,
1510 ldap_tls_cert
)) != LDAP_SUCCESS
)
1512 log_error ("Cannot set LDAP TLS client certificate file %s: %s",
1513 ldap_tls_cert
, ldap_err2string (ret
));
1516 if( ldap_tls_key
!= NULL
)
1518 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_KEYFILE
,
1519 ldap_tls_key
)) != LDAP_SUCCESS
)
1521 log_error ("Cannot set LDAP TLS certificate key file %s: %s",
1522 ldap_tls_key
, ldap_err2string (ret
));
1525 if( ldap_tls_crlcheck
!= -1)
1527 int opt
= ldap_tls_crlcheck
;
1528 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CRLCHECK
,
1529 &opt
)) != LDAP_SUCCESS
)
1531 log_error ("Cannot set LDAP TLS crl check option: %s",
1532 ldap_err2string (ret
));
1535 if( ldap_tls_ciphers
!= NULL
)
1537 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_CIPHER_SUITE
,
1538 ldap_tls_ciphers
)) != LDAP_SUCCESS
)
1540 log_error ("Cannot set LDAP TLS cipher suite %s: %s",
1541 ldap_tls_ciphers
, ldap_err2string (ret
));
1544 if( ldap_tls_randfile
!= NULL
)
1546 if ((ret
= ldap_set_option (NULL
, LDAP_OPT_X_TLS_RANDOM_FILE
,
1547 ldap_tls_randfile
)) != LDAP_SUCCESS
)
1549 log_error ("Cannot set LDAP TLS random file %s: %s",
1550 ldap_tls_randfile
, ldap_err2string (ret
));
1556 /* enough for 'ldap://+ + hostname + ':' + port number */
1557 uri
= malloc(strlen(ldap_server
) + 16);
1560 log_error ("Cannot build ldap init URI %s:%d", ldap_server
, ldap_port
);
1564 sprintf(uri
, "ldap://%s:%d", ldap_server
, ldap_port
);
1565 ldap_initialize(&ld
, uri
);
1569 log_error ("Cannot init ldap session to %s:%d", ldap_server
, ldap_port
);
1575 version
= LDAP_VERSION3
;
1576 if ((ret
= ldap_set_option (ld
, LDAP_OPT_PROTOCOL_VERSION
, &version
)) != LDAP_OPT_SUCCESS
)
1578 log_error ("Cannot set LDAP version to %d: %s", version
,
1579 ldap_err2string (ret
));
1582 if (ldap_referrals
!= -1)
1584 if ((ret
= ldap_set_option (ld
, LDAP_OPT_REFERRALS
, ldap_referrals
?
1585 LDAP_OPT_ON
: LDAP_OPT_OFF
)) != LDAP_OPT_SUCCESS
)
1587 log_error ("Cannot %s LDAP referrals option: %s",
1588 (ldap_referrals
? "enable" : "disable"),
1589 ldap_err2string (ret
));
1593 if ((ret
= ldap_set_rebind_proc(ld
, ldap_rebind_cb
, NULL
)) != LDAP_SUCCESS
)
1595 log_error ("Warning: Cannot set ldap rebind procedure: %s",
1596 ldap_err2string (ret
));
1599 #if defined (LDAP_USE_SSL)
1600 if (ldap_use_ssl
== LDAP_SSL_LDAPS
||
1601 (ldap_use_ssl
== LDAP_SSL_ON
&& ldap_port
== LDAPS_PORT
))
1603 int opt
= LDAP_OPT_X_TLS_HARD
;
1604 if ((ret
= ldap_set_option (ld
, LDAP_OPT_X_TLS
, &opt
)) != LDAP_SUCCESS
)
1606 log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
1607 ldap_server
, ldap_port
, ldap_err2string (ret
));
1613 log_info ("LDAPS session successfully enabled to %s:%d",
1614 ldap_server
, ldap_port
);
1617 else if (ldap_use_ssl
!= LDAP_SSL_OFF
)
1621 ret
= ldap_start_tls_s (ld
, NULL
, NULL
);
1623 while(_do_ldap_retry(ret
, ldap_server
, ldap_port
) > 0);
1625 if (ret
!= LDAP_SUCCESS
)
1627 log_error ("Error: Cannot start TLS session to %s:%d: %s",
1628 ldap_server
, ldap_port
, ldap_err2string (ret
));
1634 log_info ("TLS session successfully started to %s:%d",
1635 ldap_server
, ldap_port
);
1640 #if defined(LDAP_USE_GSSAPI)
1641 if (ldap_gssapi_principal
!= NULL
) {
1642 krb5_get_tgt(ldap_gssapi_principal
, ldap_gssapi_keytab
);
1643 if ((ret
= ldap_sasl_interactive_bind_s(ld
, NULL
, ldap_sasl_inst
->sasl_mech
,
1644 NULL
, NULL
, LDAP_SASL_AUTOMATIC
,
1645 _ldap_sasl_interact
, ldap_sasl_inst
)
1648 log_error ("Error: Cannot SASL bind to ldap server %s:%d: %s",
1649 ldap_server
, ldap_port
, ldap_err2string (ret
));
1651 ldap_get_option( ld
, LDAP_OPT_DIAGNOSTIC_MESSAGE
, (void*)&msg
);
1652 log_error ("\tAdditional info: %s", msg
);
1660 if (ldap_username
!= NULL
&& *ldap_username
!= '\0' && ldap_password
!= NULL
)
1662 creds
.bv_val
= strdup(ldap_password
);
1663 if (creds
.bv_val
== NULL
)
1664 log_fatal ("Error: Unable to allocate memory to duplicate ldap_password");
1666 creds
.bv_len
= strlen(ldap_password
);
1670 ret
= ldap_sasl_bind_s (ld
, ldap_username
, LDAP_SASL_SIMPLE
,
1671 &creds
, NULL
, NULL
, NULL
);
1673 while(_do_ldap_retry(ret
, ldap_server
, ldap_port
) > 0);
1676 if (ret
!= LDAP_SUCCESS
)
1678 log_error ("Error: Cannot login into ldap server %s:%d: %s",
1679 ldap_server
, ldap_port
, ldap_err2string (ret
));
1685 #if defined (DEBUG_LDAP)
1686 log_info ("Successfully logged into LDAP server %s", ldap_server
);
1692 parse_external_dns (LDAPMessage
* ent
)
1694 char *search
[] = {"dhcpOptionsDN", "dhcpSharedNetworkDN", "dhcpSubnetDN",
1695 "dhcpGroupDN", "dhcpHostDN", "dhcpClassesDN",
1696 "dhcpPoolDN", "dhcpZoneDN", "dhcpFailOverPeerDN", NULL
};
1698 /* TODO: dhcpKeyDN can't be added. It is referenced in dhcpDnsZone to
1699 retrive the key name (cn). Adding keyDN will reflect adding a key
1700 declaration inside the zone configuration.
1702 dhcpSubClassesDN cant be added. It is also similar to the above.
1703 Needs schema change.
1705 LDAPMessage
* newres
, * newent
;
1706 struct berval
**tempbv
;
1708 #if defined (DEBUG_LDAP)
1711 dn
= ldap_get_dn (ld
, ent
);
1714 log_info ("Parsing external DNs for '%s'", dn
);
1724 for (i
=0; search
[i
] != NULL
; i
++)
1726 if ((tempbv
= ldap_get_values_len (ld
, ent
, search
[i
])) == NULL
)
1729 for (j
=0; tempbv
[j
] != NULL
; j
++)
1731 if (*tempbv
[j
]->bv_val
== '\0')
1734 if ((ret
= ldap_search_ext_s(ld
, tempbv
[j
]->bv_val
, LDAP_SCOPE_BASE
,
1735 "objectClass=*", NULL
, 0, NULL
,
1736 NULL
, NULL
, 0, &newres
)) != LDAP_SUCCESS
)
1738 ldap_value_free_len (tempbv
);
1743 #if defined (DEBUG_LDAP)
1744 log_info ("Adding contents of subtree '%s' to config stack from '%s' reference", tempbv
[j
]->bv_val
, search
[i
]);
1746 for (newent
= ldap_first_entry (ld
, newres
);
1748 newent
= ldap_next_entry (ld
, newent
))
1750 #if defined (DEBUG_LDAP)
1751 dn
= ldap_get_dn (ld
, newent
);
1754 log_info ("Adding LDAP result set starting with '%s' to config stack", dn
);
1759 add_to_config_stack (newres
, newent
);
1760 /* don't free newres here */
1764 ldap_value_free_len (tempbv
);
1770 free_stack_entry (struct ldap_config_stack
*item
)
1772 struct ldap_config_stack
*look_ahead_pointer
= item
;
1773 int may_free_msg
= 1;
1775 while (look_ahead_pointer
->next
!= NULL
)
1777 look_ahead_pointer
= look_ahead_pointer
->next
;
1778 if (look_ahead_pointer
->res
== item
->res
)
1786 ldap_msgfree (item
->res
);
1793 next_ldap_entry (struct parse
*cfile
)
1795 struct ldap_config_stack
*temp_stack
;
1797 if (ldap_stack
!= NULL
&& ldap_stack
->close_brace
)
1799 x_parser_strcat (cfile
, "}\n");
1800 ldap_stack
->close_brace
= 0;
1803 while (ldap_stack
!= NULL
&&
1804 (ldap_stack
->ldent
== NULL
|| ( ldap_stack
->processed
&&
1805 (ldap_stack
->ldent
= ldap_next_entry (ld
, ldap_stack
->ldent
)) == NULL
)))
1807 if (ldap_stack
->close_brace
)
1809 x_parser_strcat (cfile
, "}\n");
1810 ldap_stack
->close_brace
= 0;
1813 temp_stack
= ldap_stack
;
1814 ldap_stack
= ldap_stack
->next
;
1815 free_stack_entry (temp_stack
);
1818 if (ldap_stack
!= NULL
&& ldap_stack
->close_brace
)
1820 x_parser_strcat (cfile
, "}\n");
1821 ldap_stack
->close_brace
= 0;
1827 check_statement_end (const char *statement
)
1831 if (statement
== NULL
|| *statement
== '\0')
1835 ** check if it ends with "}", e.g.:
1836 ** "zone my.domain. { ... }"
1837 ** optionally followed by spaces
1839 ptr
= strrchr (statement
, '}');
1842 /* skip following white-spaces */
1843 for (++ptr
; isspace ((int)*ptr
); ptr
++);
1845 /* check if we reached the end */
1847 return ('}'); /* yes, block end */
1853 ** this should not happen, but...
1854 ** check if it ends with ";", e.g.:
1856 ** optionally followed by spaces
1858 ptr
= strrchr (statement
, ';');
1861 /* skip following white-spaces */
1862 for (++ptr
; isspace ((int)*ptr
); ptr
++);
1864 /* check if we reached the end */
1866 return (';'); /* ends with a ; */
1876 ldap_parse_entry_options (LDAPMessage
*ent
, struct parse
*cfile
,
1879 struct berval
**tempbv
;
1882 if (ent
== NULL
|| cfile
== NULL
)
1883 return (ISC_R_FAILURE
);
1885 if ((tempbv
= ldap_get_values_len (ld
, ent
, "dhcpStatements")) != NULL
)
1887 for (i
=0; tempbv
[i
] != NULL
; i
++)
1889 if (lease_limit
!= NULL
&&
1890 strncasecmp ("lease limit ", tempbv
[i
]->bv_val
, 12) == 0)
1892 *lease_limit
= (int) strtol ((tempbv
[i
]->bv_val
) + 12, NULL
, 10);
1896 x_parser_strcat (cfile
, tempbv
[i
]->bv_val
);
1898 switch((int) check_statement_end (tempbv
[i
]->bv_val
))
1902 x_parser_strcat (cfile
, "\n");
1905 x_parser_strcat (cfile
, ";\n");
1909 ldap_value_free_len (tempbv
);
1912 if ((tempbv
= ldap_get_values_len (ld
, ent
, "dhcpOption")) != NULL
)
1914 for (i
=0; tempbv
[i
] != NULL
; i
++)
1916 x_parser_strcat (cfile
, "option ");
1917 x_parser_strcat (cfile
, tempbv
[i
]->bv_val
);
1918 switch ((int) check_statement_end (tempbv
[i
]->bv_val
))
1921 x_parser_strcat (cfile
, "\n");
1924 x_parser_strcat (cfile
, ";\n");
1928 ldap_value_free_len (tempbv
);
1931 return (ISC_R_SUCCESS
);
1936 ldap_generate_config_string (struct parse
*cfile
)
1938 struct berval
**objectClass
;
1940 struct ldap_config_stack
*entry
;
1941 LDAPMessage
* ent
, * res
, *entfirst
, *resfirst
;
1942 int i
, ignore
, found
;
1943 int ret
, parsedn
= 1;
1944 size_t len
= cfile
->buflen
;
1952 if ((objectClass
= ldap_get_values_len (ld
, entry
->ldent
,
1953 "objectClass")) == NULL
)
1956 entry
->processed
= 1;
1959 for (i
=0; objectClass
[i
] != NULL
; i
++)
1961 if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpSharedNetwork") == 0)
1962 ldap_parse_shared_network (entry
, cfile
);
1963 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpClass") == 0)
1964 ldap_parse_class (entry
, cfile
);
1965 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpSubnet") == 0)
1966 ldap_parse_subnet (entry
, cfile
);
1967 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpSubnet6") == 0)
1968 ldap_parse_subnet6 (entry
, cfile
);
1969 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpPool") == 0)
1970 ldap_parse_pool (entry
, cfile
);
1971 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpPool6") == 0)
1972 ldap_parse_pool6 (entry
, cfile
);
1973 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpGroup") == 0)
1974 ldap_parse_group (entry
, cfile
);
1975 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpTSigKey") == 0)
1976 ldap_parse_key (entry
, cfile
);
1977 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpDnsZone") == 0)
1978 ldap_parse_zone (entry
, cfile
);
1979 #if defined(HAVE_IFADDRS_H)
1980 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpFailOverPeer") == 0)
1981 ldap_parse_failover (entry
, cfile
);
1983 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpHost") == 0)
1985 if (ldap_method
== LDAP_METHOD_STATIC
)
1986 ldap_parse_host (entry
, cfile
);
1993 else if (strcasecmp (objectClass
[i
]->bv_val
, "dhcpSubClass") == 0)
1995 if (ldap_method
== LDAP_METHOD_STATIC
)
1996 ldap_parse_subclass (entry
, cfile
);
2006 if (found
&& x_parser_length(cfile
) <= len
)
2013 ldap_value_free_len (objectClass
);
2017 next_ldap_entry (cfile
);
2021 ldap_parse_entry_options(entry
->ldent
, cfile
, NULL
);
2023 dn
= ldap_get_dn (ld
, entry
->ldent
);
2029 #if defined(DEBUG_LDAP)
2030 log_info ("Found LDAP entry '%s'", dn
);
2033 if ((ret
= ldap_search_ext_s (ld
, dn
, LDAP_SCOPE_ONELEVEL
,
2034 "(!(|(|(objectClass=dhcpTSigKey)(objectClass=dhcpClass)) (objectClass=dhcpFailOverPeer)))",
2035 NULL
, 0, NULL
, NULL
,
2036 NULL
, 0, &res
)) != LDAP_SUCCESS
)
2044 if ((ret
= ldap_search_ext_s (ld
, dn
, LDAP_SCOPE_ONELEVEL
,
2045 "(|(|(objectClass=dhcpTSigKey)(objectClass=dhcpClass)) (objectClass=dhcpFailOverPeer))",
2046 NULL
, 0, NULL
, NULL
,
2047 NULL
, 0, &resfirst
)) != LDAP_SUCCESS
)
2058 ent
= ldap_first_entry(ld
, res
);
2059 entfirst
= ldap_first_entry(ld
, resfirst
);
2061 if (ent
== NULL
&& entfirst
== NULL
)
2063 parse_external_dns (entry
->ldent
);
2064 next_ldap_entry (cfile
);
2069 add_to_config_stack (res
, ent
);
2070 parse_external_dns (entry
->ldent
);
2076 if (entfirst
!= NULL
)
2078 add_to_config_stack (resfirst
, entfirst
);
2080 parse_external_dns (entry
->ldent
);
2084 ldap_msgfree (resfirst
);
2089 ldap_close_debug_fd()
2091 if (ldap_debug_fd
!= -1)
2093 close (ldap_debug_fd
);
2100 ldap_write_debug (const void *buff
, size_t size
)
2102 if (ldap_debug_fd
!= -1)
2104 if (write (ldap_debug_fd
, buff
, size
) < 0)
2106 log_error ("Error writing to LDAP debug file %s: %s."
2107 " Disabling log file.", ldap_debug_file
,
2109 ldap_close_debug_fd();
2115 ldap_read_function (struct parse
*cfile
)
2119 /* append when in saved state */
2120 if (cfile
->saved_state
== NULL
)
2122 cfile
->inbuf
[0] = '\0';
2126 len
= cfile
->buflen
;
2128 while (ldap_stack
!= NULL
&& x_parser_length(cfile
) <= len
)
2129 ldap_generate_config_string (cfile
);
2131 if (x_parser_length(cfile
) <= len
&& ldap_stack
== NULL
)
2134 if (cfile
->buflen
> len
)
2135 ldap_write_debug (cfile
->inbuf
+ len
, cfile
->buflen
- len
);
2136 #if defined (DEBUG_LDAP)
2137 log_info ("Sending config portion '%s'", cfile
->inbuf
+ len
);
2140 return (cfile
->inbuf
[cfile
->bufix
++]);
2145 ldap_get_host_name (LDAPMessage
* ent
)
2147 struct berval
**name
;
2151 if ((name
= ldap_get_values_len (ld
, ent
, "cn")) == NULL
|| name
[0] == NULL
)
2154 ldap_value_free_len (name
);
2156 #if defined (DEBUG_LDAP)
2157 ret
= ldap_get_dn (ld
, ent
);
2160 log_info ("Cannot get cn attribute for LDAP entry %s", ret
);
2167 ret
= dmalloc (strlen (name
[0]->bv_val
) + 1, MDL
);
2168 strcpy (ret
, name
[0]->bv_val
);
2169 ldap_value_free_len (name
);
2176 ldap_read_config (void)
2178 LDAPMessage
* ldres
, * hostres
, * ent
, * hostent
;
2179 char hfilter
[1024], sfilter
[1024], fqdn
[257];
2181 ldap_dn_node
*curr
= NULL
;
2182 struct parse
*cfile
;
2183 struct utsname unme
;
2187 struct berval
**tempbv
= NULL
;
2188 struct berval bv_o
[2];
2190 cfile
= x_parser_init("LDAP");
2192 return (ISC_R_NOMEMORY
);
2194 ldap_enable_retry
= 1;
2197 ldap_enable_retry
= 0;
2201 x_parser_free(&cfile
);
2202 return (ldap_server
== NULL
? ISC_R_SUCCESS
: ISC_R_FAILURE
);
2206 if (ldap_dhcp_server_cn
!= NULL
)
2208 if (_do_ldap_str2esc_filter_bv(ldap_dhcp_server_cn
, 0, &bv_o
[0]) == NULL
)
2210 log_error ("Cannot escape ldap filter value %s: %m", ldap_dhcp_server_cn
);
2211 x_parser_free(&cfile
);
2212 return (ISC_R_FAILURE
);
2215 snprintf (hfilter
, sizeof (hfilter
),
2216 "(&(objectClass=dhcpServer)(cn=%s))", bv_o
[0].bv_val
);
2218 ber_memfree(bv_o
[0].bv_val
);
2222 if (_do_ldap_str2esc_filter_bv(unme
.nodename
, 0, &bv_o
[0]) == NULL
)
2224 log_error ("Cannot escape ldap filter value %s: %m", unme
.nodename
);
2225 x_parser_free(&cfile
);
2226 return (ISC_R_FAILURE
);
2230 if(0 == get_host_entry(fqdn
, sizeof(fqdn
), NULL
, 0))
2232 if (_do_ldap_str2esc_filter_bv(fqdn
, 0, &bv_o
[1]) == NULL
)
2234 log_error ("Cannot escape ldap filter value %s: %m", fqdn
);
2235 ber_memfree(bv_o
[0].bv_val
);
2236 x_parser_free(&cfile
);
2237 return (ISC_R_FAILURE
);
2241 // If we have fqdn and it isn't the same as nodename, use it in filter
2242 // otherwise just use nodename
2243 if ((*fqdn
) && (strcmp(unme
.nodename
, fqdn
))) {
2244 snprintf (hfilter
, sizeof (hfilter
),
2245 "(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))",
2246 bv_o
[0].bv_val
, bv_o
[1].bv_val
);
2248 ber_memfree(bv_o
[1].bv_val
);
2252 snprintf (hfilter
, sizeof (hfilter
),
2253 "(&(objectClass=dhcpServer)(cn=%s))",
2257 ber_memfree(bv_o
[0].bv_val
);
2260 ldap_enable_retry
= 1;
2264 ret
= ldap_search_ext_s (ld
, ldap_base_dn
, LDAP_SCOPE_SUBTREE
,
2265 hfilter
, NULL
, 0, NULL
, NULL
, NULL
, 0,
2268 while(_do_ldap_retry(ret
, ldap_server
, ldap_port
) > 0);
2269 ldap_enable_retry
= 0;
2271 if(ret
!= LDAP_SUCCESS
)
2273 log_error ("Cannot find host LDAP entry %s %s",
2274 ((ldap_dhcp_server_cn
== NULL
)?(unme
.nodename
):(ldap_dhcp_server_cn
)), hfilter
);
2276 ldap_msgfree (hostres
);
2278 x_parser_free(&cfile
);
2279 return (ISC_R_FAILURE
);
2282 if ((hostent
= ldap_first_entry (ld
, hostres
)) == NULL
)
2284 log_error ("Error: Cannot find LDAP entry matching %s", hfilter
);
2285 ldap_msgfree (hostres
);
2287 x_parser_free(&cfile
);
2288 return (ISC_R_FAILURE
);
2291 hostdn
= ldap_get_dn (ld
, hostent
);
2292 #if defined(DEBUG_LDAP)
2294 log_info ("Found dhcpServer LDAP entry '%s'", hostdn
);
2297 if (hostdn
== NULL
||
2298 (tempbv
= ldap_get_values_len (ld
, hostent
, "dhcpServiceDN")) == NULL
||
2301 log_error ("Error: No dhcp service is associated with the server %s %s",
2302 (hostdn
? "dn" : "name"), (hostdn
? hostdn
:
2303 (ldap_dhcp_server_cn
? ldap_dhcp_server_cn
: unme
.nodename
)));
2306 ldap_value_free_len (tempbv
);
2309 ldap_memfree (hostdn
);
2310 ldap_msgfree (hostres
);
2312 x_parser_free(&cfile
);
2313 return (ISC_R_FAILURE
);
2316 #if defined(DEBUG_LDAP)
2317 log_info ("LDAP: Parsing dhcpServer options '%s' ...", hostdn
);
2320 res
= ldap_parse_entry_options(hostent
, cfile
, NULL
);
2321 if (res
!= ISC_R_SUCCESS
)
2323 ldap_value_free_len (tempbv
);
2324 ldap_msgfree (hostres
);
2325 ldap_memfree (hostdn
);
2327 x_parser_free(&cfile
);
2331 if (x_parser_length(cfile
) > 0)
2333 ldap_write_debug(cfile
->inbuf
, cfile
->buflen
);
2335 res
= conf_file_subparse (cfile
, root_group
, ROOT_GROUP
);
2336 if (res
!= ISC_R_SUCCESS
)
2338 log_error ("LDAP: cannot parse dhcpServer entry '%s'", hostdn
);
2339 ldap_value_free_len (tempbv
);
2340 ldap_msgfree (hostres
);
2341 ldap_memfree (hostdn
);
2343 x_parser_free(&cfile
);
2346 x_parser_reset(cfile
);
2348 ldap_msgfree (hostres
);
2350 res
= ISC_R_SUCCESS
;
2351 for (cnt
=0; tempbv
[cnt
] != NULL
; cnt
++)
2354 if (_do_ldap_str2esc_filter_bv(hostdn
, 0, &bv_o
[0]) == NULL
)
2356 log_error ("Cannot escape ldap filter value %s: %m", hostdn
);
2357 res
= ISC_R_FAILURE
;
2361 snprintf(sfilter
, sizeof(sfilter
), "(&(objectClass=dhcpService)"
2362 "(|(|(dhcpPrimaryDN=%s)(dhcpSecondaryDN=%s))(dhcpServerDN=%s)))",
2363 bv_o
[0].bv_val
, bv_o
[0].bv_val
, bv_o
[0].bv_val
);
2365 ber_memfree(bv_o
[0].bv_val
);
2368 if ((ret
= ldap_search_ext_s (ld
, tempbv
[cnt
]->bv_val
, LDAP_SCOPE_BASE
,
2369 sfilter
, NULL
, 0, NULL
, NULL
, NULL
,
2370 0, &ldres
)) != LDAP_SUCCESS
)
2372 log_error ("Error searching for dhcpServiceDN '%s': %s. Please update the LDAP entry '%s'",
2373 tempbv
[cnt
]->bv_val
, ldap_err2string (ret
), hostdn
);
2375 ldap_msgfree(ldres
);
2376 res
= ISC_R_FAILURE
;
2380 if ((ent
= ldap_first_entry (ld
, ldres
)) == NULL
)
2382 log_error ("Error: Cannot find dhcpService DN '%s' with server reference. Please update the LDAP server entry '%s'",
2383 tempbv
[cnt
]->bv_val
, hostdn
);
2385 ldap_msgfree(ldres
);
2386 res
= ISC_R_FAILURE
;
2391 ** FIXME: how to free the remembered dn's on exit?
2392 ** This should be OK if dmalloc registers the
2393 ** memory it allocated and frees it on exit..
2396 curr
= dmalloc (sizeof (*curr
), MDL
);
2399 length
= strlen (tempbv
[cnt
]->bv_val
);
2400 curr
->dn
= dmalloc (length
+ 1, MDL
);
2401 if (curr
->dn
== NULL
)
2407 strcpy (curr
->dn
, tempbv
[cnt
]->bv_val
);
2414 /* append to service-dn list */
2415 if (ldap_service_dn_tail
!= NULL
)
2416 ldap_service_dn_tail
->next
= curr
;
2418 ldap_service_dn_head
= curr
;
2420 ldap_service_dn_tail
= curr
;
2423 log_fatal ("no memory to remember ldap service dn");
2425 #if defined (DEBUG_LDAP)
2426 log_info ("LDAP: Parsing dhcpService DN '%s' ...", tempbv
[cnt
]->bv_val
);
2428 add_to_config_stack (ldres
, ent
);
2429 res
= conf_file_subparse (cfile
, root_group
, ROOT_GROUP
);
2430 if (res
!= ISC_R_SUCCESS
)
2432 log_error ("LDAP: cannot parse dhcpService entry '%s'", tempbv
[cnt
]->bv_val
);
2437 x_parser_free(&cfile
);
2438 ldap_close_debug_fd();
2440 ldap_memfree (hostdn
);
2441 ldap_value_free_len (tempbv
);
2443 if (res
!= ISC_R_SUCCESS
)
2445 struct ldap_config_stack
*temp_stack
;
2447 while ((curr
= ldap_service_dn_head
) != NULL
)
2449 ldap_service_dn_head
= curr
->next
;
2450 dfree (curr
->dn
, MDL
);
2454 ldap_service_dn_tail
= NULL
;
2456 while ((temp_stack
= ldap_stack
) != NULL
)
2458 ldap_stack
= temp_stack
->next
;
2459 free_stack_entry (temp_stack
);
2465 /* Unbind from ldap immediately after reading config in static mode. */
2466 if (ldap_method
== LDAP_METHOD_STATIC
)
2473 /* This function will parse the dhcpOption and dhcpStatements field in the LDAP
2474 entry if it exists. Right now, type will be either HOST_DECL or CLASS_DECL.
2475 If we are parsing a HOST_DECL, this always returns 0. If we are parsing a
2476 CLASS_DECL, this will return what the current lease limit is in LDAP. If
2477 there is no lease limit specified, we return 0 */
2480 ldap_parse_options (LDAPMessage
* ent
, struct group
*group
,
2481 int type
, struct host_decl
*host
,
2482 struct class **class)
2484 int declaration
, lease_limit
;
2485 enum dhcp_token token
;
2486 struct parse
*cfile
;
2491 cfile
= x_parser_init(type
== HOST_DECL
? "LDAP-HOST" : "LDAP-SUBCLASS");
2493 return (lease_limit
);
2495 /* This block of code will try to find the parent of the host, and
2496 if it is a group object, fetch the options and apply to the host. */
2497 if (type
== HOST_DECL
)
2499 char *hostdn
, *basedn
, *temp1
, *temp2
, filter
[1024];
2500 LDAPMessage
*groupdn
, *entry
;
2503 hostdn
= ldap_get_dn (ld
, ent
);
2508 temp1
= strchr (hostdn
, '=');
2510 temp1
= strchr (++temp1
, '=');
2512 temp2
= strchr (++temp1
, ',');
2520 if (_do_ldap_str2esc_filter_bv(temp1
, (temp2
- temp1
), &bv_o
) == NULL
)
2522 log_error ("Cannot escape ldap filter value %.*s: %m",
2523 (int)(temp2
- temp1
), temp1
);
2528 snprintf (filter
, sizeof(filter
),
2529 "(&(cn=%s)(objectClass=dhcpGroup))",
2532 ber_memfree(bv_o
.bv_val
);
2535 basedn
= strchr (temp1
, ',');
2540 if (basedn
!= NULL
&& *basedn
!= '\0' && filter
[0] != '\0')
2542 ret
= ldap_search_ext_s (ld
, basedn
, LDAP_SCOPE_SUBTREE
, filter
,
2543 NULL
, 0, NULL
, NULL
, NULL
, 0, &groupdn
);
2544 if (ret
== LDAP_SUCCESS
)
2546 if ((entry
= ldap_first_entry (ld
, groupdn
)) != NULL
)
2548 res
= ldap_parse_entry_options (entry
, cfile
, &lease_limit
);
2549 if (res
!= ISC_R_SUCCESS
)
2551 /* reset option buffer discarding any results */
2552 x_parser_reset(cfile
);
2556 ldap_msgfree( groupdn
);
2559 ldap_memfree( hostdn
);
2563 res
= ldap_parse_entry_options (ent
, cfile
, &lease_limit
);
2564 if (res
!= ISC_R_SUCCESS
)
2566 x_parser_free(&cfile
);
2567 return (lease_limit
);
2570 if (x_parser_length(cfile
) == 0)
2572 x_parser_free(&cfile
);
2573 return (lease_limit
);
2579 token
= peek_token (&val
, NULL
, cfile
);
2580 if (token
== END_OF_FILE
)
2582 declaration
= parse_statement (cfile
, group
, type
, host
, declaration
);
2585 x_parser_free(&cfile
);
2587 return (lease_limit
);
2593 find_haddr_in_ldap (struct host_decl
**hp
, int htype
, unsigned hlen
,
2594 const unsigned char *haddr
, const char *file
, int line
)
2596 char buf
[128], *type_str
;
2597 LDAPMessage
* res
, *ent
;
2598 struct host_decl
* host
;
2599 isc_result_t status
;
2604 struct berval bv_o
[2];
2609 if (ldap_method
== LDAP_METHOD_STATIC
)
2620 type_str
= "ethernet";
2623 type_str
= "token-ring";
2629 log_info ("Ignoring unknown type %d", htype
);
2634 ** FIXME: It is not guaranteed, that the dhcpHWAddress attribute
2635 ** contains _exactly_ "type addr" with one space between!
2637 snprintf(lo_hwaddr
, sizeof(lo_hwaddr
), "%s",
2638 print_hw_addr (htype
, hlen
, haddr
));
2639 x_strxform(up_hwaddr
, lo_hwaddr
, sizeof(up_hwaddr
), toupper
);
2641 if (_do_ldap_str2esc_filter_bv(lo_hwaddr
, 0, &bv_o
[0]) == NULL
)
2643 log_error ("Cannot escape ldap filter value %s: %m", lo_hwaddr
);
2646 if (_do_ldap_str2esc_filter_bv(up_hwaddr
, 0, &bv_o
[1]) == NULL
)
2648 log_error ("Cannot escape ldap filter value %s: %m", up_hwaddr
);
2649 ber_memfree(bv_o
[0].bv_val
);
2653 snprintf (buf
, sizeof (buf
),
2654 "(&(objectClass=dhcpHost)(|(dhcpHWAddress=%s %s)(dhcpHWAddress=%s %s)))",
2655 type_str
, bv_o
[0].bv_val
, type_str
, bv_o
[1].bv_val
);
2657 ber_memfree(bv_o
[0].bv_val
);
2658 ber_memfree(bv_o
[1].bv_val
);
2661 for (curr
= ldap_service_dn_head
;
2662 curr
!= NULL
&& *curr
->dn
!= '\0';
2665 #if defined (DEBUG_LDAP)
2666 log_info ("Searching for %s in LDAP tree %s", buf
, curr
->dn
);
2668 ret
= ldap_search_ext_s (ld
, curr
->dn
, LDAP_SCOPE_SUBTREE
, buf
, NULL
, 0,
2669 NULL
, NULL
, NULL
, 0, &res
);
2671 if(ret
== LDAP_SERVER_DOWN
)
2673 log_info ("LDAP server was down, trying to reconnect...");
2679 log_info ("LDAP reconnect failed - try again later...");
2683 ret
= ldap_search_ext_s (ld
, curr
->dn
, LDAP_SCOPE_SUBTREE
, buf
, NULL
,
2684 0, NULL
, NULL
, NULL
, 0, &res
);
2687 if (ret
== LDAP_SUCCESS
)
2689 ent
= ldap_first_entry (ld
, res
);
2690 #if defined (DEBUG_LDAP)
2692 log_info ("No host entry for %s in LDAP tree %s",
2696 while (ent
!= NULL
) {
2697 #if defined (DEBUG_LDAP)
2698 char *dn
= ldap_get_dn (ld
, ent
);
2701 log_info ("Found dhcpHWAddress LDAP entry %s", dn
);
2706 host
= (struct host_decl
*)0;
2707 status
= host_allocate (&host
, MDL
);
2708 if (status
!= ISC_R_SUCCESS
)
2710 log_fatal ("can't allocate host decl struct: %s",
2711 isc_result_totext (status
));
2716 host
->name
= ldap_get_host_name (ent
);
2717 if (host
->name
== NULL
)
2719 host_dereference (&host
, MDL
);
2724 if (!clone_group (&host
->group
, root_group
, MDL
))
2726 log_fatal ("can't clone group for host %s", host
->name
);
2727 host_dereference (&host
, MDL
);
2732 ldap_parse_options (ent
, host
->group
, HOST_DECL
, host
, NULL
);
2734 host
->n_ipaddr
= *hp
;
2736 ent
= ldap_next_entry (ld
, ent
);
2743 return (*hp
!= NULL
);
2753 if (ret
!= LDAP_NO_SUCH_OBJECT
&& ret
!= LDAP_SUCCESS
)
2755 log_error ("Cannot search for %s in LDAP tree %s: %s", buf
,
2756 curr
->dn
, ldap_err2string (ret
));
2760 #if defined (DEBUG_LDAP)
2763 log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
2764 ldap_err2string (ret
), buf
, curr
->dn
);
2775 find_subclass_in_ldap (struct class *class, struct class **newclass
,
2776 struct data_string
*data
)
2778 LDAPMessage
* res
, * ent
;
2779 int ret
, lease_limit
;
2780 isc_result_t status
;
2783 struct berval bv_class
;
2784 struct berval bv_cdata
;
2787 if (ldap_method
== LDAP_METHOD_STATIC
)
2795 hex_1
= print_hex_1 (data
->len
, data
->data
, 1024);
2798 /* result is a quotted not hex string: ldap escape the original string */
2799 if (_do_ldap_str2esc_filter_bv((const char*)data
->data
, data
->len
, &bv_cdata
) == NULL
)
2801 log_error ("Cannot escape ldap filter value %s: %m", hex_1
);
2806 if (_do_ldap_str2esc_filter_bv(class->name
, strlen (class->name
), &bv_class
) == NULL
)
2808 log_error ("Cannot escape ldap filter value %s: %m", class->name
);
2810 ber_memfree(bv_cdata
.bv_val
);
2814 snprintf (buf
, sizeof (buf
),
2815 "(&(objectClass=dhcpSubClass)(cn=%s)(dhcpClassData=%s))",
2816 (hex_1
== NULL
? bv_cdata
.bv_val
: hex_1
), bv_class
.bv_val
);
2819 ber_memfree(bv_cdata
.bv_val
);
2820 ber_memfree(bv_class
.bv_val
);
2822 #if defined (DEBUG_LDAP)
2823 log_info ("Searching LDAP for %s", buf
);
2827 for (curr
= ldap_service_dn_head
;
2828 curr
!= NULL
&& *curr
->dn
!= '\0';
2831 #if defined (DEBUG_LDAP)
2832 log_info ("Searching for %s in LDAP tree %s", buf
, curr
->dn
);
2834 ret
= ldap_search_ext_s (ld
, curr
->dn
, LDAP_SCOPE_SUBTREE
, buf
, NULL
, 0,
2835 NULL
, NULL
, NULL
, 0, &res
);
2837 if(ret
== LDAP_SERVER_DOWN
)
2839 log_info ("LDAP server was down, trying to reconnect...");
2846 log_info ("LDAP reconnect failed - try again later...");
2850 ret
= ldap_search_ext_s (ld
, curr
->dn
, LDAP_SCOPE_SUBTREE
, buf
,
2851 NULL
, 0, NULL
, NULL
, NULL
, 0, &res
);
2854 if (ret
== LDAP_SUCCESS
)
2856 if( (ent
= ldap_first_entry (ld
, res
)) != NULL
)
2857 break; /* search OK and have entry */
2859 #if defined (DEBUG_LDAP)
2860 log_info ("No subclass entry for %s in LDAP tree %s",
2877 if (ret
!= LDAP_NO_SUCH_OBJECT
&& ret
!= LDAP_SUCCESS
)
2879 log_error ("Cannot search for %s in LDAP tree %s: %s", buf
,
2880 curr
->dn
, ldap_err2string (ret
));
2884 #if defined (DEBUG_LDAP)
2887 log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
2888 ldap_err2string (ret
), buf
, curr
->dn
);
2896 #if defined (DEBUG_LDAP)
2897 char *dn
= ldap_get_dn (ld
, ent
);
2900 log_info ("Found subclass LDAP entry %s", dn
);
2905 status
= class_allocate (newclass
, MDL
);
2906 if (status
!= ISC_R_SUCCESS
)
2908 log_error ("Cannot allocate memory for a new class");
2913 group_reference (&(*newclass
)->group
, class->group
, MDL
);
2914 class_reference (&(*newclass
)->superclass
, class, MDL
);
2915 lease_limit
= ldap_parse_options (ent
, (*newclass
)->group
,
2916 CLASS_DECL
, NULL
, newclass
);
2917 if (lease_limit
== 0)
2918 (*newclass
)->lease_limit
= class->lease_limit
;
2920 class->lease_limit
= lease_limit
;
2922 if ((*newclass
)->lease_limit
)
2924 (*newclass
)->billed_leases
=
2925 dmalloc ((*newclass
)->lease_limit
* sizeof (struct lease
*), MDL
);
2926 if (!(*newclass
)->billed_leases
)
2928 log_error ("no memory for billing");
2929 class_dereference (newclass
, MDL
);
2933 memset ((*newclass
)->billed_leases
, 0,
2934 ((*newclass
)->lease_limit
* sizeof (struct lease
*)));
2937 data_string_copy (&(*newclass
)->hash_string
, data
, MDL
);
2943 if(res
) ldap_msgfree (res
);
2947 int find_client_in_ldap (struct host_decl
**hp
, struct packet
*packet
,
2948 struct option_state
*state
, const char *file
, int line
)
2950 LDAPMessage
* res
, * ent
;
2952 struct host_decl
* host
;
2953 isc_result_t status
;
2954 struct data_string client_id
;
2955 char buf
[1024], buf1
[1024];
2958 if (ldap_method
== LDAP_METHOD_STATIC
)
2966 memset(&client_id
, 0, sizeof(client_id
));
2967 if (get_client_id(packet
, &client_id
) != ISC_R_SUCCESS
)
2969 snprintf(buf
, sizeof(buf
),
2970 "(&(objectClass=dhcpHost)(dhcpClientId=%s))",
2971 print_hw_addr(0, client_id
.len
, client_id
.data
));
2973 /* log_info ("Searching LDAP for %s (%s)", buf, packet->interface->shared_network->name); */
2976 for (curr
= ldap_service_dn_head
;
2977 curr
!= NULL
&& *curr
->dn
!= '\0';
2980 snprintf(buf1
, sizeof(buf1
), "cn=%s,%s", packet
->interface
->shared_network
->name
, curr
->dn
);
2981 #if defined (DEBUG_LDAP)
2982 log_info ("Searching for %s in LDAP tree %s", buf
, buf1
);
2984 ret
= ldap_search_ext_s (ld
, buf1
, LDAP_SCOPE_SUBTREE
, buf
, NULL
, 0,
2985 NULL
, NULL
, NULL
, 0, &res
);
2987 if(ret
== LDAP_SERVER_DOWN
)
2989 log_info ("LDAP server was down, trying to reconnect...");
2996 log_info ("LDAP reconnect failed - try again later...");
3000 ret
= ldap_search_ext_s (ld
, buf1
, LDAP_SCOPE_SUBTREE
, buf
,
3001 NULL
, 0, NULL
, NULL
, NULL
, 0, &res
);
3004 if (ret
== LDAP_SUCCESS
)
3006 if( (ent
= ldap_first_entry (ld
, res
)) != NULL
) {
3007 log_info ("found entry in search %s", buf1
);
3008 break; /* search OK and have entry */
3011 #if defined (DEBUG_LDAP)
3012 log_info ("No subclass entry for %s in LDAP tree %s", buf
, curr
->dn
);
3028 if (ret
!= LDAP_NO_SUCH_OBJECT
&& ret
!= LDAP_SUCCESS
)
3030 log_error ("Cannot search for %s in LDAP tree %s: %s", buf
,
3031 curr
->dn
, ldap_err2string (ret
));
3037 log_info ("did not find: %s", buf
);
3044 #if defined (DEBUG_LDAP)
3045 log_info ("ldap_get_dn %s", curr
->dn
);
3046 char *dn
= ldap_get_dn (ld
, ent
);
3049 log_info ("Found subclass LDAP entry %s", dn
);
3052 log_info ("DN is null %s", dn
);
3056 host
= (struct host_decl
*)0;
3057 status
= host_allocate (&host
, MDL
);
3058 if (status
!= ISC_R_SUCCESS
)
3060 log_fatal ("can't allocate host decl struct: %s",
3061 isc_result_totext (status
));
3066 host
->name
= ldap_get_host_name (ent
);
3067 if (host
->name
== NULL
)
3069 host_dereference (&host
, MDL
);
3073 /* log_info ("Host name %s", host->name); */
3075 if (!clone_group (&host
->group
, root_group
, MDL
))
3077 log_fatal ("can't clone group for host %s", host
->name
);
3078 host_dereference (&host
, MDL
);
3083 ldap_parse_options (ent
, host
->group
, HOST_DECL
, host
, NULL
);
3091 log_info ("did not find clientid: %s", buf
);
3094 if(res
) ldap_msgfree (res
);
3099 #if defined(LDAP_USE_GSSAPI)
3101 _ldap_sasl_interact(LDAP
*ld
, unsigned flags
, void *defaults
, void *sin
)
3103 sasl_interact_t
*in
;
3104 struct ldap_sasl_instance
*ldap_inst
= defaults
;
3105 int ret
= LDAP_OTHER
;
3108 if (ld
== NULL
|| sin
== NULL
)
3109 return LDAP_PARAM_ERROR
;
3111 log_info("doing interactive bind");
3112 for (in
= sin
; in
!= NULL
&& in
->id
!= SASL_CB_LIST_END
; in
++) {
3115 log_info("got request for SASL_CB_USER %s", ldap_inst
->sasl_authz_id
);
3116 size
= strlen(ldap_inst
->sasl_authz_id
);
3117 in
->result
= ldap_inst
->sasl_authz_id
;
3121 case SASL_CB_GETREALM
:
3122 log_info("got request for SASL_CB_GETREALM %s", ldap_inst
->sasl_realm
);
3123 size
= strlen(ldap_inst
->sasl_realm
);
3124 in
->result
= ldap_inst
->sasl_realm
;
3128 case SASL_CB_AUTHNAME
:
3129 log_info("got request for SASL_CB_AUTHNAME %s", ldap_inst
->sasl_authc_id
);
3130 size
= strlen(ldap_inst
->sasl_authc_id
);
3131 in
->result
= ldap_inst
->sasl_authc_id
;
3136 log_info("got request for SASL_CB_PASS %s", ldap_inst
->sasl_password
);
3137 size
= strlen(ldap_inst
->sasl_password
);
3138 in
->result
= ldap_inst
->sasl_password
;
3153 #endif /* LDAP_USE_GSSAPI */