ldap.c revision 1.3 1 1.2 christos /* $NetBSD: ldap.c,v 1.3 2020/08/03 21:10:57 christos Exp $ */
2 1.1 christos
3 1.1 christos /* ldap.c
4 1.1 christos
5 1.1 christos Routines for reading the configuration from LDAP */
6 1.1 christos
7 1.1 christos /*
8 1.3 christos * Copyright (c) 2010-2019 by Internet Systems Consortium, Inc. ("ISC")
9 1.1 christos * Copyright (c) 2003-2006 Ntelos, Inc.
10 1.1 christos * All rights reserved.
11 1.1 christos *
12 1.1 christos * Redistribution and use in source and binary forms, with or without
13 1.1 christos * modification, are permitted provided that the following conditions
14 1.1 christos * are met:
15 1.1 christos *
16 1.1 christos * 1. Redistributions of source code must retain the above copyright
17 1.1 christos * notice, this list of conditions and the following disclaimer.
18 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright
19 1.1 christos * notice, this list of conditions and the following disclaimer in the
20 1.1 christos * documentation and/or other materials provided with the distribution.
21 1.1 christos * 3. Neither the name of The Internet Software Consortium nor the names
22 1.1 christos * of its contributors may be used to endorse or promote products derived
23 1.1 christos * from this software without specific prior written permission.
24 1.1 christos *
25 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
26 1.1 christos * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
27 1.1 christos * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28 1.1 christos * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 1.1 christos * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
30 1.1 christos * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 1.1 christos * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 1.1 christos * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
33 1.1 christos * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
34 1.1 christos * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35 1.1 christos * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
36 1.1 christos * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 1.1 christos * SUCH DAMAGE.
38 1.1 christos *
39 1.1 christos * This LDAP module was written by Brian Masney <masneyb (at) ntelos.net>. Its
40 1.1 christos * development was sponsored by Ntelos, Inc. (www.ntelos.com).
41 1.1 christos */
42 1.1 christos
43 1.1 christos #include <sys/cdefs.h>
44 1.2 christos __RCSID("$NetBSD: ldap.c,v 1.3 2020/08/03 21:10:57 christos Exp $");
45 1.1 christos
46 1.1 christos
47 1.1 christos #include "dhcpd.h"
48 1.1 christos #if defined(LDAP_CONFIGURATION)
49 1.1 christos #include <signal.h>
50 1.1 christos #include <errno.h>
51 1.1 christos #include <ctype.h>
52 1.1 christos #include <netdb.h>
53 1.1 christos #include <net/if.h>
54 1.1 christos #if defined(HAVE_IFADDRS_H)
55 1.1 christos #include <ifaddrs.h>
56 1.1 christos #endif
57 1.1 christos #include <string.h>
58 1.1 christos
59 1.1 christos #if defined(LDAP_CASA_AUTH)
60 1.1 christos #include "ldap_casa.h"
61 1.1 christos #endif
62 1.1 christos
63 1.1 christos #if defined(LDAP_USE_GSSAPI)
64 1.1 christos #include <sasl/sasl.h>
65 1.1 christos #include "ldap_krb_helper.h"
66 1.1 christos #endif
67 1.1 christos
68 1.1 christos static LDAP * ld = NULL;
69 1.1 christos static char *ldap_server = NULL,
70 1.1 christos *ldap_username = NULL,
71 1.1 christos *ldap_password = NULL,
72 1.1 christos *ldap_base_dn = NULL,
73 1.1 christos *ldap_dhcp_server_cn = NULL,
74 1.1 christos *ldap_debug_file = NULL;
75 1.1 christos static int ldap_port = LDAP_PORT,
76 1.1 christos ldap_method = LDAP_METHOD_DYNAMIC,
77 1.1 christos ldap_referrals = -1,
78 1.1 christos ldap_debug_fd = -1,
79 1.1 christos ldap_enable_retry = -1,
80 1.1 christos ldap_init_retry = -1;
81 1.1 christos #if defined (LDAP_USE_SSL)
82 1.1 christos static int ldap_use_ssl = -1, /* try TLS if possible */
83 1.1 christos ldap_tls_reqcert = -1,
84 1.1 christos ldap_tls_crlcheck = -1;
85 1.1 christos static char *ldap_tls_ca_file = NULL,
86 1.1 christos *ldap_tls_ca_dir = NULL,
87 1.1 christos *ldap_tls_cert = NULL,
88 1.1 christos *ldap_tls_key = NULL,
89 1.1 christos *ldap_tls_ciphers = NULL,
90 1.1 christos *ldap_tls_randfile = NULL;
91 1.1 christos #endif
92 1.1 christos
93 1.1 christos #if defined (LDAP_USE_GSSAPI)
94 1.1 christos static char *ldap_gssapi_keytab = NULL,
95 1.1 christos *ldap_gssapi_principal = NULL;
96 1.1 christos
97 1.1 christos struct ldap_sasl_instance {
98 1.1 christos char *sasl_mech;
99 1.1 christos char *sasl_realm;
100 1.1 christos char *sasl_authz_id;
101 1.1 christos char *sasl_authc_id;
102 1.1 christos char *sasl_password;
103 1.1 christos };
104 1.1 christos
105 1.1 christos static struct ldap_sasl_instance *ldap_sasl_inst = NULL;
106 1.1 christos
107 1.1 christos static int
108 1.1 christos _ldap_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *sin) ;
109 1.1 christos #endif
110 1.1 christos
111 1.1 christos static struct ldap_config_stack *ldap_stack = NULL;
112 1.1 christos
113 1.1 christos typedef struct ldap_dn_node {
114 1.1 christos struct ldap_dn_node *next;
115 1.1 christos size_t refs;
116 1.1 christos char *dn;
117 1.1 christos } ldap_dn_node;
118 1.1 christos
119 1.1 christos static ldap_dn_node *ldap_service_dn_head = NULL;
120 1.1 christos static ldap_dn_node *ldap_service_dn_tail = NULL;
121 1.1 christos
122 1.1 christos static int ldap_read_function (struct parse *cfile);
123 1.1 christos
124 1.1 christos static struct parse *
125 1.1 christos x_parser_init(const char *name)
126 1.1 christos {
127 1.1 christos struct parse *cfile;
128 1.1 christos isc_result_t res;
129 1.1 christos char *inbuf;
130 1.1 christos
131 1.1 christos inbuf = dmalloc (LDAP_BUFFER_SIZE, MDL);
132 1.1 christos if (inbuf == NULL)
133 1.1 christos return NULL;
134 1.1 christos
135 1.1 christos cfile = (struct parse *) NULL;
136 1.1 christos res = new_parse (&cfile, -1, inbuf, LDAP_BUFFER_SIZE, name, 0);
137 1.1 christos if (res != ISC_R_SUCCESS)
138 1.1 christos {
139 1.1 christos dfree(inbuf, MDL);
140 1.1 christos return NULL;
141 1.1 christos }
142 1.1 christos /* the buffer is still empty */
143 1.1 christos cfile->bufsiz = LDAP_BUFFER_SIZE;
144 1.1 christos cfile->buflen = cfile->bufix = 0;
145 1.1 christos /* attach ldap read function */
146 1.1 christos cfile->read_function = ldap_read_function;
147 1.1 christos return cfile;
148 1.1 christos }
149 1.1 christos
150 1.1 christos static isc_result_t
151 1.1 christos x_parser_free(struct parse **cfile)
152 1.1 christos {
153 1.1 christos if (cfile && *cfile)
154 1.1 christos {
155 1.1 christos if ((*cfile)->inbuf)
156 1.1 christos dfree((*cfile)->inbuf, MDL);
157 1.1 christos (*cfile)->inbuf = NULL;
158 1.1 christos (*cfile)->bufsiz = 0;
159 1.1 christos return end_parse(cfile);
160 1.1 christos }
161 1.1 christos return ISC_R_SUCCESS;
162 1.1 christos }
163 1.1 christos
164 1.1 christos static int
165 1.1 christos x_parser_resize(struct parse *cfile, size_t len)
166 1.1 christos {
167 1.1 christos size_t size;
168 1.1 christos char * temp;
169 1.1 christos
170 1.1 christos /* grow by len rounded up at LDAP_BUFFER_SIZE */
171 1.1 christos size = cfile->bufsiz + (len | (LDAP_BUFFER_SIZE-1)) + 1;
172 1.1 christos
173 1.1 christos /* realloc would be better, but there isn't any */
174 1.1 christos if ((temp = dmalloc (size, MDL)) != NULL)
175 1.1 christos {
176 1.1 christos #if defined (DEBUG_LDAP)
177 1.1 christos log_info ("Reallocated %s buffer from %zu to %zu",
178 1.1 christos cfile->tlname, cfile->bufsiz, size);
179 1.1 christos #endif
180 1.1 christos memcpy(temp, cfile->inbuf, cfile->bufsiz);
181 1.1 christos dfree(cfile->inbuf, MDL);
182 1.1 christos cfile->inbuf = temp;
183 1.1 christos cfile->bufsiz = size;
184 1.1 christos return 1;
185 1.1 christos }
186 1.1 christos
187 1.1 christos /*
188 1.1 christos * Hmm... what is worser, consider it as fatal error and
189 1.1 christos * bail out completely or discard config data in hope it
190 1.1 christos * is "only" an option in dynamic host lookup?
191 1.1 christos */
192 1.1 christos log_error("Unable to reallocated %s buffer from %zu to %zu",
193 1.1 christos cfile->tlname, cfile->bufsiz, size);
194 1.1 christos return 0;
195 1.1 christos }
196 1.1 christos
197 1.1 christos static char *
198 1.1 christos x_parser_strcat(struct parse *cfile, const char *str)
199 1.1 christos {
200 1.1 christos size_t cur = strlen(cfile->inbuf);
201 1.1 christos size_t len = strlen(str);
202 1.1 christos size_t cnt;
203 1.1 christos
204 1.1 christos if (cur + len >= cfile->bufsiz && !x_parser_resize(cfile, len))
205 1.1 christos return NULL;
206 1.1 christos
207 1.1 christos cnt = cfile->bufsiz > cur ? cfile->bufsiz - cur - 1 : 0;
208 1.1 christos return strncat(cfile->inbuf, str, cnt);
209 1.1 christos }
210 1.1 christos
211 1.1 christos static inline void
212 1.1 christos x_parser_reset(struct parse *cfile)
213 1.1 christos {
214 1.1 christos cfile->inbuf[0] = '\0';
215 1.1 christos cfile->bufix = cfile->buflen = 0;
216 1.1 christos }
217 1.1 christos
218 1.1 christos static inline size_t
219 1.1 christos x_parser_length(struct parse *cfile)
220 1.1 christos {
221 1.1 christos cfile->buflen = strlen(cfile->inbuf);
222 1.1 christos return cfile->buflen;
223 1.1 christos }
224 1.1 christos
225 1.1 christos static char *
226 1.1 christos x_strxform(char *dst, const char *src, size_t dst_size,
227 1.1 christos int (*xform)(int))
228 1.1 christos {
229 1.1 christos if(dst && src && dst_size)
230 1.1 christos {
231 1.1 christos size_t len, pos;
232 1.1 christos
233 1.1 christos len = strlen(src);
234 1.1 christos for(pos=0; pos < len && pos + 1 < dst_size; pos++)
235 1.1 christos dst[pos] = xform((int)src[pos]);
236 1.1 christos dst[pos] = '\0';
237 1.1 christos
238 1.1 christos return dst;
239 1.1 christos }
240 1.1 christos return NULL;
241 1.1 christos }
242 1.1 christos
243 1.1 christos static int
244 1.1 christos get_host_entry(char *fqdnname, size_t fqdnname_size,
245 1.1 christos char *hostaddr, size_t hostaddr_size)
246 1.1 christos {
247 1.1 christos #if defined(MAXHOSTNAMELEN)
248 1.1 christos char hname[MAXHOSTNAMELEN+1];
249 1.1 christos #else
250 1.1 christos char hname[65];
251 1.1 christos #endif
252 1.1 christos struct hostent *hp;
253 1.1 christos
254 1.1 christos if (NULL == fqdnname || 1 >= fqdnname_size)
255 1.1 christos return -1;
256 1.1 christos
257 1.1 christos memset(hname, 0, sizeof(hname));
258 1.1 christos if (gethostname(hname, sizeof(hname)-1))
259 1.1 christos return -1;
260 1.1 christos
261 1.1 christos if (NULL == (hp = gethostbyname(hname)))
262 1.1 christos return -1;
263 1.1 christos
264 1.1 christos strncpy(fqdnname, hp->h_name, fqdnname_size-1);
265 1.1 christos fqdnname[fqdnname_size-1] = '\0';
266 1.1 christos
267 1.1 christos if (hostaddr != NULL)
268 1.1 christos {
269 1.1 christos if (hp->h_addr != NULL)
270 1.1 christos {
271 1.1 christos struct in_addr *aptr = (struct in_addr *)hp->h_addr;
272 1.1 christos #if defined(HAVE_INET_NTOP)
273 1.1 christos if (hostaddr_size >= INET_ADDRSTRLEN &&
274 1.1 christos inet_ntop(AF_INET, aptr, hostaddr, hostaddr_size) != NULL)
275 1.1 christos {
276 1.1 christos return 0;
277 1.1 christos }
278 1.1 christos #else
279 1.1 christos char *astr = inet_ntoa(*aptr);
280 1.1 christos size_t alen = strlen(astr);
281 1.1 christos if (astr && alen > 0 && hostaddr_size > alen)
282 1.1 christos {
283 1.1 christos strncpy(hostaddr, astr, hostaddr_size-1);
284 1.1 christos hostaddr[hostaddr_size-1] = '\0';
285 1.1 christos return 0;
286 1.1 christos }
287 1.1 christos #endif
288 1.1 christos }
289 1.1 christos return -1;
290 1.1 christos }
291 1.1 christos return 0;
292 1.1 christos }
293 1.1 christos
294 1.1 christos #if defined(HAVE_IFADDRS_H)
295 1.1 christos static int
296 1.1 christos is_iface_address(struct ifaddrs *addrs, struct in_addr *addr)
297 1.1 christos {
298 1.1 christos struct ifaddrs *ia;
299 1.1 christos struct sockaddr_in *sa;
300 1.1 christos int num = 0;
301 1.1 christos
302 1.1 christos if(addrs == NULL || addr == NULL)
303 1.1 christos return -1;
304 1.1 christos
305 1.1 christos for (ia = addrs; ia != NULL; ia = ia->ifa_next)
306 1.1 christos {
307 1.1 christos ++num;
308 1.1 christos if (ia->ifa_addr && (ia->ifa_flags & IFF_UP) &&
309 1.1 christos ia->ifa_addr->sa_family == AF_INET)
310 1.1 christos {
311 1.1 christos sa = (struct sockaddr_in *)(ia->ifa_addr);
312 1.1 christos if (addr->s_addr == sa->sin_addr.s_addr)
313 1.1 christos return num;
314 1.1 christos }
315 1.1 christos }
316 1.1 christos return 0;
317 1.1 christos }
318 1.1 christos
319 1.1 christos static int
320 1.1 christos get_host_address(const char *hostname, char *hostaddr, size_t hostaddr_size, struct ifaddrs *addrs)
321 1.1 christos {
322 1.1 christos if (hostname && *hostname && hostaddr && hostaddr_size)
323 1.1 christos {
324 1.1 christos struct in_addr addr;
325 1.1 christos
326 1.1 christos #if defined(HAVE_INET_PTON)
327 1.1 christos if (inet_pton(AF_INET, hostname, &addr) == 1)
328 1.1 christos #else
329 1.1 christos if (inet_aton(hostname, &addr) != 0)
330 1.1 christos #endif
331 1.1 christos {
332 1.1 christos /* it is already IP address string */
333 1.1 christos if(strlen(hostname) < hostaddr_size)
334 1.1 christos {
335 1.1 christos strncpy(hostaddr, hostname, hostaddr_size-1);
336 1.1 christos hostaddr[hostaddr_size-1] = '\0';
337 1.1 christos
338 1.1 christos if (addrs != NULL && is_iface_address (addrs, &addr) > 0)
339 1.1 christos return 1;
340 1.1 christos else
341 1.1 christos return 0;
342 1.1 christos }
343 1.1 christos }
344 1.1 christos else
345 1.1 christos {
346 1.1 christos struct hostent *hp;
347 1.1 christos if ((hp = gethostbyname(hostname)) != NULL && hp->h_addr != NULL)
348 1.1 christos {
349 1.1 christos struct in_addr *aptr = (struct in_addr *)hp->h_addr;
350 1.1 christos int mret = 0;
351 1.1 christos
352 1.1 christos if (addrs != NULL)
353 1.1 christos {
354 1.1 christos char **h;
355 1.1 christos for (h=hp->h_addr_list; *h; h++)
356 1.1 christos {
357 1.1 christos struct in_addr *haddr = (struct in_addr *)*h;
358 1.1 christos if (is_iface_address (addrs, haddr) > 0)
359 1.1 christos {
360 1.1 christos aptr = haddr;
361 1.1 christos mret = 1;
362 1.1 christos }
363 1.1 christos }
364 1.1 christos }
365 1.1 christos
366 1.1 christos #if defined(HAVE_INET_NTOP)
367 1.1 christos if (hostaddr_size >= INET_ADDRSTRLEN &&
368 1.1 christos inet_ntop(AF_INET, aptr, hostaddr, hostaddr_size) != NULL)
369 1.1 christos {
370 1.1 christos return mret;
371 1.1 christos }
372 1.1 christos #else
373 1.1 christos char *astr = inet_ntoa(*aptr);
374 1.1 christos size_t alen = strlen(astr);
375 1.1 christos if (astr && alen > 0 && alen < hostaddr_size)
376 1.1 christos {
377 1.1 christos strncpy(hostaddr, astr, hostaddr_size-1);
378 1.1 christos hostaddr[hostaddr_size-1] = '\0';
379 1.1 christos return mret;
380 1.1 christos }
381 1.1 christos #endif
382 1.1 christos }
383 1.1 christos }
384 1.1 christos }
385 1.1 christos return -1;
386 1.1 christos }
387 1.1 christos #endif /* HAVE_IFADDRS_H */
388 1.1 christos
389 1.1 christos static void
390 1.1 christos ldap_parse_class (struct ldap_config_stack *item, struct parse *cfile)
391 1.1 christos {
392 1.1 christos struct berval **tempbv;
393 1.1 christos
394 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
395 1.1 christos tempbv[0] == NULL)
396 1.1 christos {
397 1.1 christos if (tempbv != NULL)
398 1.1 christos ldap_value_free_len (tempbv);
399 1.1 christos
400 1.1 christos return;
401 1.1 christos }
402 1.1 christos
403 1.1 christos x_parser_strcat (cfile, "class \"");
404 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
405 1.1 christos x_parser_strcat (cfile, "\" {\n");
406 1.1 christos
407 1.1 christos item->close_brace = 1;
408 1.1 christos ldap_value_free_len (tempbv);
409 1.1 christos }
410 1.1 christos
411 1.1 christos static int
412 1.1 christos is_hex_string(const char *str)
413 1.1 christos {
414 1.1 christos int colon = 1;
415 1.1 christos int xdigit = 0;
416 1.1 christos size_t i;
417 1.1 christos
418 1.1 christos if (!str)
419 1.1 christos return 0;
420 1.1 christos
421 1.1 christos if (*str == '-')
422 1.1 christos str++;
423 1.1 christos
424 1.1 christos for (i=0; str[i]; ++i)
425 1.1 christos {
426 1.1 christos if (str[i] == ':')
427 1.1 christos {
428 1.1 christos xdigit = 0;
429 1.1 christos if(++colon > 1)
430 1.1 christos return 0;
431 1.1 christos }
432 1.1 christos else if(isxdigit((unsigned char)str[i]))
433 1.1 christos {
434 1.1 christos colon = 0;
435 1.1 christos if (++xdigit > 2)
436 1.1 christos return 0;
437 1.1 christos }
438 1.1 christos else
439 1.1 christos return 0;
440 1.1 christos }
441 1.1 christos return i > 0 && !colon;
442 1.1 christos }
443 1.1 christos
444 1.1 christos static void
445 1.1 christos ldap_parse_subclass (struct ldap_config_stack *item, struct parse *cfile)
446 1.1 christos {
447 1.1 christos struct berval **tempbv, **classdata;
448 1.1 christos char *tmp;
449 1.1 christos
450 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
451 1.1 christos tempbv[0] == NULL)
452 1.1 christos {
453 1.1 christos if (tempbv != NULL)
454 1.1 christos ldap_value_free_len (tempbv);
455 1.1 christos
456 1.1 christos return;
457 1.1 christos }
458 1.1 christos
459 1.1 christos if ((classdata = ldap_get_values_len (ld, item->ldent,
460 1.1 christos "dhcpClassData")) == NULL ||
461 1.1 christos classdata[0] == NULL)
462 1.1 christos {
463 1.1 christos if (classdata != NULL)
464 1.1 christos ldap_value_free_len (classdata);
465 1.1 christos ldap_value_free_len (tempbv);
466 1.1 christos
467 1.1 christos return;
468 1.1 christos }
469 1.1 christos
470 1.1 christos x_parser_strcat (cfile, "subclass \"");
471 1.1 christos x_parser_strcat (cfile, classdata[0]->bv_val);
472 1.1 christos if (is_hex_string(tempbv[0]->bv_val))
473 1.1 christos {
474 1.1 christos x_parser_strcat (cfile, "\" ");
475 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
476 1.1 christos x_parser_strcat (cfile, " {\n");
477 1.1 christos }
478 1.1 christos else
479 1.1 christos {
480 1.1 christos tmp = quotify_string(tempbv[0]->bv_val, MDL);
481 1.1 christos x_parser_strcat (cfile, "\" \"");
482 1.1 christos x_parser_strcat (cfile, tmp);
483 1.1 christos x_parser_strcat (cfile, "\" {\n");
484 1.1 christos dfree(tmp, MDL);
485 1.1 christos }
486 1.1 christos
487 1.1 christos item->close_brace = 1;
488 1.1 christos ldap_value_free_len (tempbv);
489 1.1 christos ldap_value_free_len (classdata);
490 1.1 christos }
491 1.1 christos
492 1.1 christos
493 1.1 christos static void
494 1.1 christos ldap_parse_host (struct ldap_config_stack *item, struct parse *cfile)
495 1.1 christos {
496 1.1 christos struct berval **tempbv, **hwaddr;
497 1.1 christos
498 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
499 1.1 christos tempbv[0] == NULL)
500 1.1 christos {
501 1.1 christos if (tempbv != NULL)
502 1.1 christos ldap_value_free_len (tempbv);
503 1.1 christos
504 1.1 christos return;
505 1.1 christos }
506 1.1 christos
507 1.1 christos hwaddr = ldap_get_values_len (ld, item->ldent, "dhcpHWAddress");
508 1.1 christos
509 1.1 christos x_parser_strcat (cfile, "host ");
510 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
511 1.1 christos x_parser_strcat (cfile, " {\n");
512 1.1 christos
513 1.1 christos if (hwaddr != NULL)
514 1.1 christos {
515 1.1 christos if (hwaddr[0] != NULL)
516 1.1 christos {
517 1.1 christos x_parser_strcat (cfile, "hardware ");
518 1.1 christos x_parser_strcat (cfile, hwaddr[0]->bv_val);
519 1.1 christos x_parser_strcat (cfile, ";\n");
520 1.1 christos }
521 1.1 christos ldap_value_free_len (hwaddr);
522 1.1 christos }
523 1.1 christos
524 1.1 christos item->close_brace = 1;
525 1.1 christos ldap_value_free_len (tempbv);
526 1.1 christos }
527 1.1 christos
528 1.1 christos
529 1.1 christos static void
530 1.1 christos ldap_parse_shared_network (struct ldap_config_stack *item, struct parse *cfile)
531 1.1 christos {
532 1.1 christos struct berval **tempbv;
533 1.1 christos
534 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
535 1.1 christos tempbv[0] == NULL)
536 1.1 christos {
537 1.1 christos if (tempbv != NULL)
538 1.1 christos ldap_value_free_len (tempbv);
539 1.1 christos
540 1.1 christos return;
541 1.1 christos }
542 1.1 christos
543 1.1 christos x_parser_strcat (cfile, "shared-network \"");
544 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
545 1.1 christos x_parser_strcat (cfile, "\" {\n");
546 1.1 christos
547 1.1 christos item->close_brace = 1;
548 1.1 christos ldap_value_free_len (tempbv);
549 1.1 christos }
550 1.1 christos
551 1.1 christos
552 1.1 christos static void
553 1.1 christos parse_netmask (int netmask, char *netmaskbuf)
554 1.1 christos {
555 1.1 christos unsigned long nm;
556 1.1 christos int i;
557 1.1 christos
558 1.1 christos nm = 0;
559 1.1 christos for (i=1; i <= netmask; i++)
560 1.1 christos {
561 1.1 christos nm |= 1 << (32 - i);
562 1.1 christos }
563 1.1 christos
564 1.1 christos sprintf (netmaskbuf, "%d.%d.%d.%d", (int) (nm >> 24) & 0xff,
565 1.1 christos (int) (nm >> 16) & 0xff,
566 1.1 christos (int) (nm >> 8) & 0xff,
567 1.1 christos (int) nm & 0xff);
568 1.1 christos }
569 1.1 christos
570 1.1 christos
571 1.1 christos static void
572 1.1 christos ldap_parse_subnet (struct ldap_config_stack *item, struct parse *cfile)
573 1.1 christos {
574 1.1 christos struct berval **tempbv, **netmaskstr;
575 1.1 christos char netmaskbuf[sizeof("255.255.255.255")];
576 1.1 christos int i;
577 1.1 christos
578 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
579 1.1 christos tempbv[0] == NULL)
580 1.1 christos {
581 1.1 christos if (tempbv != NULL)
582 1.1 christos ldap_value_free_len (tempbv);
583 1.1 christos
584 1.1 christos return;
585 1.1 christos }
586 1.1 christos
587 1.1 christos if ((netmaskstr = ldap_get_values_len (ld, item->ldent,
588 1.1 christos "dhcpNetmask")) == NULL ||
589 1.1 christos netmaskstr[0] == NULL)
590 1.1 christos {
591 1.1 christos if (netmaskstr != NULL)
592 1.1 christos ldap_value_free_len (netmaskstr);
593 1.1 christos ldap_value_free_len (tempbv);
594 1.1 christos
595 1.1 christos return;
596 1.1 christos }
597 1.1 christos
598 1.1 christos x_parser_strcat (cfile, "subnet ");
599 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
600 1.1 christos
601 1.1 christos x_parser_strcat (cfile, " netmask ");
602 1.1 christos parse_netmask (strtol (netmaskstr[0]->bv_val, NULL, 10), netmaskbuf);
603 1.1 christos x_parser_strcat (cfile, netmaskbuf);
604 1.1 christos
605 1.1 christos x_parser_strcat (cfile, " {\n");
606 1.1 christos
607 1.1 christos ldap_value_free_len (tempbv);
608 1.1 christos ldap_value_free_len (netmaskstr);
609 1.1 christos
610 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpRange")) != NULL)
611 1.1 christos {
612 1.1 christos for (i=0; tempbv[i] != NULL; i++)
613 1.1 christos {
614 1.1 christos x_parser_strcat (cfile, "range");
615 1.1 christos x_parser_strcat (cfile, " ");
616 1.1 christos x_parser_strcat (cfile, tempbv[i]->bv_val);
617 1.1 christos x_parser_strcat (cfile, ";\n");
618 1.1 christos }
619 1.1 christos ldap_value_free_len (tempbv);
620 1.1 christos }
621 1.1 christos
622 1.1 christos item->close_brace = 1;
623 1.1 christos }
624 1.1 christos
625 1.1 christos static void
626 1.1 christos ldap_parse_subnet6 (struct ldap_config_stack *item, struct parse *cfile)
627 1.1 christos {
628 1.1 christos struct berval **tempbv;
629 1.1 christos int i;
630 1.1 christos
631 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
632 1.1 christos tempbv[0] == NULL)
633 1.1 christos {
634 1.1 christos if (tempbv != NULL)
635 1.1 christos ldap_value_free_len (tempbv);
636 1.1 christos
637 1.1 christos return;
638 1.1 christos }
639 1.1 christos
640 1.1 christos x_parser_strcat (cfile, "subnet6 ");
641 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
642 1.1 christos
643 1.1 christos x_parser_strcat (cfile, " {\n");
644 1.1 christos
645 1.1 christos ldap_value_free_len (tempbv);
646 1.1 christos
647 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpRange6")) != NULL)
648 1.1 christos {
649 1.1 christos for (i=0; tempbv[i] != NULL; i++)
650 1.1 christos {
651 1.1 christos x_parser_strcat (cfile, "range6");
652 1.1 christos x_parser_strcat (cfile, " ");
653 1.1 christos x_parser_strcat (cfile, tempbv[i]->bv_val);
654 1.1 christos x_parser_strcat (cfile, ";\n");
655 1.1 christos }
656 1.1 christos ldap_value_free_len (tempbv);
657 1.1 christos }
658 1.1 christos
659 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpPermitList")) != NULL)
660 1.1 christos {
661 1.1 christos for (i=0; tempbv[i] != NULL; i++)
662 1.1 christos {
663 1.1 christos x_parser_strcat (cfile, tempbv[i]->bv_val);
664 1.1 christos x_parser_strcat (cfile, ";\n");
665 1.1 christos }
666 1.1 christos ldap_value_free_len (tempbv);
667 1.1 christos }
668 1.1 christos
669 1.1 christos item->close_brace = 1;
670 1.1 christos }
671 1.1 christos
672 1.1 christos static void
673 1.1 christos ldap_parse_pool (struct ldap_config_stack *item, struct parse *cfile)
674 1.1 christos {
675 1.1 christos struct berval **tempbv;
676 1.1 christos int i;
677 1.1 christos
678 1.1 christos x_parser_strcat (cfile, "pool {\n");
679 1.1 christos
680 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpRange")) != NULL)
681 1.1 christos {
682 1.1 christos x_parser_strcat (cfile, "range");
683 1.1 christos for (i=0; tempbv[i] != NULL; i++)
684 1.1 christos {
685 1.1 christos x_parser_strcat (cfile, " ");
686 1.1 christos x_parser_strcat (cfile, tempbv[i]->bv_val);
687 1.1 christos }
688 1.1 christos x_parser_strcat (cfile, ";\n");
689 1.1 christos ldap_value_free_len (tempbv);
690 1.1 christos }
691 1.1 christos
692 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpPermitList")) != NULL)
693 1.1 christos {
694 1.1 christos for (i=0; tempbv[i] != NULL; i++)
695 1.1 christos {
696 1.1 christos x_parser_strcat (cfile, tempbv[i]->bv_val);
697 1.1 christos x_parser_strcat (cfile, ";\n");
698 1.1 christos }
699 1.1 christos ldap_value_free_len (tempbv);
700 1.1 christos }
701 1.1 christos
702 1.1 christos item->close_brace = 1;
703 1.1 christos }
704 1.1 christos
705 1.1 christos static void
706 1.1 christos ldap_parse_pool6 (struct ldap_config_stack *item, struct parse *cfile)
707 1.1 christos {
708 1.1 christos struct berval **tempbv;
709 1.1 christos int i;
710 1.1 christos
711 1.1 christos x_parser_strcat (cfile, "pool6 {\n");
712 1.1 christos
713 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpRange6")) != NULL)
714 1.1 christos {
715 1.1 christos x_parser_strcat (cfile, "range6");
716 1.1 christos for (i=0; tempbv[i] != NULL; i++)
717 1.1 christos {
718 1.1 christos x_parser_strcat (cfile, " ");
719 1.1 christos x_parser_strcat (cfile, tempbv[i]->bv_val);
720 1.1 christos }
721 1.1 christos x_parser_strcat (cfile, ";\n");
722 1.1 christos ldap_value_free_len (tempbv);
723 1.1 christos }
724 1.1 christos
725 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpPermitList")) != NULL)
726 1.1 christos {
727 1.1 christos for (i=0; tempbv[i] != NULL; i++)
728 1.1 christos {
729 1.1 christos x_parser_strcat(cfile, tempbv[i]->bv_val);
730 1.1 christos x_parser_strcat (cfile, ";\n");
731 1.1 christos }
732 1.1 christos ldap_value_free_len (tempbv);
733 1.1 christos }
734 1.1 christos
735 1.1 christos item->close_brace = 1;
736 1.1 christos }
737 1.1 christos
738 1.1 christos static void
739 1.1 christos ldap_parse_group (struct ldap_config_stack *item, struct parse *cfile)
740 1.1 christos {
741 1.1 christos x_parser_strcat (cfile, "group {\n");
742 1.1 christos item->close_brace = 1;
743 1.1 christos }
744 1.1 christos
745 1.1 christos
746 1.1 christos static void
747 1.1 christos ldap_parse_key (struct ldap_config_stack *item, struct parse *cfile)
748 1.1 christos {
749 1.1 christos struct berval **tempbv;
750 1.1 christos
751 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) != NULL)
752 1.1 christos {
753 1.1 christos x_parser_strcat (cfile, "key ");
754 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
755 1.1 christos x_parser_strcat (cfile, " {\n");
756 1.1 christos ldap_value_free_len (tempbv);
757 1.1 christos }
758 1.1 christos
759 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpKeyAlgorithm")) != NULL)
760 1.1 christos {
761 1.1 christos x_parser_strcat (cfile, "algorithm ");
762 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
763 1.1 christos x_parser_strcat (cfile, ";\n");
764 1.1 christos ldap_value_free_len (tempbv);
765 1.1 christos }
766 1.1 christos
767 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpKeySecret")) != NULL)
768 1.1 christos {
769 1.1 christos x_parser_strcat (cfile, "secret ");
770 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
771 1.1 christos x_parser_strcat (cfile, ";\n");
772 1.1 christos ldap_value_free_len (tempbv);
773 1.1 christos }
774 1.1 christos
775 1.1 christos item->close_brace = 1;
776 1.1 christos }
777 1.1 christos
778 1.1 christos
779 1.1 christos static void
780 1.1 christos ldap_parse_zone (struct ldap_config_stack *item, struct parse *cfile)
781 1.1 christos {
782 1.1 christos char *cnFindStart, *cnFindEnd;
783 1.1 christos struct berval **tempbv;
784 1.1 christos char *keyCn;
785 1.1 christos size_t len;
786 1.1 christos
787 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) != NULL)
788 1.1 christos {
789 1.1 christos x_parser_strcat (cfile, "zone ");
790 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
791 1.1 christos x_parser_strcat (cfile, " {\n");
792 1.1 christos ldap_value_free_len (tempbv);
793 1.1 christos }
794 1.1 christos
795 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpDnsZoneServer")) != NULL)
796 1.1 christos {
797 1.1 christos x_parser_strcat (cfile, "primary ");
798 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
799 1.1 christos
800 1.1 christos x_parser_strcat (cfile, ";\n");
801 1.1 christos ldap_value_free_len (tempbv);
802 1.1 christos }
803 1.1 christos
804 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpKeyDN")) != NULL)
805 1.1 christos {
806 1.1 christos cnFindStart = strchr(tempbv[0]->bv_val,'=');
807 1.1 christos if (cnFindStart != NULL)
808 1.1 christos cnFindEnd = strchr(++cnFindStart,',');
809 1.1 christos else
810 1.1 christos cnFindEnd = NULL;
811 1.1 christos
812 1.1 christos if (cnFindEnd != NULL && cnFindEnd > cnFindStart)
813 1.1 christos {
814 1.1 christos len = cnFindEnd - cnFindStart;
815 1.1 christos keyCn = dmalloc (len + 1, MDL);
816 1.1 christos }
817 1.1 christos else
818 1.1 christos {
819 1.1 christos len = 0;
820 1.1 christos keyCn = NULL;
821 1.1 christos }
822 1.1 christos
823 1.1 christos if (keyCn != NULL)
824 1.1 christos {
825 1.1 christos strncpy (keyCn, cnFindStart, len);
826 1.1 christos keyCn[len] = '\0';
827 1.1 christos
828 1.1 christos x_parser_strcat (cfile, "key ");
829 1.1 christos x_parser_strcat (cfile, keyCn);
830 1.1 christos x_parser_strcat (cfile, ";\n");
831 1.1 christos
832 1.1 christos dfree (keyCn, MDL);
833 1.1 christos }
834 1.1 christos
835 1.1 christos ldap_value_free_len (tempbv);
836 1.1 christos }
837 1.1 christos
838 1.1 christos item->close_brace = 1;
839 1.1 christos }
840 1.1 christos
841 1.1 christos #if defined(HAVE_IFADDRS_H)
842 1.1 christos static void
843 1.1 christos ldap_parse_failover (struct ldap_config_stack *item, struct parse *cfile)
844 1.1 christos {
845 1.1 christos struct berval **tempbv, **peername;
846 1.1 christos struct ifaddrs *addrs = NULL;
847 1.1 christos char srvaddr[2][64] = {"\0", "\0"};
848 1.1 christos int primary, split = 0, match;
849 1.1 christos
850 1.1 christos if ((peername = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
851 1.1 christos peername[0] == NULL)
852 1.1 christos {
853 1.1 christos if (peername != NULL)
854 1.1 christos ldap_value_free_len (peername);
855 1.1 christos
856 1.1 christos // ldap with disabled schema checks? fail to avoid syntax error.
857 1.1 christos log_error("Unable to find mandatory failover peering name attribute");
858 1.1 christos return;
859 1.1 christos }
860 1.1 christos
861 1.1 christos /* Get all interface addresses */
862 1.1 christos getifaddrs(&addrs);
863 1.1 christos
864 1.1 christos /*
865 1.1 christos ** when dhcpFailOverPrimaryServer or dhcpFailOverSecondaryServer
866 1.1 christos ** matches one of our IP address, the following valiables are set:
867 1.1 christos ** - primary is 1 when we are primary or 0 when we are secondary
868 1.1 christos ** - srvaddr[0] contains ip address of the primary
869 1.1 christos ** - srvaddr[1] contains ip address of the secondary
870 1.1 christos */
871 1.1 christos primary = -1;
872 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverPrimaryServer")) != NULL &&
873 1.1 christos tempbv[0] != NULL)
874 1.1 christos {
875 1.1 christos match = get_host_address (tempbv[0]->bv_val, srvaddr[0], sizeof(srvaddr[0]), addrs);
876 1.1 christos if (match >= 0)
877 1.1 christos {
878 1.1 christos /* we are the primary */
879 1.1 christos if (match > 0)
880 1.1 christos primary = 1;
881 1.1 christos }
882 1.1 christos else
883 1.1 christos {
884 1.1 christos log_info("Can't resolve address of the primary failover '%s' server %s",
885 1.1 christos peername[0]->bv_val, tempbv[0]->bv_val);
886 1.1 christos ldap_value_free_len (tempbv);
887 1.1 christos ldap_value_free_len (peername);
888 1.1 christos if (addrs)
889 1.1 christos freeifaddrs(addrs);
890 1.1 christos return;
891 1.1 christos }
892 1.1 christos }
893 1.1 christos if (tempbv != NULL)
894 1.1 christos ldap_value_free_len (tempbv);
895 1.1 christos
896 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverSecondaryServer")) != NULL &&
897 1.1 christos tempbv[0] != NULL)
898 1.1 christos {
899 1.1 christos match = get_host_address (tempbv[0]->bv_val, srvaddr[1], sizeof(srvaddr[1]), addrs);
900 1.1 christos if (match >= 0)
901 1.1 christos {
902 1.1 christos if (match > 0)
903 1.1 christos {
904 1.1 christos if (primary == 1)
905 1.1 christos {
906 1.1 christos log_info("Both, primary and secondary failover '%s' server"
907 1.1 christos " attributes match our local address", peername[0]->bv_val);
908 1.1 christos ldap_value_free_len (tempbv);
909 1.1 christos ldap_value_free_len (peername);
910 1.1 christos if (addrs)
911 1.1 christos freeifaddrs(addrs);
912 1.1 christos return;
913 1.1 christos }
914 1.1 christos
915 1.1 christos /* we are the secondary */
916 1.1 christos primary = 0;
917 1.1 christos }
918 1.1 christos }
919 1.1 christos else
920 1.1 christos {
921 1.1 christos log_info("Can't resolve address of the secondary failover '%s' server %s",
922 1.1 christos peername[0]->bv_val, tempbv[0]->bv_val);
923 1.1 christos ldap_value_free_len (tempbv);
924 1.1 christos ldap_value_free_len (peername);
925 1.1 christos if (addrs)
926 1.1 christos freeifaddrs(addrs);
927 1.1 christos return;
928 1.1 christos }
929 1.1 christos }
930 1.1 christos if (tempbv != NULL)
931 1.1 christos ldap_value_free_len (tempbv);
932 1.1 christos
933 1.1 christos
934 1.3 christos if (primary == -1 || *srvaddr[0] == '\0' || *srvaddr[1] == '\0')
935 1.1 christos {
936 1.1 christos log_error("Could not decide if the server type is primary"
937 1.1 christos " or secondary for failover peering '%s'.", peername[0]->bv_val);
938 1.1 christos ldap_value_free_len (peername);
939 1.1 christos if (addrs)
940 1.1 christos freeifaddrs(addrs);
941 1.1 christos return;
942 1.1 christos }
943 1.1 christos
944 1.1 christos x_parser_strcat (cfile, "failover peer \"");
945 1.1 christos x_parser_strcat (cfile, peername[0]->bv_val);
946 1.1 christos x_parser_strcat (cfile, "\" {\n");
947 1.1 christos
948 1.1 christos if (primary)
949 1.1 christos x_parser_strcat (cfile, "primary;\n");
950 1.1 christos else
951 1.1 christos x_parser_strcat (cfile, "secondary;\n");
952 1.1 christos
953 1.1 christos x_parser_strcat (cfile, "address ");
954 1.1 christos if (primary)
955 1.1 christos x_parser_strcat (cfile, srvaddr[0]);
956 1.1 christos else
957 1.1 christos x_parser_strcat (cfile, srvaddr[1]);
958 1.1 christos x_parser_strcat (cfile, ";\n");
959 1.1 christos
960 1.1 christos x_parser_strcat (cfile, "peer address ");
961 1.1 christos if (primary)
962 1.1 christos x_parser_strcat (cfile, srvaddr[1]);
963 1.1 christos else
964 1.1 christos x_parser_strcat (cfile, srvaddr[0]);
965 1.1 christos x_parser_strcat (cfile, ";\n");
966 1.1 christos
967 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverPrimaryPort")) != NULL &&
968 1.1 christos tempbv[0] != NULL)
969 1.1 christos {
970 1.1 christos if (primary)
971 1.1 christos x_parser_strcat (cfile, "port ");
972 1.1 christos else
973 1.1 christos x_parser_strcat (cfile, "peer port ");
974 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
975 1.1 christos x_parser_strcat (cfile, ";\n");
976 1.1 christos }
977 1.1 christos if (tempbv != NULL)
978 1.1 christos ldap_value_free_len (tempbv);
979 1.1 christos
980 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverSecondaryPort")) != NULL &&
981 1.1 christos tempbv[0] != NULL)
982 1.1 christos {
983 1.1 christos if (primary)
984 1.1 christos x_parser_strcat (cfile, "peer port ");
985 1.1 christos else
986 1.1 christos x_parser_strcat (cfile, "port ");
987 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
988 1.1 christos x_parser_strcat (cfile, ";\n");
989 1.1 christos }
990 1.1 christos if (tempbv != NULL)
991 1.1 christos ldap_value_free_len (tempbv);
992 1.1 christos
993 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverResponseDelay")) != NULL &&
994 1.1 christos tempbv[0] != NULL)
995 1.1 christos {
996 1.1 christos x_parser_strcat (cfile, "max-response-delay ");
997 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
998 1.1 christos x_parser_strcat (cfile, ";\n");
999 1.1 christos }
1000 1.1 christos if (tempbv != NULL)
1001 1.1 christos ldap_value_free_len (tempbv);
1002 1.1 christos
1003 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverUnackedUpdates")) != NULL &&
1004 1.1 christos tempbv[0] != NULL)
1005 1.1 christos {
1006 1.1 christos x_parser_strcat (cfile, "max-unacked-updates ");
1007 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
1008 1.1 christos x_parser_strcat (cfile, ";\n");
1009 1.1 christos }
1010 1.1 christos if (tempbv != NULL)
1011 1.1 christos ldap_value_free_len (tempbv);
1012 1.1 christos
1013 1.1 christos if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverLoadBalanceTime")) != NULL &&
1014 1.1 christos tempbv[0] != NULL)
1015 1.1 christos {
1016 1.1 christos x_parser_strcat (cfile, "load balance max seconds ");
1017 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
1018 1.1 christos x_parser_strcat (cfile, ";\n");
1019 1.1 christos }
1020 1.1 christos if (tempbv != NULL)
1021 1.1 christos ldap_value_free_len (tempbv);
1022 1.1 christos
1023 1.1 christos tempbv = NULL;
1024 1.1 christos if (primary &&
1025 1.1 christos (tempbv = ldap_get_values_len (ld, item->ldent, "dhcpMaxClientLeadTime")) != NULL &&
1026 1.1 christos tempbv[0] != NULL)
1027 1.1 christos {
1028 1.1 christos x_parser_strcat (cfile, "mclt ");
1029 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
1030 1.1 christos x_parser_strcat (cfile, ";\n");
1031 1.1 christos }
1032 1.1 christos if (tempbv != NULL)
1033 1.1 christos ldap_value_free_len (tempbv);
1034 1.1 christos
1035 1.1 christos tempbv = NULL;
1036 1.1 christos if (primary &&
1037 1.1 christos (tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverSplit")) != NULL &&
1038 1.1 christos tempbv[0] != NULL)
1039 1.1 christos {
1040 1.1 christos x_parser_strcat (cfile, "split ");
1041 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
1042 1.1 christos x_parser_strcat (cfile, ";\n");
1043 1.1 christos split = 1;
1044 1.1 christos }
1045 1.1 christos if (tempbv != NULL)
1046 1.1 christos ldap_value_free_len (tempbv);
1047 1.1 christos
1048 1.1 christos tempbv = NULL;
1049 1.1 christos if (primary && !split &&
1050 1.1 christos (tempbv = ldap_get_values_len (ld, item->ldent, "dhcpFailOverHashBucketAssignment")) != NULL &&
1051 1.1 christos tempbv[0] != NULL)
1052 1.1 christos {
1053 1.1 christos x_parser_strcat (cfile, "hba ");
1054 1.1 christos x_parser_strcat (cfile, tempbv[0]->bv_val);
1055 1.1 christos x_parser_strcat (cfile, ";\n");
1056 1.1 christos }
1057 1.1 christos if (tempbv != NULL)
1058 1.1 christos ldap_value_free_len (tempbv);
1059 1.1 christos
1060 1.1 christos item->close_brace = 1;
1061 1.1 christos }
1062 1.1 christos #endif /* HAVE_IFADDRS_H */
1063 1.1 christos
1064 1.1 christos static void
1065 1.1 christos add_to_config_stack (LDAPMessage * res, LDAPMessage * ent)
1066 1.1 christos {
1067 1.1 christos struct ldap_config_stack *ns;
1068 1.1 christos
1069 1.1 christos ns = dmalloc (sizeof (*ns), MDL);
1070 1.1 christos if (!ns) {
1071 1.1 christos log_fatal ("no memory for add_to_config_stack()");
1072 1.1 christos }
1073 1.1 christos
1074 1.1 christos ns->res = res;
1075 1.1 christos ns->ldent = ent;
1076 1.1 christos ns->close_brace = 0;
1077 1.1 christos ns->processed = 0;
1078 1.1 christos ns->next = ldap_stack;
1079 1.1 christos ldap_stack = ns;
1080 1.1 christos }
1081 1.1 christos
1082 1.1 christos static void
1083 1.1 christos ldap_stop()
1084 1.1 christos {
1085 1.1 christos struct sigaction old, new;
1086 1.1 christos
1087 1.1 christos if (ld == NULL)
1088 1.1 christos return;
1089 1.1 christos
1090 1.1 christos /*
1091 1.1 christos ** ldap_unbind after a LDAP_SERVER_DOWN result
1092 1.1 christos ** causes a SIGPIPE and dhcpd gets terminated,
1093 1.1 christos ** since it doesn't handle it...
1094 1.1 christos */
1095 1.1 christos
1096 1.1 christos new.sa_flags = 0;
1097 1.1 christos new.sa_handler = SIG_IGN;
1098 1.1 christos sigemptyset (&new.sa_mask);
1099 1.1 christos sigaction (SIGPIPE, &new, &old);
1100 1.1 christos
1101 1.1 christos ldap_unbind_ext_s (ld, NULL, NULL);
1102 1.1 christos ld = NULL;
1103 1.1 christos
1104 1.1 christos sigaction (SIGPIPE, &old, &new);
1105 1.1 christos }
1106 1.1 christos
1107 1.1 christos
1108 1.1 christos static char *
1109 1.1 christos _do_lookup_dhcp_string_option (struct option_state *options, int option_name)
1110 1.1 christos {
1111 1.1 christos struct option_cache *oc;
1112 1.1 christos struct data_string db;
1113 1.1 christos char *ret;
1114 1.1 christos
1115 1.1 christos memset (&db, 0, sizeof (db));
1116 1.1 christos oc = lookup_option (&server_universe, options, option_name);
1117 1.1 christos if (oc &&
1118 1.1 christos evaluate_option_cache (&db, (struct packet*) NULL,
1119 1.1 christos (struct lease *) NULL,
1120 1.1 christos (struct client_state *) NULL, options,
1121 1.1 christos (struct option_state *) NULL,
1122 1.1 christos &global_scope, oc, MDL) &&
1123 1.1 christos db.data != NULL && *db.data != '\0')
1124 1.1 christos
1125 1.1 christos {
1126 1.1 christos ret = dmalloc (db.len + 1, MDL);
1127 1.1 christos if (ret == NULL)
1128 1.1 christos log_fatal ("no memory for ldap option %d value", option_name);
1129 1.1 christos
1130 1.1 christos memcpy (ret, db.data, db.len);
1131 1.1 christos ret[db.len] = 0;
1132 1.1 christos data_string_forget (&db, MDL);
1133 1.1 christos }
1134 1.1 christos else
1135 1.1 christos ret = NULL;
1136 1.1 christos
1137 1.1 christos return (ret);
1138 1.1 christos }
1139 1.1 christos
1140 1.1 christos
1141 1.1 christos static int
1142 1.1 christos _do_lookup_dhcp_int_option (struct option_state *options, int option_name)
1143 1.1 christos {
1144 1.1 christos struct option_cache *oc;
1145 1.1 christos struct data_string db;
1146 1.3 christos int ret = 0;
1147 1.1 christos
1148 1.1 christos memset (&db, 0, sizeof (db));
1149 1.1 christos oc = lookup_option (&server_universe, options, option_name);
1150 1.1 christos if (oc &&
1151 1.1 christos evaluate_option_cache (&db, (struct packet*) NULL,
1152 1.1 christos (struct lease *) NULL,
1153 1.1 christos (struct client_state *) NULL, options,
1154 1.1 christos (struct option_state *) NULL,
1155 1.1 christos &global_scope, oc, MDL) &&
1156 1.3 christos db.data != NULL)
1157 1.1 christos {
1158 1.3 christos if (db.len == 4) {
1159 1.3 christos ret = getULong(db.data);
1160 1.3 christos }
1161 1.3 christos
1162 1.1 christos data_string_forget (&db, MDL);
1163 1.1 christos }
1164 1.1 christos
1165 1.1 christos return (ret);
1166 1.1 christos }
1167 1.1 christos
1168 1.1 christos
1169 1.1 christos static int
1170 1.1 christos _do_lookup_dhcp_enum_option (struct option_state *options, int option_name)
1171 1.1 christos {
1172 1.1 christos struct option_cache *oc;
1173 1.1 christos struct data_string db;
1174 1.1 christos int ret = -1;
1175 1.1 christos
1176 1.1 christos memset (&db, 0, sizeof (db));
1177 1.1 christos oc = lookup_option (&server_universe, options, option_name);
1178 1.1 christos if (oc &&
1179 1.1 christos evaluate_option_cache (&db, (struct packet*) NULL,
1180 1.1 christos (struct lease *) NULL,
1181 1.1 christos (struct client_state *) NULL, options,
1182 1.1 christos (struct option_state *) NULL,
1183 1.1 christos &global_scope, oc, MDL) &&
1184 1.1 christos db.data != NULL && *db.data != '\0')
1185 1.1 christos {
1186 1.1 christos if (db.len == 1)
1187 1.1 christos ret = db.data [0];
1188 1.1 christos else
1189 1.1 christos log_fatal ("invalid option name %d", option_name);
1190 1.1 christos
1191 1.1 christos data_string_forget (&db, MDL);
1192 1.1 christos }
1193 1.1 christos else
1194 1.1 christos ret = 0;
1195 1.1 christos
1196 1.1 christos return (ret);
1197 1.1 christos }
1198 1.1 christos
1199 1.1 christos int
1200 1.1 christos ldap_rebind_cb (LDAP *ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *parms)
1201 1.1 christos {
1202 1.1 christos int ret;
1203 1.1 christos LDAPURLDesc *ldapurl = NULL;
1204 1.1 christos char *who = NULL;
1205 1.1 christos struct berval creds;
1206 1.1 christos
1207 1.1 christos log_info("LDAP rebind to '%s'", url);
1208 1.1 christos if ((ret = ldap_url_parse(url, &ldapurl)) != LDAP_SUCCESS)
1209 1.1 christos {
1210 1.1 christos log_error ("Error: Can not parse ldap rebind url '%s': %s",
1211 1.1 christos url, ldap_err2string(ret));
1212 1.1 christos return ret;
1213 1.1 christos }
1214 1.1 christos
1215 1.1 christos
1216 1.1 christos #if defined (LDAP_USE_SSL)
1217 1.1 christos if (strcasecmp(ldapurl->lud_scheme, "ldaps") == 0)
1218 1.1 christos {
1219 1.1 christos int opt = LDAP_OPT_X_TLS_HARD;
1220 1.1 christos if ((ret = ldap_set_option (ld, LDAP_OPT_X_TLS, &opt)) != LDAP_SUCCESS)
1221 1.1 christos {
1222 1.1 christos log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
1223 1.1 christos ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret));
1224 1.1 christos ldap_free_urldesc(ldapurl);
1225 1.1 christos return ret;
1226 1.1 christos }
1227 1.1 christos else
1228 1.1 christos {
1229 1.1 christos log_info ("LDAPS session successfully enabled to %s", ldap_server);
1230 1.1 christos }
1231 1.1 christos }
1232 1.1 christos else
1233 1.1 christos if (strcasecmp(ldapurl->lud_scheme, "ldap") == 0 &&
1234 1.1 christos ldap_use_ssl != LDAP_SSL_OFF)
1235 1.1 christos {
1236 1.1 christos if ((ret = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS)
1237 1.1 christos {
1238 1.1 christos log_error ("Error: Cannot start TLS session to %s:%d: %s",
1239 1.1 christos ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret));
1240 1.1 christos ldap_free_urldesc(ldapurl);
1241 1.1 christos return ret;
1242 1.1 christos }
1243 1.1 christos else
1244 1.1 christos {
1245 1.1 christos log_info ("TLS session successfully started to %s:%d",
1246 1.1 christos ldapurl->lud_host, ldapurl->lud_port);
1247 1.1 christos }
1248 1.1 christos }
1249 1.1 christos #endif
1250 1.1 christos
1251 1.1 christos #if defined(LDAP_USE_GSSAPI)
1252 1.1 christos if (ldap_gssapi_principal != NULL) {
1253 1.1 christos krb5_get_tgt(ldap_gssapi_principal, ldap_gssapi_keytab);
1254 1.1 christos if ((ret = ldap_sasl_interactive_bind_s(ld, NULL, ldap_sasl_inst->sasl_mech,
1255 1.1 christos NULL, NULL, LDAP_SASL_AUTOMATIC,
1256 1.1 christos _ldap_sasl_interact, ldap_sasl_inst)
1257 1.1 christos ) != LDAP_SUCCESS)
1258 1.1 christos {
1259 1.1 christos log_error ("Error: Cannot SASL bind to ldap server %s:%d: %s",
1260 1.1 christos ldap_server, ldap_port, ldap_err2string (ret));
1261 1.1 christos char *msg=NULL;
1262 1.1 christos ldap_get_option( ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*)&msg);
1263 1.1 christos log_error ("\tAdditional info: %s", msg);
1264 1.1 christos ldap_memfree(msg);
1265 1.1 christos ldap_stop();
1266 1.1 christos }
1267 1.1 christos
1268 1.1 christos ldap_free_urldesc(ldapurl);
1269 1.1 christos return ret;
1270 1.1 christos }
1271 1.1 christos #endif
1272 1.1 christos
1273 1.1 christos if (ldap_username != NULL && *ldap_username != '\0' && ldap_password != NULL)
1274 1.1 christos {
1275 1.1 christos who = ldap_username;
1276 1.1 christos creds.bv_val = strdup(ldap_password);
1277 1.1 christos if (creds.bv_val == NULL)
1278 1.1 christos log_fatal ("Error: Unable to allocate memory to duplicate ldap_password");
1279 1.1 christos
1280 1.1 christos creds.bv_len = strlen(ldap_password);
1281 1.1 christos
1282 1.1 christos if ((ret = ldap_sasl_bind_s (ld, who, LDAP_SASL_SIMPLE, &creds,
1283 1.1 christos NULL, NULL, NULL)) != LDAP_SUCCESS)
1284 1.1 christos {
1285 1.1 christos log_error ("Error: Cannot login into ldap server %s:%d: %s",
1286 1.1 christos ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret));
1287 1.1 christos }
1288 1.1 christos
1289 1.1 christos if (creds.bv_val)
1290 1.1 christos free(creds.bv_val);
1291 1.1 christos }
1292 1.1 christos
1293 1.1 christos ldap_free_urldesc(ldapurl);
1294 1.1 christos return ret;
1295 1.1 christos }
1296 1.1 christos
1297 1.1 christos static int
1298 1.1 christos _do_ldap_retry(int ret, const char *server, int port)
1299 1.1 christos {
1300 1.1 christos static int inform = 1;
1301 1.1 christos
1302 1.1 christos if (ldap_enable_retry > 0 && ret == LDAP_SERVER_DOWN && ldap_init_retry > 0)
1303 1.1 christos {
1304 1.1 christos if (inform || (ldap_init_retry % 10) == 0)
1305 1.1 christos {
1306 1.1 christos inform = 0;
1307 1.1 christos log_info ("Can't contact LDAP server %s:%d: retrying for %d sec",
1308 1.1 christos server, port, ldap_init_retry);
1309 1.1 christos }
1310 1.1 christos sleep(1);
1311 1.1 christos return ldap_init_retry--;
1312 1.1 christos }
1313 1.1 christos return 0;
1314 1.1 christos }
1315 1.1 christos
1316 1.1 christos static struct berval *
1317 1.1 christos _do_ldap_str2esc_filter_bv(const char *str, ber_len_t len, struct berval *bv_o)
1318 1.1 christos {
1319 1.1 christos struct berval bv_i;
1320 1.1 christos
1321 1.1 christos if (!str || !bv_o || (ber_str2bv(str, len, 0, &bv_i) == NULL) ||
1322 1.1 christos (ldap_bv2escaped_filter_value(&bv_i, bv_o) != 0))
1323 1.1 christos return NULL;
1324 1.1 christos return bv_o;
1325 1.1 christos }
1326 1.1 christos
1327 1.1 christos static void
1328 1.1 christos ldap_start (void)
1329 1.1 christos {
1330 1.1 christos struct option_state *options;
1331 1.1 christos int ret, version;
1332 1.1 christos char *uri = NULL;
1333 1.1 christos struct berval creds;
1334 1.1 christos #if defined(LDAP_USE_GSSAPI)
1335 1.1 christos char *gssapi_realm = NULL;
1336 1.1 christos char *gssapi_user = NULL;
1337 1.1 christos char *running = NULL;
1338 1.1 christos const char *gssapi_delim = "@";
1339 1.1 christos #endif
1340 1.1 christos
1341 1.1 christos if (ld != NULL)
1342 1.1 christos return;
1343 1.1 christos
1344 1.1 christos if (ldap_server == NULL)
1345 1.1 christos {
1346 1.1 christos options = NULL;
1347 1.1 christos option_state_allocate (&options, MDL);
1348 1.1 christos
1349 1.1 christos execute_statements_in_scope (NULL, NULL, NULL, NULL, NULL,
1350 1.1 christos options, &global_scope, root_group,
1351 1.1 christos NULL, NULL);
1352 1.1 christos
1353 1.1 christos ldap_server = _do_lookup_dhcp_string_option (options, SV_LDAP_SERVER);
1354 1.1 christos ldap_dhcp_server_cn = _do_lookup_dhcp_string_option (options,
1355 1.1 christos SV_LDAP_DHCP_SERVER_CN);
1356 1.1 christos ldap_port = _do_lookup_dhcp_int_option (options, SV_LDAP_PORT);
1357 1.1 christos ldap_base_dn = _do_lookup_dhcp_string_option (options, SV_LDAP_BASE_DN);
1358 1.1 christos ldap_method = _do_lookup_dhcp_enum_option (options, SV_LDAP_METHOD);
1359 1.1 christos ldap_debug_file = _do_lookup_dhcp_string_option (options,
1360 1.1 christos SV_LDAP_DEBUG_FILE);
1361 1.1 christos ldap_referrals = _do_lookup_dhcp_enum_option (options, SV_LDAP_REFERRALS);
1362 1.1 christos ldap_init_retry = _do_lookup_dhcp_int_option (options, SV_LDAP_INIT_RETRY);
1363 1.1 christos
1364 1.1 christos #if defined (LDAP_USE_SSL)
1365 1.1 christos ldap_use_ssl = _do_lookup_dhcp_enum_option (options, SV_LDAP_SSL);
1366 1.1 christos if( ldap_use_ssl != LDAP_SSL_OFF)
1367 1.1 christos {
1368 1.1 christos ldap_tls_reqcert = _do_lookup_dhcp_enum_option (options, SV_LDAP_TLS_REQCERT);
1369 1.1 christos ldap_tls_ca_file = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CA_FILE);
1370 1.1 christos ldap_tls_ca_dir = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CA_DIR);
1371 1.1 christos ldap_tls_cert = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CERT);
1372 1.1 christos ldap_tls_key = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_KEY);
1373 1.1 christos ldap_tls_crlcheck = _do_lookup_dhcp_enum_option (options, SV_LDAP_TLS_CRLCHECK);
1374 1.1 christos ldap_tls_ciphers = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CIPHERS);
1375 1.1 christos ldap_tls_randfile = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_RANDFILE);
1376 1.1 christos }
1377 1.1 christos #endif
1378 1.1 christos
1379 1.1 christos #if defined (LDAP_USE_GSSAPI)
1380 1.1 christos ldap_gssapi_principal = _do_lookup_dhcp_string_option (options,
1381 1.1 christos SV_LDAP_GSSAPI_PRINCIPAL);
1382 1.1 christos
1383 1.1 christos if (ldap_gssapi_principal == NULL) {
1384 1.1 christos log_error("ldap_gssapi_principal is not set,"
1385 1.1 christos "GSSAPI Authentication for LDAP will not be used");
1386 1.1 christos } else {
1387 1.1 christos ldap_gssapi_keytab = _do_lookup_dhcp_string_option (options,
1388 1.1 christos SV_LDAP_GSSAPI_KEYTAB);
1389 1.1 christos if (ldap_gssapi_keytab == NULL) {
1390 1.1 christos log_fatal("ldap_gssapi_keytab must be specified");
1391 1.1 christos }
1392 1.1 christos
1393 1.1 christos running = strdup(ldap_gssapi_principal);
1394 1.1 christos if (running == NULL)
1395 1.1 christos log_fatal("Could not allocate memory to duplicate gssapi principal");
1396 1.1 christos
1397 1.1 christos gssapi_user = strtok(running, gssapi_delim);
1398 1.1 christos if (!gssapi_user || strlen(gssapi_user) == 0) {
1399 1.1 christos log_fatal ("GSSAPI principal must specify user: user@realm");
1400 1.1 christos }
1401 1.1 christos
1402 1.1 christos gssapi_realm = strtok(NULL, gssapi_delim);
1403 1.1 christos if (!gssapi_realm || strlen(gssapi_realm) == 0) {
1404 1.1 christos log_fatal ("GSSAPI principal must specify realm: user@realm");
1405 1.1 christos }
1406 1.1 christos
1407 1.1 christos ldap_sasl_inst = malloc(sizeof(struct ldap_sasl_instance));
1408 1.1 christos if (ldap_sasl_inst == NULL)
1409 1.1 christos log_fatal("Could not allocate memory for sasl instance! Can not run!");
1410 1.1 christos
1411 1.1 christos ldap_sasl_inst->sasl_mech = ber_strdup("GSSAPI");
1412 1.1 christos if (ldap_sasl_inst->sasl_mech == NULL)
1413 1.1 christos log_fatal("Could not allocate memory to duplicate gssapi mechanism");
1414 1.1 christos
1415 1.1 christos ldap_sasl_inst->sasl_realm = ber_strdup(gssapi_realm);
1416 1.1 christos if (ldap_sasl_inst->sasl_realm == NULL)
1417 1.1 christos log_fatal("Could not allocate memory to duplicate gssapi realm");
1418 1.1 christos
1419 1.1 christos ldap_sasl_inst->sasl_authz_id = ber_strdup(gssapi_user);
1420 1.1 christos if (ldap_sasl_inst->sasl_authz_id == NULL)
1421 1.1 christos log_fatal("Could not allocate memory to duplicate gssapi user");
1422 1.1 christos
1423 1.1 christos ldap_sasl_inst->sasl_authc_id = NULL;
1424 1.1 christos ldap_sasl_inst->sasl_password = NULL; //"" before
1425 1.1 christos free(running);
1426 1.1 christos }
1427 1.1 christos #endif
1428 1.1 christos
1429 1.1 christos #if defined (LDAP_CASA_AUTH)
1430 1.1 christos if (!load_uname_pwd_from_miCASA(&ldap_username,&ldap_password))
1431 1.1 christos {
1432 1.1 christos #if defined (DEBUG_LDAP)
1433 1.1 christos log_info ("Authentication credential taken from file");
1434 1.1 christos #endif
1435 1.1 christos #endif
1436 1.1 christos
1437 1.1 christos ldap_username = _do_lookup_dhcp_string_option (options, SV_LDAP_USERNAME);
1438 1.1 christos ldap_password = _do_lookup_dhcp_string_option (options, SV_LDAP_PASSWORD);
1439 1.1 christos
1440 1.1 christos #if defined (LDAP_CASA_AUTH)
1441 1.1 christos }
1442 1.1 christos #endif
1443 1.1 christos
1444 1.1 christos option_state_dereference (&options, MDL);
1445 1.1 christos }
1446 1.1 christos
1447 1.1 christos if (ldap_server == NULL || ldap_base_dn == NULL)
1448 1.1 christos {
1449 1.1 christos log_info ("Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not specified in the config file");
1450 1.1 christos ldap_method = LDAP_METHOD_STATIC;
1451 1.1 christos return;
1452 1.1 christos }
1453 1.1 christos
1454 1.1 christos if (ldap_debug_file != NULL && ldap_debug_fd == -1)
1455 1.1 christos {
1456 1.1 christos if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY,
1457 1.1 christos S_IRUSR | S_IWUSR)) < 0)
1458 1.1 christos log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file,
1459 1.1 christos strerror (errno));
1460 1.1 christos }
1461 1.1 christos
1462 1.1 christos #if defined (DEBUG_LDAP)
1463 1.1 christos log_info ("Connecting to LDAP server %s:%d", ldap_server, ldap_port);
1464 1.1 christos #endif
1465 1.1 christos
1466 1.1 christos #if defined (LDAP_USE_SSL)
1467 1.1 christos if (ldap_use_ssl == -1)
1468 1.1 christos {
1469 1.1 christos /*
1470 1.1 christos ** There was no "ldap-ssl" option in dhcpd.conf (also not "off").
1471 1.1 christos ** Let's try, if we can use an anonymous TLS session without to
1472 1.1 christos ** verify the server certificate -- if not continue without TLS.
1473 1.1 christos */
1474 1.1 christos int opt = LDAP_OPT_X_TLS_ALLOW;
1475 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
1476 1.1 christos &opt)) != LDAP_SUCCESS)
1477 1.1 christos {
1478 1.1 christos log_error ("Warning: Cannot set LDAP TLS require cert option to 'allow': %s",
1479 1.1 christos ldap_err2string (ret));
1480 1.1 christos }
1481 1.1 christos }
1482 1.1 christos
1483 1.1 christos if (ldap_use_ssl != LDAP_SSL_OFF)
1484 1.1 christos {
1485 1.1 christos if (ldap_tls_reqcert != -1)
1486 1.1 christos {
1487 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
1488 1.1 christos &ldap_tls_reqcert)) != LDAP_SUCCESS)
1489 1.1 christos {
1490 1.1 christos log_error ("Cannot set LDAP TLS require cert option: %s",
1491 1.1 christos ldap_err2string (ret));
1492 1.1 christos }
1493 1.1 christos }
1494 1.1 christos
1495 1.1 christos if( ldap_tls_ca_file != NULL)
1496 1.1 christos {
1497 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE,
1498 1.1 christos ldap_tls_ca_file)) != LDAP_SUCCESS)
1499 1.1 christos {
1500 1.1 christos log_error ("Cannot set LDAP TLS CA certificate file %s: %s",
1501 1.1 christos ldap_tls_ca_file, ldap_err2string (ret));
1502 1.1 christos }
1503 1.1 christos }
1504 1.1 christos if( ldap_tls_ca_dir != NULL)
1505 1.1 christos {
1506 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR,
1507 1.1 christos ldap_tls_ca_dir)) != LDAP_SUCCESS)
1508 1.1 christos {
1509 1.1 christos log_error ("Cannot set LDAP TLS CA certificate dir %s: %s",
1510 1.1 christos ldap_tls_ca_dir, ldap_err2string (ret));
1511 1.1 christos }
1512 1.1 christos }
1513 1.1 christos if( ldap_tls_cert != NULL)
1514 1.1 christos {
1515 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE,
1516 1.1 christos ldap_tls_cert)) != LDAP_SUCCESS)
1517 1.1 christos {
1518 1.1 christos log_error ("Cannot set LDAP TLS client certificate file %s: %s",
1519 1.1 christos ldap_tls_cert, ldap_err2string (ret));
1520 1.1 christos }
1521 1.1 christos }
1522 1.1 christos if( ldap_tls_key != NULL)
1523 1.1 christos {
1524 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE,
1525 1.1 christos ldap_tls_key)) != LDAP_SUCCESS)
1526 1.1 christos {
1527 1.1 christos log_error ("Cannot set LDAP TLS certificate key file %s: %s",
1528 1.1 christos ldap_tls_key, ldap_err2string (ret));
1529 1.1 christos }
1530 1.1 christos }
1531 1.1 christos if( ldap_tls_crlcheck != -1)
1532 1.1 christos {
1533 1.1 christos int opt = ldap_tls_crlcheck;
1534 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CRLCHECK,
1535 1.1 christos &opt)) != LDAP_SUCCESS)
1536 1.1 christos {
1537 1.1 christos log_error ("Cannot set LDAP TLS crl check option: %s",
1538 1.1 christos ldap_err2string (ret));
1539 1.1 christos }
1540 1.1 christos }
1541 1.1 christos if( ldap_tls_ciphers != NULL)
1542 1.1 christos {
1543 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE,
1544 1.1 christos ldap_tls_ciphers)) != LDAP_SUCCESS)
1545 1.1 christos {
1546 1.1 christos log_error ("Cannot set LDAP TLS cipher suite %s: %s",
1547 1.1 christos ldap_tls_ciphers, ldap_err2string (ret));
1548 1.1 christos }
1549 1.1 christos }
1550 1.1 christos if( ldap_tls_randfile != NULL)
1551 1.1 christos {
1552 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE,
1553 1.1 christos ldap_tls_randfile)) != LDAP_SUCCESS)
1554 1.1 christos {
1555 1.1 christos log_error ("Cannot set LDAP TLS random file %s: %s",
1556 1.1 christos ldap_tls_randfile, ldap_err2string (ret));
1557 1.1 christos }
1558 1.1 christos }
1559 1.1 christos }
1560 1.1 christos #endif
1561 1.1 christos
1562 1.1 christos /* enough for 'ldap://+ + hostname + ':' + port number */
1563 1.1 christos uri = malloc(strlen(ldap_server) + 16);
1564 1.1 christos if (uri == NULL)
1565 1.1 christos {
1566 1.1 christos log_error ("Cannot build ldap init URI %s:%d", ldap_server, ldap_port);
1567 1.1 christos return;
1568 1.1 christos }
1569 1.1 christos
1570 1.1 christos sprintf(uri, "ldap://%s:%d", ldap_server, ldap_port);
1571 1.1 christos ldap_initialize(&ld, uri);
1572 1.1 christos
1573 1.1 christos if (ld == NULL)
1574 1.1 christos {
1575 1.1 christos log_error ("Cannot init ldap session to %s:%d", ldap_server, ldap_port);
1576 1.1 christos return;
1577 1.1 christos }
1578 1.1 christos
1579 1.1 christos free(uri);
1580 1.1 christos
1581 1.1 christos version = LDAP_VERSION3;
1582 1.1 christos if ((ret = ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version)) != LDAP_OPT_SUCCESS)
1583 1.1 christos {
1584 1.1 christos log_error ("Cannot set LDAP version to %d: %s", version,
1585 1.1 christos ldap_err2string (ret));
1586 1.1 christos }
1587 1.1 christos
1588 1.1 christos if (ldap_referrals != -1)
1589 1.1 christos {
1590 1.1 christos if ((ret = ldap_set_option (ld, LDAP_OPT_REFERRALS, ldap_referrals ?
1591 1.1 christos LDAP_OPT_ON : LDAP_OPT_OFF)) != LDAP_OPT_SUCCESS)
1592 1.1 christos {
1593 1.1 christos log_error ("Cannot %s LDAP referrals option: %s",
1594 1.1 christos (ldap_referrals ? "enable" : "disable"),
1595 1.1 christos ldap_err2string (ret));
1596 1.1 christos }
1597 1.1 christos }
1598 1.1 christos
1599 1.1 christos if ((ret = ldap_set_rebind_proc(ld, ldap_rebind_cb, NULL)) != LDAP_SUCCESS)
1600 1.1 christos {
1601 1.1 christos log_error ("Warning: Cannot set ldap rebind procedure: %s",
1602 1.1 christos ldap_err2string (ret));
1603 1.1 christos }
1604 1.1 christos
1605 1.1 christos #if defined (LDAP_USE_SSL)
1606 1.1 christos if (ldap_use_ssl == LDAP_SSL_LDAPS ||
1607 1.1 christos (ldap_use_ssl == LDAP_SSL_ON && ldap_port == LDAPS_PORT))
1608 1.1 christos {
1609 1.1 christos int opt = LDAP_OPT_X_TLS_HARD;
1610 1.1 christos if ((ret = ldap_set_option (ld, LDAP_OPT_X_TLS, &opt)) != LDAP_SUCCESS)
1611 1.1 christos {
1612 1.1 christos log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
1613 1.1 christos ldap_server, ldap_port, ldap_err2string (ret));
1614 1.1 christos ldap_stop();
1615 1.1 christos return;
1616 1.1 christos }
1617 1.1 christos else
1618 1.1 christos {
1619 1.1 christos log_info ("LDAPS session successfully enabled to %s:%d",
1620 1.1 christos ldap_server, ldap_port);
1621 1.1 christos }
1622 1.1 christos }
1623 1.1 christos else if (ldap_use_ssl != LDAP_SSL_OFF)
1624 1.1 christos {
1625 1.1 christos do
1626 1.1 christos {
1627 1.1 christos ret = ldap_start_tls_s (ld, NULL, NULL);
1628 1.1 christos }
1629 1.1 christos while(_do_ldap_retry(ret, ldap_server, ldap_port) > 0);
1630 1.1 christos
1631 1.1 christos if (ret != LDAP_SUCCESS)
1632 1.1 christos {
1633 1.1 christos log_error ("Error: Cannot start TLS session to %s:%d: %s",
1634 1.1 christos ldap_server, ldap_port, ldap_err2string (ret));
1635 1.1 christos ldap_stop();
1636 1.1 christos return;
1637 1.1 christos }
1638 1.1 christos else
1639 1.1 christos {
1640 1.1 christos log_info ("TLS session successfully started to %s:%d",
1641 1.1 christos ldap_server, ldap_port);
1642 1.1 christos }
1643 1.1 christos }
1644 1.1 christos #endif
1645 1.1 christos
1646 1.1 christos #if defined(LDAP_USE_GSSAPI)
1647 1.1 christos if (ldap_gssapi_principal != NULL) {
1648 1.1 christos krb5_get_tgt(ldap_gssapi_principal, ldap_gssapi_keytab);
1649 1.1 christos if ((ret = ldap_sasl_interactive_bind_s(ld, NULL, ldap_sasl_inst->sasl_mech,
1650 1.1 christos NULL, NULL, LDAP_SASL_AUTOMATIC,
1651 1.1 christos _ldap_sasl_interact, ldap_sasl_inst)
1652 1.1 christos ) != LDAP_SUCCESS)
1653 1.1 christos {
1654 1.1 christos log_error ("Error: Cannot SASL bind to ldap server %s:%d: %s",
1655 1.1 christos ldap_server, ldap_port, ldap_err2string (ret));
1656 1.1 christos char *msg=NULL;
1657 1.1 christos ldap_get_option( ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*)&msg);
1658 1.1 christos log_error ("\tAdditional info: %s", msg);
1659 1.1 christos ldap_memfree(msg);
1660 1.1 christos ldap_stop();
1661 1.1 christos return;
1662 1.1 christos }
1663 1.1 christos } else
1664 1.1 christos #endif
1665 1.1 christos
1666 1.1 christos if (ldap_username != NULL && *ldap_username != '\0' && ldap_password != NULL)
1667 1.1 christos {
1668 1.1 christos creds.bv_val = strdup(ldap_password);
1669 1.1 christos if (creds.bv_val == NULL)
1670 1.1 christos log_fatal ("Error: Unable to allocate memory to duplicate ldap_password");
1671 1.1 christos
1672 1.1 christos creds.bv_len = strlen(ldap_password);
1673 1.1 christos
1674 1.1 christos do
1675 1.1 christos {
1676 1.1 christos ret = ldap_sasl_bind_s (ld, ldap_username, LDAP_SASL_SIMPLE,
1677 1.1 christos &creds, NULL, NULL, NULL);
1678 1.1 christos }
1679 1.1 christos while(_do_ldap_retry(ret, ldap_server, ldap_port) > 0);
1680 1.1 christos free(creds.bv_val);
1681 1.1 christos
1682 1.1 christos if (ret != LDAP_SUCCESS)
1683 1.1 christos {
1684 1.1 christos log_error ("Error: Cannot login into ldap server %s:%d: %s",
1685 1.1 christos ldap_server, ldap_port, ldap_err2string (ret));
1686 1.1 christos ldap_stop();
1687 1.1 christos return;
1688 1.1 christos }
1689 1.1 christos }
1690 1.1 christos
1691 1.1 christos #if defined (DEBUG_LDAP)
1692 1.1 christos log_info ("Successfully logged into LDAP server %s", ldap_server);
1693 1.1 christos #endif
1694 1.1 christos }
1695 1.1 christos
1696 1.1 christos
1697 1.1 christos static void
1698 1.1 christos parse_external_dns (LDAPMessage * ent)
1699 1.1 christos {
1700 1.1 christos char *search[] = {"dhcpOptionsDN", "dhcpSharedNetworkDN", "dhcpSubnetDN",
1701 1.1 christos "dhcpGroupDN", "dhcpHostDN", "dhcpClassesDN",
1702 1.1 christos "dhcpPoolDN", "dhcpZoneDN", "dhcpFailOverPeerDN", NULL};
1703 1.1 christos
1704 1.1 christos /* TODO: dhcpKeyDN can't be added. It is referenced in dhcpDnsZone to
1705 1.1 christos retrive the key name (cn). Adding keyDN will reflect adding a key
1706 1.1 christos declaration inside the zone configuration.
1707 1.1 christos
1708 1.1 christos dhcpSubClassesDN cant be added. It is also similar to the above.
1709 1.1 christos Needs schema change.
1710 1.1 christos */
1711 1.1 christos LDAPMessage * newres, * newent;
1712 1.1 christos struct berval **tempbv;
1713 1.1 christos int i, j, ret;
1714 1.1 christos #if defined (DEBUG_LDAP)
1715 1.1 christos char *dn;
1716 1.1 christos
1717 1.1 christos dn = ldap_get_dn (ld, ent);
1718 1.1 christos if (dn != NULL)
1719 1.1 christos {
1720 1.1 christos log_info ("Parsing external DNs for '%s'", dn);
1721 1.1 christos ldap_memfree (dn);
1722 1.1 christos }
1723 1.1 christos #endif
1724 1.1 christos
1725 1.1 christos if (ld == NULL)
1726 1.1 christos ldap_start ();
1727 1.1 christos if (ld == NULL)
1728 1.1 christos return;
1729 1.1 christos
1730 1.1 christos for (i=0; search[i] != NULL; i++)
1731 1.1 christos {
1732 1.1 christos if ((tempbv = ldap_get_values_len (ld, ent, search[i])) == NULL)
1733 1.1 christos continue;
1734 1.1 christos
1735 1.1 christos for (j=0; tempbv[j] != NULL; j++)
1736 1.1 christos {
1737 1.1 christos if (*tempbv[j]->bv_val == '\0')
1738 1.1 christos continue;
1739 1.1 christos
1740 1.1 christos if ((ret = ldap_search_ext_s(ld, tempbv[j]->bv_val, LDAP_SCOPE_BASE,
1741 1.1 christos "objectClass=*", NULL, 0, NULL,
1742 1.1 christos NULL, NULL, 0, &newres)) != LDAP_SUCCESS)
1743 1.1 christos {
1744 1.1 christos ldap_value_free_len (tempbv);
1745 1.1 christos ldap_stop();
1746 1.1 christos return;
1747 1.1 christos }
1748 1.1 christos
1749 1.1 christos #if defined (DEBUG_LDAP)
1750 1.1 christos log_info ("Adding contents of subtree '%s' to config stack from '%s' reference", tempbv[j]->bv_val, search[i]);
1751 1.1 christos #endif
1752 1.1 christos for (newent = ldap_first_entry (ld, newres);
1753 1.1 christos newent != NULL;
1754 1.1 christos newent = ldap_next_entry (ld, newent))
1755 1.1 christos {
1756 1.1 christos #if defined (DEBUG_LDAP)
1757 1.1 christos dn = ldap_get_dn (ld, newent);
1758 1.1 christos if (dn != NULL)
1759 1.1 christos {
1760 1.1 christos log_info ("Adding LDAP result set starting with '%s' to config stack", dn);
1761 1.1 christos ldap_memfree (dn);
1762 1.1 christos }
1763 1.1 christos #endif
1764 1.1 christos
1765 1.1 christos add_to_config_stack (newres, newent);
1766 1.1 christos /* don't free newres here */
1767 1.1 christos }
1768 1.1 christos }
1769 1.1 christos
1770 1.1 christos ldap_value_free_len (tempbv);
1771 1.1 christos }
1772 1.1 christos }
1773 1.1 christos
1774 1.1 christos
1775 1.1 christos static void
1776 1.1 christos free_stack_entry (struct ldap_config_stack *item)
1777 1.1 christos {
1778 1.1 christos struct ldap_config_stack *look_ahead_pointer = item;
1779 1.1 christos int may_free_msg = 1;
1780 1.1 christos
1781 1.1 christos while (look_ahead_pointer->next != NULL)
1782 1.1 christos {
1783 1.1 christos look_ahead_pointer = look_ahead_pointer->next;
1784 1.1 christos if (look_ahead_pointer->res == item->res)
1785 1.1 christos {
1786 1.1 christos may_free_msg = 0;
1787 1.1 christos break;
1788 1.1 christos }
1789 1.1 christos }
1790 1.1 christos
1791 1.1 christos if (may_free_msg)
1792 1.1 christos ldap_msgfree (item->res);
1793 1.1 christos
1794 1.1 christos dfree (item, MDL);
1795 1.1 christos }
1796 1.1 christos
1797 1.1 christos
1798 1.1 christos static void
1799 1.1 christos next_ldap_entry (struct parse *cfile)
1800 1.1 christos {
1801 1.1 christos struct ldap_config_stack *temp_stack;
1802 1.1 christos
1803 1.1 christos if (ldap_stack != NULL && ldap_stack->close_brace)
1804 1.1 christos {
1805 1.1 christos x_parser_strcat (cfile, "}\n");
1806 1.1 christos ldap_stack->close_brace = 0;
1807 1.1 christos }
1808 1.1 christos
1809 1.1 christos while (ldap_stack != NULL &&
1810 1.1 christos (ldap_stack->ldent == NULL || ( ldap_stack->processed &&
1811 1.1 christos (ldap_stack->ldent = ldap_next_entry (ld, ldap_stack->ldent)) == NULL)))
1812 1.1 christos {
1813 1.1 christos if (ldap_stack->close_brace)
1814 1.1 christos {
1815 1.1 christos x_parser_strcat (cfile, "}\n");
1816 1.1 christos ldap_stack->close_brace = 0;
1817 1.1 christos }
1818 1.1 christos
1819 1.1 christos temp_stack = ldap_stack;
1820 1.1 christos ldap_stack = ldap_stack->next;
1821 1.1 christos free_stack_entry (temp_stack);
1822 1.1 christos }
1823 1.1 christos
1824 1.1 christos if (ldap_stack != NULL && ldap_stack->close_brace)
1825 1.1 christos {
1826 1.1 christos x_parser_strcat (cfile, "}\n");
1827 1.1 christos ldap_stack->close_brace = 0;
1828 1.1 christos }
1829 1.1 christos }
1830 1.1 christos
1831 1.1 christos
1832 1.1 christos static char
1833 1.1 christos check_statement_end (const char *statement)
1834 1.1 christos {
1835 1.1 christos char *ptr;
1836 1.1 christos
1837 1.1 christos if (statement == NULL || *statement == '\0')
1838 1.1 christos return ('\0');
1839 1.1 christos
1840 1.1 christos /*
1841 1.1 christos ** check if it ends with "}", e.g.:
1842 1.1 christos ** "zone my.domain. { ... }"
1843 1.1 christos ** optionally followed by spaces
1844 1.1 christos */
1845 1.1 christos ptr = strrchr (statement, '}');
1846 1.1 christos if (ptr != NULL)
1847 1.1 christos {
1848 1.1 christos /* skip following white-spaces */
1849 1.1 christos for (++ptr; isspace ((int)*ptr); ptr++);
1850 1.1 christos
1851 1.1 christos /* check if we reached the end */
1852 1.1 christos if (*ptr == '\0')
1853 1.1 christos return ('}'); /* yes, block end */
1854 1.1 christos else
1855 1.1 christos return (*ptr);
1856 1.1 christos }
1857 1.1 christos
1858 1.1 christos /*
1859 1.1 christos ** this should not happen, but...
1860 1.1 christos ** check if it ends with ";", e.g.:
1861 1.1 christos ** "authoritative;"
1862 1.1 christos ** optionally followed by spaces
1863 1.1 christos */
1864 1.1 christos ptr = strrchr (statement, ';');
1865 1.1 christos if (ptr != NULL)
1866 1.1 christos {
1867 1.1 christos /* skip following white-spaces */
1868 1.1 christos for (++ptr; isspace ((int)*ptr); ptr++);
1869 1.1 christos
1870 1.1 christos /* check if we reached the end */
1871 1.1 christos if (*ptr == '\0')
1872 1.1 christos return (';'); /* ends with a ; */
1873 1.1 christos else
1874 1.1 christos return (*ptr);
1875 1.1 christos }
1876 1.1 christos
1877 1.1 christos return ('\0');
1878 1.1 christos }
1879 1.1 christos
1880 1.1 christos
1881 1.1 christos static isc_result_t
1882 1.1 christos ldap_parse_entry_options (LDAPMessage *ent, struct parse *cfile,
1883 1.1 christos int *lease_limit)
1884 1.1 christos {
1885 1.1 christos struct berval **tempbv;
1886 1.1 christos int i;
1887 1.1 christos
1888 1.1 christos if (ent == NULL || cfile == NULL)
1889 1.1 christos return (ISC_R_FAILURE);
1890 1.1 christos
1891 1.1 christos if ((tempbv = ldap_get_values_len (ld, ent, "dhcpStatements")) != NULL)
1892 1.1 christos {
1893 1.1 christos for (i=0; tempbv[i] != NULL; i++)
1894 1.1 christos {
1895 1.1 christos if (lease_limit != NULL &&
1896 1.1 christos strncasecmp ("lease limit ", tempbv[i]->bv_val, 12) == 0)
1897 1.1 christos {
1898 1.1 christos *lease_limit = (int) strtol ((tempbv[i]->bv_val) + 12, NULL, 10);
1899 1.1 christos continue;
1900 1.1 christos }
1901 1.1 christos
1902 1.1 christos x_parser_strcat (cfile, tempbv[i]->bv_val);
1903 1.1 christos
1904 1.1 christos switch((int) check_statement_end (tempbv[i]->bv_val))
1905 1.1 christos {
1906 1.1 christos case '}':
1907 1.1 christos case ';':
1908 1.1 christos x_parser_strcat (cfile, "\n");
1909 1.1 christos break;
1910 1.1 christos default:
1911 1.1 christos x_parser_strcat (cfile, ";\n");
1912 1.1 christos break;
1913 1.1 christos }
1914 1.1 christos }
1915 1.1 christos ldap_value_free_len (tempbv);
1916 1.1 christos }
1917 1.1 christos
1918 1.1 christos if ((tempbv = ldap_get_values_len (ld, ent, "dhcpOption")) != NULL)
1919 1.1 christos {
1920 1.1 christos for (i=0; tempbv[i] != NULL; i++)
1921 1.1 christos {
1922 1.1 christos x_parser_strcat (cfile, "option ");
1923 1.1 christos x_parser_strcat (cfile, tempbv[i]->bv_val);
1924 1.1 christos switch ((int) check_statement_end (tempbv[i]->bv_val))
1925 1.1 christos {
1926 1.1 christos case ';':
1927 1.1 christos x_parser_strcat (cfile, "\n");
1928 1.1 christos break;
1929 1.1 christos default:
1930 1.1 christos x_parser_strcat (cfile, ";\n");
1931 1.1 christos break;
1932 1.1 christos }
1933 1.1 christos }
1934 1.1 christos ldap_value_free_len (tempbv);
1935 1.1 christos }
1936 1.1 christos
1937 1.1 christos return (ISC_R_SUCCESS);
1938 1.1 christos }
1939 1.1 christos
1940 1.1 christos
1941 1.1 christos static void
1942 1.1 christos ldap_generate_config_string (struct parse *cfile)
1943 1.1 christos {
1944 1.1 christos struct berval **objectClass;
1945 1.1 christos char *dn;
1946 1.1 christos struct ldap_config_stack *entry;
1947 1.1 christos LDAPMessage * ent, * res, *entfirst, *resfirst;
1948 1.1 christos int i, ignore, found;
1949 1.1 christos int ret, parsedn = 1;
1950 1.1 christos size_t len = cfile->buflen;
1951 1.1 christos
1952 1.1 christos if (ld == NULL)
1953 1.1 christos ldap_start ();
1954 1.1 christos if (ld == NULL)
1955 1.1 christos return;
1956 1.1 christos
1957 1.1 christos entry = ldap_stack;
1958 1.1 christos if ((objectClass = ldap_get_values_len (ld, entry->ldent,
1959 1.1 christos "objectClass")) == NULL)
1960 1.1 christos return;
1961 1.1 christos
1962 1.1 christos entry->processed = 1;
1963 1.1 christos ignore = 0;
1964 1.1 christos found = 1;
1965 1.1 christos for (i=0; objectClass[i] != NULL; i++)
1966 1.1 christos {
1967 1.1 christos if (strcasecmp (objectClass[i]->bv_val, "dhcpSharedNetwork") == 0)
1968 1.1 christos ldap_parse_shared_network (entry, cfile);
1969 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpClass") == 0)
1970 1.1 christos ldap_parse_class (entry, cfile);
1971 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpSubnet") == 0)
1972 1.1 christos ldap_parse_subnet (entry, cfile);
1973 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpSubnet6") == 0)
1974 1.1 christos ldap_parse_subnet6 (entry, cfile);
1975 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpPool") == 0)
1976 1.1 christos ldap_parse_pool (entry, cfile);
1977 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpPool6") == 0)
1978 1.1 christos ldap_parse_pool6 (entry, cfile);
1979 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpGroup") == 0)
1980 1.1 christos ldap_parse_group (entry, cfile);
1981 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpTSigKey") == 0)
1982 1.1 christos ldap_parse_key (entry, cfile);
1983 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpDnsZone") == 0)
1984 1.1 christos ldap_parse_zone (entry, cfile);
1985 1.1 christos #if defined(HAVE_IFADDRS_H)
1986 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpFailOverPeer") == 0)
1987 1.1 christos ldap_parse_failover (entry, cfile);
1988 1.1 christos #endif
1989 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpHost") == 0)
1990 1.1 christos {
1991 1.1 christos if (ldap_method == LDAP_METHOD_STATIC)
1992 1.1 christos ldap_parse_host (entry, cfile);
1993 1.1 christos else
1994 1.1 christos {
1995 1.1 christos ignore = 1;
1996 1.1 christos break;
1997 1.1 christos }
1998 1.1 christos }
1999 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpSubClass") == 0)
2000 1.1 christos {
2001 1.1 christos if (ldap_method == LDAP_METHOD_STATIC)
2002 1.1 christos ldap_parse_subclass (entry, cfile);
2003 1.1 christos else
2004 1.1 christos {
2005 1.1 christos ignore = 1;
2006 1.1 christos break;
2007 1.1 christos }
2008 1.1 christos }
2009 1.1 christos else
2010 1.1 christos found = 0;
2011 1.1 christos
2012 1.1 christos if (found && x_parser_length(cfile) <= len)
2013 1.1 christos {
2014 1.1 christos ignore = 1;
2015 1.1 christos break;
2016 1.1 christos }
2017 1.1 christos }
2018 1.1 christos
2019 1.1 christos ldap_value_free_len (objectClass);
2020 1.1 christos
2021 1.1 christos if (ignore)
2022 1.1 christos {
2023 1.1 christos next_ldap_entry (cfile);
2024 1.1 christos return;
2025 1.1 christos }
2026 1.1 christos
2027 1.1 christos ldap_parse_entry_options(entry->ldent, cfile, NULL);
2028 1.1 christos
2029 1.1 christos dn = ldap_get_dn (ld, entry->ldent);
2030 1.1 christos if (dn == NULL)
2031 1.1 christos {
2032 1.1 christos ldap_stop();
2033 1.1 christos return;
2034 1.1 christos }
2035 1.1 christos #if defined(DEBUG_LDAP)
2036 1.1 christos log_info ("Found LDAP entry '%s'", dn);
2037 1.1 christos #endif
2038 1.1 christos
2039 1.1 christos if ((ret = ldap_search_ext_s (ld, dn, LDAP_SCOPE_ONELEVEL,
2040 1.1 christos "(!(|(|(objectClass=dhcpTSigKey)(objectClass=dhcpClass)) (objectClass=dhcpFailOverPeer)))",
2041 1.1 christos NULL, 0, NULL, NULL,
2042 1.1 christos NULL, 0, &res)) != LDAP_SUCCESS)
2043 1.1 christos {
2044 1.1 christos ldap_memfree (dn);
2045 1.1 christos
2046 1.1 christos ldap_stop();
2047 1.1 christos return;
2048 1.1 christos }
2049 1.1 christos
2050 1.1 christos if ((ret = ldap_search_ext_s (ld, dn, LDAP_SCOPE_ONELEVEL,
2051 1.1 christos "(|(|(objectClass=dhcpTSigKey)(objectClass=dhcpClass)) (objectClass=dhcpFailOverPeer))",
2052 1.1 christos NULL, 0, NULL, NULL,
2053 1.1 christos NULL, 0, &resfirst)) != LDAP_SUCCESS)
2054 1.1 christos {
2055 1.1 christos ldap_memfree (dn);
2056 1.1 christos ldap_msgfree (res);
2057 1.1 christos
2058 1.1 christos ldap_stop();
2059 1.1 christos return;
2060 1.1 christos }
2061 1.1 christos
2062 1.1 christos ldap_memfree (dn);
2063 1.1 christos
2064 1.1 christos ent = ldap_first_entry(ld, res);
2065 1.1 christos entfirst = ldap_first_entry(ld, resfirst);
2066 1.1 christos
2067 1.1 christos if (ent == NULL && entfirst == NULL)
2068 1.1 christos {
2069 1.1 christos parse_external_dns (entry->ldent);
2070 1.1 christos next_ldap_entry (cfile);
2071 1.1 christos }
2072 1.1 christos
2073 1.1 christos if (ent != NULL)
2074 1.1 christos {
2075 1.1 christos add_to_config_stack (res, ent);
2076 1.1 christos parse_external_dns (entry->ldent);
2077 1.1 christos parsedn = 0;
2078 1.1 christos }
2079 1.1 christos else
2080 1.1 christos ldap_msgfree (res);
2081 1.1 christos
2082 1.1 christos if (entfirst != NULL)
2083 1.1 christos {
2084 1.1 christos add_to_config_stack (resfirst, entfirst);
2085 1.1 christos if(parsedn)
2086 1.1 christos parse_external_dns (entry->ldent);
2087 1.1 christos
2088 1.1 christos }
2089 1.1 christos else
2090 1.1 christos ldap_msgfree (resfirst);
2091 1.1 christos }
2092 1.1 christos
2093 1.1 christos
2094 1.1 christos static void
2095 1.1 christos ldap_close_debug_fd()
2096 1.1 christos {
2097 1.1 christos if (ldap_debug_fd != -1)
2098 1.1 christos {
2099 1.1 christos close (ldap_debug_fd);
2100 1.1 christos ldap_debug_fd = -1;
2101 1.1 christos }
2102 1.1 christos }
2103 1.1 christos
2104 1.1 christos
2105 1.1 christos static void
2106 1.1 christos ldap_write_debug (const void *buff, size_t size)
2107 1.1 christos {
2108 1.1 christos if (ldap_debug_fd != -1)
2109 1.1 christos {
2110 1.1 christos if (write (ldap_debug_fd, buff, size) < 0)
2111 1.1 christos {
2112 1.1 christos log_error ("Error writing to LDAP debug file %s: %s."
2113 1.1 christos " Disabling log file.", ldap_debug_file,
2114 1.1 christos strerror (errno));
2115 1.1 christos ldap_close_debug_fd();
2116 1.1 christos }
2117 1.1 christos }
2118 1.1 christos }
2119 1.1 christos
2120 1.1 christos static int
2121 1.1 christos ldap_read_function (struct parse *cfile)
2122 1.1 christos {
2123 1.1 christos size_t len;
2124 1.1 christos
2125 1.1 christos /* append when in saved state */
2126 1.1 christos if (cfile->saved_state == NULL)
2127 1.1 christos {
2128 1.1 christos cfile->inbuf[0] = '\0';
2129 1.1 christos cfile->bufix = 0;
2130 1.1 christos cfile->buflen = 0;
2131 1.1 christos }
2132 1.1 christos len = cfile->buflen;
2133 1.1 christos
2134 1.1 christos while (ldap_stack != NULL && x_parser_length(cfile) <= len)
2135 1.1 christos ldap_generate_config_string (cfile);
2136 1.1 christos
2137 1.1 christos if (x_parser_length(cfile) <= len && ldap_stack == NULL)
2138 1.1 christos return (EOF);
2139 1.1 christos
2140 1.1 christos if (cfile->buflen > len)
2141 1.1 christos ldap_write_debug (cfile->inbuf + len, cfile->buflen - len);
2142 1.1 christos #if defined (DEBUG_LDAP)
2143 1.1 christos log_info ("Sending config portion '%s'", cfile->inbuf + len);
2144 1.1 christos #endif
2145 1.1 christos
2146 1.1 christos return (cfile->inbuf[cfile->bufix++]);
2147 1.1 christos }
2148 1.1 christos
2149 1.1 christos
2150 1.1 christos static char *
2151 1.1 christos ldap_get_host_name (LDAPMessage * ent)
2152 1.1 christos {
2153 1.1 christos struct berval **name;
2154 1.1 christos char *ret;
2155 1.1 christos
2156 1.1 christos ret = NULL;
2157 1.1 christos if ((name = ldap_get_values_len (ld, ent, "cn")) == NULL || name[0] == NULL)
2158 1.1 christos {
2159 1.1 christos if (name != NULL)
2160 1.1 christos ldap_value_free_len (name);
2161 1.1 christos
2162 1.1 christos #if defined (DEBUG_LDAP)
2163 1.1 christos ret = ldap_get_dn (ld, ent);
2164 1.1 christos if (ret != NULL)
2165 1.1 christos {
2166 1.1 christos log_info ("Cannot get cn attribute for LDAP entry %s", ret);
2167 1.1 christos ldap_memfree(ret);
2168 1.1 christos }
2169 1.1 christos #endif
2170 1.1 christos return (NULL);
2171 1.1 christos }
2172 1.1 christos
2173 1.1 christos ret = dmalloc (strlen (name[0]->bv_val) + 1, MDL);
2174 1.1 christos strcpy (ret, name[0]->bv_val);
2175 1.1 christos ldap_value_free_len (name);
2176 1.1 christos
2177 1.1 christos return (ret);
2178 1.1 christos }
2179 1.1 christos
2180 1.1 christos
2181 1.1 christos isc_result_t
2182 1.1 christos ldap_read_config (void)
2183 1.1 christos {
2184 1.1 christos LDAPMessage * ldres, * hostres, * ent, * hostent;
2185 1.1 christos char hfilter[1024], sfilter[1024], fqdn[257];
2186 1.1 christos char *hostdn;
2187 1.1 christos ldap_dn_node *curr = NULL;
2188 1.1 christos struct parse *cfile;
2189 1.1 christos struct utsname unme;
2190 1.1 christos isc_result_t res;
2191 1.1 christos size_t length;
2192 1.1 christos int ret, cnt;
2193 1.1 christos struct berval **tempbv = NULL;
2194 1.1 christos struct berval bv_o[2];
2195 1.1 christos
2196 1.1 christos cfile = x_parser_init("LDAP");
2197 1.1 christos if (cfile == NULL)
2198 1.1 christos return (ISC_R_NOMEMORY);
2199 1.1 christos
2200 1.1 christos ldap_enable_retry = 1;
2201 1.1 christos if (ld == NULL)
2202 1.1 christos ldap_start ();
2203 1.1 christos ldap_enable_retry = 0;
2204 1.1 christos
2205 1.1 christos if (ld == NULL)
2206 1.1 christos {
2207 1.1 christos x_parser_free(&cfile);
2208 1.1 christos return (ldap_server == NULL ? ISC_R_SUCCESS : ISC_R_FAILURE);
2209 1.1 christos }
2210 1.1 christos
2211 1.1 christos uname (&unme);
2212 1.1 christos if (ldap_dhcp_server_cn != NULL)
2213 1.1 christos {
2214 1.1 christos if (_do_ldap_str2esc_filter_bv(ldap_dhcp_server_cn, 0, &bv_o[0]) == NULL)
2215 1.1 christos {
2216 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", ldap_dhcp_server_cn);
2217 1.1 christos x_parser_free(&cfile);
2218 1.1 christos return (ISC_R_FAILURE);
2219 1.1 christos }
2220 1.1 christos
2221 1.1 christos snprintf (hfilter, sizeof (hfilter),
2222 1.1 christos "(&(objectClass=dhcpServer)(cn=%s))", bv_o[0].bv_val);
2223 1.1 christos
2224 1.1 christos ber_memfree(bv_o[0].bv_val);
2225 1.1 christos }
2226 1.1 christos else
2227 1.1 christos {
2228 1.1 christos if (_do_ldap_str2esc_filter_bv(unme.nodename, 0, &bv_o[0]) == NULL)
2229 1.1 christos {
2230 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", unme.nodename);
2231 1.1 christos x_parser_free(&cfile);
2232 1.1 christos return (ISC_R_FAILURE);
2233 1.1 christos }
2234 1.1 christos
2235 1.1 christos *fqdn ='\0';
2236 1.1 christos if(0 == get_host_entry(fqdn, sizeof(fqdn), NULL, 0))
2237 1.1 christos {
2238 1.1 christos if (_do_ldap_str2esc_filter_bv(fqdn, 0, &bv_o[1]) == NULL)
2239 1.1 christos {
2240 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", fqdn);
2241 1.1 christos ber_memfree(bv_o[0].bv_val);
2242 1.1 christos x_parser_free(&cfile);
2243 1.1 christos return (ISC_R_FAILURE);
2244 1.1 christos }
2245 1.1 christos }
2246 1.1 christos
2247 1.1 christos // If we have fqdn and it isn't the same as nodename, use it in filter
2248 1.1 christos // otherwise just use nodename
2249 1.1 christos if ((*fqdn) && (strcmp(unme.nodename, fqdn))) {
2250 1.1 christos snprintf (hfilter, sizeof (hfilter),
2251 1.1 christos "(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))",
2252 1.1 christos bv_o[0].bv_val, bv_o[1].bv_val);
2253 1.1 christos
2254 1.1 christos ber_memfree(bv_o[1].bv_val);
2255 1.1 christos }
2256 1.1 christos else
2257 1.1 christos {
2258 1.1 christos snprintf (hfilter, sizeof (hfilter),
2259 1.1 christos "(&(objectClass=dhcpServer)(cn=%s))",
2260 1.1 christos bv_o[0].bv_val);
2261 1.1 christos }
2262 1.1 christos
2263 1.1 christos ber_memfree(bv_o[0].bv_val);
2264 1.1 christos }
2265 1.1 christos
2266 1.1 christos ldap_enable_retry = 1;
2267 1.1 christos do
2268 1.1 christos {
2269 1.1 christos hostres = NULL;
2270 1.1 christos ret = ldap_search_ext_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE,
2271 1.1 christos hfilter, NULL, 0, NULL, NULL, NULL, 0,
2272 1.1 christos &hostres);
2273 1.1 christos }
2274 1.1 christos while(_do_ldap_retry(ret, ldap_server, ldap_port) > 0);
2275 1.1 christos ldap_enable_retry = 0;
2276 1.1 christos
2277 1.1 christos if(ret != LDAP_SUCCESS)
2278 1.1 christos {
2279 1.1 christos log_error ("Cannot find host LDAP entry %s %s",
2280 1.1 christos ((ldap_dhcp_server_cn == NULL)?(unme.nodename):(ldap_dhcp_server_cn)), hfilter);
2281 1.1 christos if(NULL != hostres)
2282 1.1 christos ldap_msgfree (hostres);
2283 1.1 christos ldap_stop();
2284 1.1 christos x_parser_free(&cfile);
2285 1.1 christos return (ISC_R_FAILURE);
2286 1.1 christos }
2287 1.1 christos
2288 1.1 christos if ((hostent = ldap_first_entry (ld, hostres)) == NULL)
2289 1.1 christos {
2290 1.1 christos log_error ("Error: Cannot find LDAP entry matching %s", hfilter);
2291 1.1 christos ldap_msgfree (hostres);
2292 1.1 christos ldap_stop();
2293 1.1 christos x_parser_free(&cfile);
2294 1.1 christos return (ISC_R_FAILURE);
2295 1.1 christos }
2296 1.1 christos
2297 1.1 christos hostdn = ldap_get_dn (ld, hostent);
2298 1.1 christos #if defined(DEBUG_LDAP)
2299 1.1 christos if (hostdn != NULL)
2300 1.1 christos log_info ("Found dhcpServer LDAP entry '%s'", hostdn);
2301 1.1 christos #endif
2302 1.1 christos
2303 1.1 christos if (hostdn == NULL ||
2304 1.1 christos (tempbv = ldap_get_values_len (ld, hostent, "dhcpServiceDN")) == NULL ||
2305 1.1 christos tempbv[0] == NULL)
2306 1.1 christos {
2307 1.1 christos log_error ("Error: No dhcp service is associated with the server %s %s",
2308 1.1 christos (hostdn ? "dn" : "name"), (hostdn ? hostdn :
2309 1.1 christos (ldap_dhcp_server_cn ? ldap_dhcp_server_cn : unme.nodename)));
2310 1.1 christos
2311 1.1 christos if (tempbv != NULL)
2312 1.1 christos ldap_value_free_len (tempbv);
2313 1.1 christos
2314 1.1 christos if (hostdn)
2315 1.1 christos ldap_memfree (hostdn);
2316 1.1 christos ldap_msgfree (hostres);
2317 1.1 christos ldap_stop();
2318 1.1 christos x_parser_free(&cfile);
2319 1.1 christos return (ISC_R_FAILURE);
2320 1.1 christos }
2321 1.1 christos
2322 1.1 christos #if defined(DEBUG_LDAP)
2323 1.1 christos log_info ("LDAP: Parsing dhcpServer options '%s' ...", hostdn);
2324 1.1 christos #endif
2325 1.1 christos
2326 1.1 christos res = ldap_parse_entry_options(hostent, cfile, NULL);
2327 1.1 christos if (res != ISC_R_SUCCESS)
2328 1.1 christos {
2329 1.1 christos ldap_value_free_len (tempbv);
2330 1.1 christos ldap_msgfree (hostres);
2331 1.1 christos ldap_memfree (hostdn);
2332 1.1 christos ldap_stop();
2333 1.1 christos x_parser_free(&cfile);
2334 1.1 christos return res;
2335 1.1 christos }
2336 1.1 christos
2337 1.1 christos if (x_parser_length(cfile) > 0)
2338 1.1 christos {
2339 1.1 christos ldap_write_debug(cfile->inbuf, cfile->buflen);
2340 1.1 christos
2341 1.1 christos res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
2342 1.1 christos if (res != ISC_R_SUCCESS)
2343 1.1 christos {
2344 1.1 christos log_error ("LDAP: cannot parse dhcpServer entry '%s'", hostdn);
2345 1.1 christos ldap_value_free_len (tempbv);
2346 1.1 christos ldap_msgfree (hostres);
2347 1.1 christos ldap_memfree (hostdn);
2348 1.1 christos ldap_stop();
2349 1.1 christos x_parser_free(&cfile);
2350 1.1 christos return res;
2351 1.1 christos }
2352 1.1 christos x_parser_reset(cfile);
2353 1.1 christos }
2354 1.1 christos ldap_msgfree (hostres);
2355 1.1 christos
2356 1.1 christos res = ISC_R_SUCCESS;
2357 1.1 christos for (cnt=0; tempbv[cnt] != NULL; cnt++)
2358 1.1 christos {
2359 1.1 christos
2360 1.1 christos if (_do_ldap_str2esc_filter_bv(hostdn, 0, &bv_o[0]) == NULL)
2361 1.1 christos {
2362 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", hostdn);
2363 1.1 christos res = ISC_R_FAILURE;
2364 1.1 christos break;
2365 1.1 christos }
2366 1.1 christos
2367 1.1 christos snprintf(sfilter, sizeof(sfilter), "(&(objectClass=dhcpService)"
2368 1.1 christos "(|(|(dhcpPrimaryDN=%s)(dhcpSecondaryDN=%s))(dhcpServerDN=%s)))",
2369 1.1 christos bv_o[0].bv_val, bv_o[0].bv_val, bv_o[0].bv_val);
2370 1.1 christos
2371 1.1 christos ber_memfree(bv_o[0].bv_val);
2372 1.1 christos
2373 1.1 christos ldres = NULL;
2374 1.1 christos if ((ret = ldap_search_ext_s (ld, tempbv[cnt]->bv_val, LDAP_SCOPE_BASE,
2375 1.1 christos sfilter, NULL, 0, NULL, NULL, NULL,
2376 1.1 christos 0, &ldres)) != LDAP_SUCCESS)
2377 1.1 christos {
2378 1.1 christos log_error ("Error searching for dhcpServiceDN '%s': %s. Please update the LDAP entry '%s'",
2379 1.1 christos tempbv[cnt]->bv_val, ldap_err2string (ret), hostdn);
2380 1.1 christos if(NULL != ldres)
2381 1.1 christos ldap_msgfree(ldres);
2382 1.1 christos res = ISC_R_FAILURE;
2383 1.1 christos break;
2384 1.1 christos }
2385 1.1 christos
2386 1.1 christos if ((ent = ldap_first_entry (ld, ldres)) == NULL)
2387 1.1 christos {
2388 1.1 christos log_error ("Error: Cannot find dhcpService DN '%s' with server reference. Please update the LDAP server entry '%s'",
2389 1.1 christos tempbv[cnt]->bv_val, hostdn);
2390 1.1 christos
2391 1.1 christos ldap_msgfree(ldres);
2392 1.1 christos res = ISC_R_FAILURE;
2393 1.1 christos break;
2394 1.1 christos }
2395 1.1 christos
2396 1.1 christos /*
2397 1.1 christos ** FIXME: how to free the remembered dn's on exit?
2398 1.1 christos ** This should be OK if dmalloc registers the
2399 1.1 christos ** memory it allocated and frees it on exit..
2400 1.1 christos */
2401 1.1 christos
2402 1.1 christos curr = dmalloc (sizeof (*curr), MDL);
2403 1.1 christos if (curr != NULL)
2404 1.1 christos {
2405 1.1 christos length = strlen (tempbv[cnt]->bv_val);
2406 1.1 christos curr->dn = dmalloc (length + 1, MDL);
2407 1.1 christos if (curr->dn == NULL)
2408 1.1 christos {
2409 1.1 christos dfree (curr, MDL);
2410 1.1 christos curr = NULL;
2411 1.1 christos }
2412 1.1 christos else
2413 1.1 christos strcpy (curr->dn, tempbv[cnt]->bv_val);
2414 1.1 christos }
2415 1.1 christos
2416 1.1 christos if (curr != NULL)
2417 1.1 christos {
2418 1.1 christos curr->refs++;
2419 1.1 christos
2420 1.1 christos /* append to service-dn list */
2421 1.1 christos if (ldap_service_dn_tail != NULL)
2422 1.1 christos ldap_service_dn_tail->next = curr;
2423 1.1 christos else
2424 1.1 christos ldap_service_dn_head = curr;
2425 1.1 christos
2426 1.1 christos ldap_service_dn_tail = curr;
2427 1.1 christos }
2428 1.1 christos else
2429 1.1 christos log_fatal ("no memory to remember ldap service dn");
2430 1.1 christos
2431 1.1 christos #if defined (DEBUG_LDAP)
2432 1.1 christos log_info ("LDAP: Parsing dhcpService DN '%s' ...", tempbv[cnt]->bv_val);
2433 1.1 christos #endif
2434 1.1 christos add_to_config_stack (ldres, ent);
2435 1.1 christos res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
2436 1.1 christos if (res != ISC_R_SUCCESS)
2437 1.1 christos {
2438 1.1 christos log_error ("LDAP: cannot parse dhcpService entry '%s'", tempbv[cnt]->bv_val);
2439 1.1 christos break;
2440 1.1 christos }
2441 1.1 christos }
2442 1.1 christos
2443 1.1 christos x_parser_free(&cfile);
2444 1.1 christos ldap_close_debug_fd();
2445 1.1 christos
2446 1.1 christos ldap_memfree (hostdn);
2447 1.1 christos ldap_value_free_len (tempbv);
2448 1.1 christos
2449 1.1 christos if (res != ISC_R_SUCCESS)
2450 1.1 christos {
2451 1.1 christos struct ldap_config_stack *temp_stack;
2452 1.1 christos
2453 1.1 christos while ((curr = ldap_service_dn_head) != NULL)
2454 1.1 christos {
2455 1.1 christos ldap_service_dn_head = curr->next;
2456 1.1 christos dfree (curr->dn, MDL);
2457 1.1 christos dfree (curr, MDL);
2458 1.1 christos }
2459 1.1 christos
2460 1.1 christos ldap_service_dn_tail = NULL;
2461 1.1 christos
2462 1.1 christos while ((temp_stack = ldap_stack) != NULL)
2463 1.1 christos {
2464 1.1 christos ldap_stack = temp_stack->next;
2465 1.1 christos free_stack_entry (temp_stack);
2466 1.1 christos }
2467 1.1 christos
2468 1.1 christos ldap_stop();
2469 1.1 christos }
2470 1.1 christos
2471 1.1 christos /* Unbind from ldap immediately after reading config in static mode. */
2472 1.1 christos if (ldap_method == LDAP_METHOD_STATIC)
2473 1.1 christos ldap_stop();
2474 1.1 christos
2475 1.1 christos return (res);
2476 1.1 christos }
2477 1.1 christos
2478 1.1 christos
2479 1.1 christos /* This function will parse the dhcpOption and dhcpStatements field in the LDAP
2480 1.1 christos entry if it exists. Right now, type will be either HOST_DECL or CLASS_DECL.
2481 1.1 christos If we are parsing a HOST_DECL, this always returns 0. If we are parsing a
2482 1.1 christos CLASS_DECL, this will return what the current lease limit is in LDAP. If
2483 1.1 christos there is no lease limit specified, we return 0 */
2484 1.1 christos
2485 1.1 christos static int
2486 1.1 christos ldap_parse_options (LDAPMessage * ent, struct group *group,
2487 1.1 christos int type, struct host_decl *host,
2488 1.1 christos struct class **class)
2489 1.1 christos {
2490 1.1 christos int declaration, lease_limit;
2491 1.1 christos enum dhcp_token token;
2492 1.1 christos struct parse *cfile;
2493 1.1 christos isc_result_t res;
2494 1.1 christos const char *val;
2495 1.1 christos
2496 1.1 christos lease_limit = 0;
2497 1.1 christos cfile = x_parser_init(type == HOST_DECL ? "LDAP-HOST" : "LDAP-SUBCLASS");
2498 1.1 christos if (cfile == NULL)
2499 1.1 christos return (lease_limit);
2500 1.1 christos
2501 1.1 christos /* This block of code will try to find the parent of the host, and
2502 1.1 christos if it is a group object, fetch the options and apply to the host. */
2503 1.1 christos if (type == HOST_DECL)
2504 1.1 christos {
2505 1.1 christos char *hostdn, *basedn, *temp1, *temp2, filter[1024];
2506 1.1 christos LDAPMessage *groupdn, *entry;
2507 1.1 christos int ret;
2508 1.1 christos
2509 1.1 christos hostdn = ldap_get_dn (ld, ent);
2510 1.1 christos if( hostdn != NULL)
2511 1.1 christos {
2512 1.1 christos basedn = NULL;
2513 1.1 christos
2514 1.1 christos temp1 = strchr (hostdn, '=');
2515 1.1 christos if (temp1 != NULL)
2516 1.1 christos temp1 = strchr (++temp1, '=');
2517 1.1 christos if (temp1 != NULL)
2518 1.1 christos temp2 = strchr (++temp1, ',');
2519 1.1 christos else
2520 1.1 christos temp2 = NULL;
2521 1.1 christos
2522 1.1 christos if (temp2 != NULL)
2523 1.1 christos {
2524 1.1 christos struct berval bv_o;
2525 1.1 christos
2526 1.1 christos if (_do_ldap_str2esc_filter_bv(temp1, (temp2 - temp1), &bv_o) == NULL)
2527 1.1 christos {
2528 1.1 christos log_error ("Cannot escape ldap filter value %.*s: %m",
2529 1.1 christos (int)(temp2 - temp1), temp1);
2530 1.1 christos filter[0] = '\0';
2531 1.1 christos }
2532 1.1 christos else
2533 1.1 christos {
2534 1.1 christos snprintf (filter, sizeof(filter),
2535 1.1 christos "(&(cn=%s)(objectClass=dhcpGroup))",
2536 1.1 christos bv_o.bv_val);
2537 1.1 christos
2538 1.1 christos ber_memfree(bv_o.bv_val);
2539 1.1 christos }
2540 1.1 christos
2541 1.1 christos basedn = strchr (temp1, ',');
2542 1.1 christos if (basedn != NULL)
2543 1.1 christos ++basedn;
2544 1.1 christos }
2545 1.1 christos
2546 1.1 christos if (basedn != NULL && *basedn != '\0' && filter[0] != '\0')
2547 1.1 christos {
2548 1.1 christos ret = ldap_search_ext_s (ld, basedn, LDAP_SCOPE_SUBTREE, filter,
2549 1.1 christos NULL, 0, NULL, NULL, NULL, 0, &groupdn);
2550 1.1 christos if (ret == LDAP_SUCCESS)
2551 1.1 christos {
2552 1.1 christos if ((entry = ldap_first_entry (ld, groupdn)) != NULL)
2553 1.1 christos {
2554 1.1 christos res = ldap_parse_entry_options (entry, cfile, &lease_limit);
2555 1.1 christos if (res != ISC_R_SUCCESS)
2556 1.1 christos {
2557 1.1 christos /* reset option buffer discarding any results */
2558 1.1 christos x_parser_reset(cfile);
2559 1.1 christos lease_limit = 0;
2560 1.1 christos }
2561 1.1 christos }
2562 1.1 christos ldap_msgfree( groupdn);
2563 1.1 christos }
2564 1.1 christos }
2565 1.1 christos ldap_memfree( hostdn);
2566 1.1 christos }
2567 1.1 christos }
2568 1.1 christos
2569 1.1 christos res = ldap_parse_entry_options (ent, cfile, &lease_limit);
2570 1.1 christos if (res != ISC_R_SUCCESS)
2571 1.1 christos {
2572 1.1 christos x_parser_free(&cfile);
2573 1.1 christos return (lease_limit);
2574 1.1 christos }
2575 1.1 christos
2576 1.1 christos if (x_parser_length(cfile) == 0)
2577 1.1 christos {
2578 1.1 christos x_parser_free(&cfile);
2579 1.1 christos return (lease_limit);
2580 1.1 christos }
2581 1.1 christos
2582 1.1 christos declaration = 0;
2583 1.1 christos do
2584 1.1 christos {
2585 1.1 christos token = peek_token (&val, NULL, cfile);
2586 1.1 christos if (token == END_OF_FILE)
2587 1.1 christos break;
2588 1.1 christos declaration = parse_statement (cfile, group, type, host, declaration);
2589 1.1 christos } while (1);
2590 1.1 christos
2591 1.1 christos x_parser_free(&cfile);
2592 1.1 christos
2593 1.1 christos return (lease_limit);
2594 1.1 christos }
2595 1.1 christos
2596 1.1 christos
2597 1.1 christos
2598 1.1 christos int
2599 1.1 christos find_haddr_in_ldap (struct host_decl **hp, int htype, unsigned hlen,
2600 1.1 christos const unsigned char *haddr, const char *file, int line)
2601 1.1 christos {
2602 1.1 christos char buf[128], *type_str;
2603 1.1 christos LDAPMessage * res, *ent;
2604 1.1 christos struct host_decl * host;
2605 1.1 christos isc_result_t status;
2606 1.1 christos ldap_dn_node *curr;
2607 1.1 christos char up_hwaddr[20];
2608 1.1 christos char lo_hwaddr[20];
2609 1.1 christos int ret;
2610 1.1 christos struct berval bv_o[2];
2611 1.1 christos
2612 1.1 christos *hp = NULL;
2613 1.1 christos
2614 1.1 christos
2615 1.1 christos if (ldap_method == LDAP_METHOD_STATIC)
2616 1.1 christos return (0);
2617 1.1 christos
2618 1.1 christos if (ld == NULL)
2619 1.1 christos ldap_start ();
2620 1.1 christos if (ld == NULL)
2621 1.1 christos return (0);
2622 1.1 christos
2623 1.1 christos switch (htype)
2624 1.1 christos {
2625 1.1 christos case HTYPE_ETHER:
2626 1.1 christos type_str = "ethernet";
2627 1.1 christos break;
2628 1.1 christos case HTYPE_IEEE802:
2629 1.1 christos type_str = "token-ring";
2630 1.1 christos break;
2631 1.1 christos case HTYPE_FDDI:
2632 1.1 christos type_str = "fddi";
2633 1.1 christos break;
2634 1.1 christos default:
2635 1.1 christos log_info ("Ignoring unknown type %d", htype);
2636 1.1 christos return (0);
2637 1.1 christos }
2638 1.1 christos
2639 1.1 christos /*
2640 1.1 christos ** FIXME: It is not guaranteed, that the dhcpHWAddress attribute
2641 1.1 christos ** contains _exactly_ "type addr" with one space between!
2642 1.1 christos */
2643 1.1 christos snprintf(lo_hwaddr, sizeof(lo_hwaddr), "%s",
2644 1.1 christos print_hw_addr (htype, hlen, haddr));
2645 1.1 christos x_strxform(up_hwaddr, lo_hwaddr, sizeof(up_hwaddr), toupper);
2646 1.1 christos
2647 1.1 christos if (_do_ldap_str2esc_filter_bv(lo_hwaddr, 0, &bv_o[0]) == NULL)
2648 1.1 christos {
2649 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", lo_hwaddr);
2650 1.1 christos return (0);
2651 1.1 christos }
2652 1.1 christos if (_do_ldap_str2esc_filter_bv(up_hwaddr, 0, &bv_o[1]) == NULL)
2653 1.1 christos {
2654 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", up_hwaddr);
2655 1.1 christos ber_memfree(bv_o[0].bv_val);
2656 1.1 christos return (0);
2657 1.1 christos }
2658 1.1 christos
2659 1.1 christos snprintf (buf, sizeof (buf),
2660 1.1 christos "(&(objectClass=dhcpHost)(|(dhcpHWAddress=%s %s)(dhcpHWAddress=%s %s)))",
2661 1.1 christos type_str, bv_o[0].bv_val, type_str, bv_o[1].bv_val);
2662 1.1 christos
2663 1.1 christos ber_memfree(bv_o[0].bv_val);
2664 1.1 christos ber_memfree(bv_o[1].bv_val);
2665 1.1 christos
2666 1.1 christos res = ent = NULL;
2667 1.1 christos for (curr = ldap_service_dn_head;
2668 1.1 christos curr != NULL && *curr->dn != '\0';
2669 1.1 christos curr = curr->next)
2670 1.1 christos {
2671 1.1 christos #if defined (DEBUG_LDAP)
2672 1.1 christos log_info ("Searching for %s in LDAP tree %s", buf, curr->dn);
2673 1.1 christos #endif
2674 1.1 christos ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL, 0,
2675 1.1 christos NULL, NULL, NULL, 0, &res);
2676 1.1 christos
2677 1.1 christos if(ret == LDAP_SERVER_DOWN)
2678 1.1 christos {
2679 1.1 christos log_info ("LDAP server was down, trying to reconnect...");
2680 1.1 christos
2681 1.1 christos ldap_stop();
2682 1.1 christos ldap_start();
2683 1.1 christos if(ld == NULL)
2684 1.1 christos {
2685 1.1 christos log_info ("LDAP reconnect failed - try again later...");
2686 1.1 christos return (0);
2687 1.1 christos }
2688 1.1 christos
2689 1.1 christos ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL,
2690 1.1 christos 0, NULL, NULL, NULL, 0, &res);
2691 1.1 christos }
2692 1.1 christos
2693 1.1 christos if (ret == LDAP_SUCCESS)
2694 1.1 christos {
2695 1.1 christos ent = ldap_first_entry (ld, res);
2696 1.1 christos #if defined (DEBUG_LDAP)
2697 1.1 christos if (ent == NULL) {
2698 1.1 christos log_info ("No host entry for %s in LDAP tree %s",
2699 1.1 christos buf, curr->dn);
2700 1.1 christos }
2701 1.1 christos #endif
2702 1.1 christos while (ent != NULL) {
2703 1.1 christos #if defined (DEBUG_LDAP)
2704 1.1 christos char *dn = ldap_get_dn (ld, ent);
2705 1.1 christos if (dn != NULL)
2706 1.1 christos {
2707 1.1 christos log_info ("Found dhcpHWAddress LDAP entry %s", dn);
2708 1.1 christos ldap_memfree(dn);
2709 1.1 christos }
2710 1.1 christos #endif
2711 1.1 christos
2712 1.1 christos host = (struct host_decl *)0;
2713 1.1 christos status = host_allocate (&host, MDL);
2714 1.1 christos if (status != ISC_R_SUCCESS)
2715 1.1 christos {
2716 1.1 christos log_fatal ("can't allocate host decl struct: %s",
2717 1.1 christos isc_result_totext (status));
2718 1.1 christos ldap_msgfree (res);
2719 1.1 christos return (0);
2720 1.1 christos }
2721 1.1 christos
2722 1.1 christos host->name = ldap_get_host_name (ent);
2723 1.1 christos if (host->name == NULL)
2724 1.1 christos {
2725 1.1 christos host_dereference (&host, MDL);
2726 1.1 christos ldap_msgfree (res);
2727 1.1 christos return (0);
2728 1.1 christos }
2729 1.1 christos
2730 1.1 christos if (!clone_group (&host->group, root_group, MDL))
2731 1.1 christos {
2732 1.1 christos log_fatal ("can't clone group for host %s", host->name);
2733 1.1 christos host_dereference (&host, MDL);
2734 1.1 christos ldap_msgfree (res);
2735 1.1 christos return (0);
2736 1.1 christos }
2737 1.1 christos
2738 1.1 christos ldap_parse_options (ent, host->group, HOST_DECL, host, NULL);
2739 1.1 christos
2740 1.1 christos host->n_ipaddr = *hp;
2741 1.1 christos *hp = host;
2742 1.1 christos ent = ldap_next_entry (ld, ent);
2743 1.1 christos }
2744 1.1 christos if(res)
2745 1.1 christos {
2746 1.1 christos ldap_msgfree (res);
2747 1.1 christos res = NULL;
2748 1.1 christos }
2749 1.1 christos return (*hp != NULL);
2750 1.1 christos }
2751 1.1 christos else
2752 1.1 christos {
2753 1.1 christos if(res)
2754 1.1 christos {
2755 1.1 christos ldap_msgfree (res);
2756 1.1 christos res = NULL;
2757 1.1 christos }
2758 1.1 christos
2759 1.1 christos if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
2760 1.1 christos {
2761 1.1 christos log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
2762 1.1 christos curr->dn, ldap_err2string (ret));
2763 1.1 christos ldap_stop();
2764 1.1 christos return (0);
2765 1.1 christos }
2766 1.1 christos #if defined (DEBUG_LDAP)
2767 1.1 christos else
2768 1.1 christos {
2769 1.1 christos log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
2770 1.1 christos ldap_err2string (ret), buf, curr->dn);
2771 1.1 christos }
2772 1.1 christos #endif
2773 1.1 christos }
2774 1.1 christos }
2775 1.1 christos
2776 1.1 christos return (0);
2777 1.1 christos }
2778 1.1 christos
2779 1.1 christos
2780 1.1 christos int
2781 1.1 christos find_subclass_in_ldap (struct class *class, struct class **newclass,
2782 1.1 christos struct data_string *data)
2783 1.1 christos {
2784 1.1 christos LDAPMessage * res, * ent;
2785 1.1 christos int ret, lease_limit;
2786 1.1 christos isc_result_t status;
2787 1.1 christos ldap_dn_node *curr;
2788 1.1 christos char buf[2048];
2789 1.1 christos struct berval bv_class;
2790 1.1 christos struct berval bv_cdata;
2791 1.1 christos char *hex_1;
2792 1.1 christos
2793 1.1 christos if (ldap_method == LDAP_METHOD_STATIC)
2794 1.1 christos return (0);
2795 1.1 christos
2796 1.1 christos if (ld == NULL)
2797 1.1 christos ldap_start ();
2798 1.1 christos if (ld == NULL)
2799 1.1 christos return (0);
2800 1.1 christos
2801 1.1 christos hex_1 = print_hex_1 (data->len, data->data, 1024);
2802 1.1 christos if (*hex_1 == '"')
2803 1.1 christos {
2804 1.1 christos /* result is a quotted not hex string: ldap escape the original string */
2805 1.1 christos if (_do_ldap_str2esc_filter_bv((const char*)data->data, data->len, &bv_cdata) == NULL)
2806 1.1 christos {
2807 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", hex_1);
2808 1.1 christos return (0);
2809 1.1 christos }
2810 1.1 christos hex_1 = NULL;
2811 1.1 christos }
2812 1.1 christos if (_do_ldap_str2esc_filter_bv(class->name, strlen (class->name), &bv_class) == NULL)
2813 1.1 christos {
2814 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", class->name);
2815 1.1 christos if (hex_1 == NULL)
2816 1.1 christos ber_memfree(bv_cdata.bv_val);
2817 1.1 christos return (0);
2818 1.1 christos }
2819 1.1 christos
2820 1.1 christos snprintf (buf, sizeof (buf),
2821 1.1 christos "(&(objectClass=dhcpSubClass)(cn=%s)(dhcpClassData=%s))",
2822 1.1 christos (hex_1 == NULL ? bv_cdata.bv_val : hex_1), bv_class.bv_val);
2823 1.1 christos
2824 1.1 christos if (hex_1 == NULL)
2825 1.1 christos ber_memfree(bv_cdata.bv_val);
2826 1.1 christos ber_memfree(bv_class.bv_val);
2827 1.1 christos
2828 1.1 christos #if defined (DEBUG_LDAP)
2829 1.1 christos log_info ("Searching LDAP for %s", buf);
2830 1.1 christos #endif
2831 1.1 christos
2832 1.1 christos res = ent = NULL;
2833 1.1 christos for (curr = ldap_service_dn_head;
2834 1.1 christos curr != NULL && *curr->dn != '\0';
2835 1.1 christos curr = curr->next)
2836 1.1 christos {
2837 1.1 christos #if defined (DEBUG_LDAP)
2838 1.1 christos log_info ("Searching for %s in LDAP tree %s", buf, curr->dn);
2839 1.1 christos #endif
2840 1.1 christos ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL, 0,
2841 1.1 christos NULL, NULL, NULL, 0, &res);
2842 1.1 christos
2843 1.1 christos if(ret == LDAP_SERVER_DOWN)
2844 1.1 christos {
2845 1.1 christos log_info ("LDAP server was down, trying to reconnect...");
2846 1.1 christos
2847 1.1 christos ldap_stop();
2848 1.1 christos ldap_start();
2849 1.1 christos
2850 1.1 christos if(ld == NULL)
2851 1.1 christos {
2852 1.1 christos log_info ("LDAP reconnect failed - try again later...");
2853 1.1 christos return (0);
2854 1.1 christos }
2855 1.1 christos
2856 1.1 christos ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf,
2857 1.1 christos NULL, 0, NULL, NULL, NULL, 0, &res);
2858 1.1 christos }
2859 1.1 christos
2860 1.1 christos if (ret == LDAP_SUCCESS)
2861 1.1 christos {
2862 1.1 christos if( (ent = ldap_first_entry (ld, res)) != NULL)
2863 1.1 christos break; /* search OK and have entry */
2864 1.1 christos
2865 1.1 christos #if defined (DEBUG_LDAP)
2866 1.1 christos log_info ("No subclass entry for %s in LDAP tree %s",
2867 1.1 christos buf, curr->dn);
2868 1.1 christos #endif
2869 1.1 christos if(res)
2870 1.1 christos {
2871 1.1 christos ldap_msgfree (res);
2872 1.1 christos res = NULL;
2873 1.1 christos }
2874 1.1 christos }
2875 1.1 christos else
2876 1.1 christos {
2877 1.1 christos if(res)
2878 1.1 christos {
2879 1.1 christos ldap_msgfree (res);
2880 1.1 christos res = NULL;
2881 1.1 christos }
2882 1.1 christos
2883 1.1 christos if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
2884 1.1 christos {
2885 1.1 christos log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
2886 1.1 christos curr->dn, ldap_err2string (ret));
2887 1.1 christos ldap_stop();
2888 1.1 christos return (0);
2889 1.1 christos }
2890 1.1 christos #if defined (DEBUG_LDAP)
2891 1.1 christos else
2892 1.1 christos {
2893 1.1 christos log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
2894 1.1 christos ldap_err2string (ret), buf, curr->dn);
2895 1.1 christos }
2896 1.1 christos #endif
2897 1.1 christos }
2898 1.1 christos }
2899 1.1 christos
2900 1.1 christos if (res && ent)
2901 1.1 christos {
2902 1.1 christos #if defined (DEBUG_LDAP)
2903 1.1 christos char *dn = ldap_get_dn (ld, ent);
2904 1.1 christos if (dn != NULL)
2905 1.1 christos {
2906 1.1 christos log_info ("Found subclass LDAP entry %s", dn);
2907 1.1 christos ldap_memfree(dn);
2908 1.1 christos }
2909 1.1 christos #endif
2910 1.1 christos
2911 1.1 christos status = class_allocate (newclass, MDL);
2912 1.1 christos if (status != ISC_R_SUCCESS)
2913 1.1 christos {
2914 1.1 christos log_error ("Cannot allocate memory for a new class");
2915 1.1 christos ldap_msgfree (res);
2916 1.1 christos return (0);
2917 1.1 christos }
2918 1.1 christos
2919 1.1 christos group_reference (&(*newclass)->group, class->group, MDL);
2920 1.1 christos class_reference (&(*newclass)->superclass, class, MDL);
2921 1.1 christos lease_limit = ldap_parse_options (ent, (*newclass)->group,
2922 1.1 christos CLASS_DECL, NULL, newclass);
2923 1.1 christos if (lease_limit == 0)
2924 1.1 christos (*newclass)->lease_limit = class->lease_limit;
2925 1.1 christos else
2926 1.1 christos class->lease_limit = lease_limit;
2927 1.1 christos
2928 1.1 christos if ((*newclass)->lease_limit)
2929 1.1 christos {
2930 1.1 christos (*newclass)->billed_leases =
2931 1.1 christos dmalloc ((*newclass)->lease_limit * sizeof (struct lease *), MDL);
2932 1.1 christos if (!(*newclass)->billed_leases)
2933 1.1 christos {
2934 1.1 christos log_error ("no memory for billing");
2935 1.1 christos class_dereference (newclass, MDL);
2936 1.1 christos ldap_msgfree (res);
2937 1.1 christos return (0);
2938 1.1 christos }
2939 1.1 christos memset ((*newclass)->billed_leases, 0,
2940 1.1 christos ((*newclass)->lease_limit * sizeof (struct lease *)));
2941 1.1 christos }
2942 1.1 christos
2943 1.1 christos data_string_copy (&(*newclass)->hash_string, data, MDL);
2944 1.1 christos
2945 1.1 christos ldap_msgfree (res);
2946 1.1 christos return (1);
2947 1.1 christos }
2948 1.1 christos
2949 1.1 christos if(res) ldap_msgfree (res);
2950 1.1 christos return (0);
2951 1.1 christos }
2952 1.1 christos
2953 1.1 christos int find_client_in_ldap (struct host_decl **hp, struct packet *packet,
2954 1.1 christos struct option_state *state, const char *file, int line)
2955 1.1 christos {
2956 1.1 christos LDAPMessage * res, * ent;
2957 1.1 christos ldap_dn_node *curr;
2958 1.1 christos struct host_decl * host;
2959 1.1 christos isc_result_t status;
2960 1.1 christos struct data_string client_id;
2961 1.1 christos char buf[1024], buf1[1024];
2962 1.1 christos int ret;
2963 1.1 christos
2964 1.1 christos if (ldap_method == LDAP_METHOD_STATIC)
2965 1.1 christos return (0);
2966 1.1 christos
2967 1.1 christos if (ld == NULL)
2968 1.1 christos ldap_start ();
2969 1.1 christos if (ld == NULL)
2970 1.1 christos return (0);
2971 1.1 christos
2972 1.1 christos memset(&client_id, 0, sizeof(client_id));
2973 1.1 christos if (get_client_id(packet, &client_id) != ISC_R_SUCCESS)
2974 1.1 christos return (0);
2975 1.1 christos snprintf(buf, sizeof(buf),
2976 1.1 christos "(&(objectClass=dhcpHost)(dhcpClientId=%s))",
2977 1.1 christos print_hw_addr(0, client_id.len, client_id.data));
2978 1.1 christos
2979 1.1 christos /* log_info ("Searching LDAP for %s (%s)", buf, packet->interface->shared_network->name); */
2980 1.1 christos
2981 1.1 christos res = ent = NULL;
2982 1.1 christos for (curr = ldap_service_dn_head;
2983 1.1 christos curr != NULL && *curr->dn != '\0';
2984 1.1 christos curr = curr->next)
2985 1.1 christos {
2986 1.1 christos snprintf(buf1, sizeof(buf1), "cn=%s,%s", packet->interface->shared_network->name, curr->dn);
2987 1.1 christos #if defined (DEBUG_LDAP)
2988 1.1 christos log_info ("Searching for %s in LDAP tree %s", buf, buf1);
2989 1.1 christos #endif
2990 1.1 christos ret = ldap_search_ext_s (ld, buf1, LDAP_SCOPE_SUBTREE, buf, NULL, 0,
2991 1.1 christos NULL, NULL, NULL, 0, &res);
2992 1.1 christos
2993 1.1 christos if(ret == LDAP_SERVER_DOWN)
2994 1.1 christos {
2995 1.1 christos log_info ("LDAP server was down, trying to reconnect...");
2996 1.1 christos
2997 1.1 christos ldap_stop();
2998 1.1 christos ldap_start();
2999 1.1 christos
3000 1.1 christos if(ld == NULL)
3001 1.1 christos {
3002 1.1 christos log_info ("LDAP reconnect failed - try again later...");
3003 1.1 christos return (0);
3004 1.1 christos }
3005 1.1 christos
3006 1.1 christos ret = ldap_search_ext_s (ld, buf1, LDAP_SCOPE_SUBTREE, buf,
3007 1.1 christos NULL, 0, NULL, NULL, NULL, 0, &res);
3008 1.1 christos }
3009 1.1 christos
3010 1.1 christos if (ret == LDAP_SUCCESS)
3011 1.1 christos {
3012 1.1 christos if( (ent = ldap_first_entry (ld, res)) != NULL) {
3013 1.1 christos log_info ("found entry in search %s", buf1);
3014 1.1 christos break; /* search OK and have entry */
3015 1.1 christos }
3016 1.1 christos
3017 1.1 christos #if defined (DEBUG_LDAP)
3018 1.1 christos log_info ("No subclass entry for %s in LDAP tree %s", buf, curr->dn);
3019 1.1 christos #endif
3020 1.1 christos if(res)
3021 1.1 christos {
3022 1.1 christos ldap_msgfree (res);
3023 1.1 christos res = NULL;
3024 1.1 christos }
3025 1.1 christos }
3026 1.1 christos else
3027 1.1 christos {
3028 1.1 christos if(res)
3029 1.1 christos {
3030 1.1 christos ldap_msgfree (res);
3031 1.1 christos res = NULL;
3032 1.1 christos }
3033 1.1 christos
3034 1.1 christos if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
3035 1.1 christos {
3036 1.1 christos log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
3037 1.1 christos curr->dn, ldap_err2string (ret));
3038 1.1 christos ldap_stop();
3039 1.1 christos return (0);
3040 1.1 christos }
3041 1.1 christos else
3042 1.1 christos {
3043 1.1 christos log_info ("did not find: %s", buf);
3044 1.1 christos }
3045 1.1 christos }
3046 1.1 christos }
3047 1.1 christos
3048 1.1 christos if (res && ent)
3049 1.1 christos {
3050 1.1 christos #if defined (DEBUG_LDAP)
3051 1.1 christos log_info ("ldap_get_dn %s", curr->dn);
3052 1.1 christos char *dn = ldap_get_dn (ld, ent);
3053 1.1 christos if (dn != NULL)
3054 1.1 christos {
3055 1.1 christos log_info ("Found subclass LDAP entry %s", dn);
3056 1.1 christos ldap_memfree(dn);
3057 1.1 christos } else {
3058 1.1 christos log_info ("DN is null %s", dn);
3059 1.1 christos }
3060 1.1 christos #endif
3061 1.1 christos
3062 1.1 christos host = (struct host_decl *)0;
3063 1.1 christos status = host_allocate (&host, MDL);
3064 1.1 christos if (status != ISC_R_SUCCESS)
3065 1.1 christos {
3066 1.1 christos log_fatal ("can't allocate host decl struct: %s",
3067 1.1 christos isc_result_totext (status));
3068 1.1 christos ldap_msgfree (res);
3069 1.1 christos return (0);
3070 1.1 christos }
3071 1.1 christos
3072 1.1 christos host->name = ldap_get_host_name (ent);
3073 1.1 christos if (host->name == NULL)
3074 1.1 christos {
3075 1.1 christos host_dereference (&host, MDL);
3076 1.1 christos ldap_msgfree (res);
3077 1.1 christos return (0);
3078 1.1 christos }
3079 1.1 christos /* log_info ("Host name %s", host->name); */
3080 1.1 christos
3081 1.1 christos if (!clone_group (&host->group, root_group, MDL))
3082 1.1 christos {
3083 1.1 christos log_fatal ("can't clone group for host %s", host->name);
3084 1.1 christos host_dereference (&host, MDL);
3085 1.1 christos ldap_msgfree (res);
3086 1.1 christos return (0);
3087 1.1 christos }
3088 1.1 christos
3089 1.1 christos ldap_parse_options (ent, host->group, HOST_DECL, host, NULL);
3090 1.1 christos
3091 1.1 christos *hp = host;
3092 1.1 christos ldap_msgfree (res);
3093 1.1 christos return (1);
3094 1.1 christos }
3095 1.1 christos else
3096 1.1 christos {
3097 1.1 christos log_info ("did not find clientid: %s", buf);
3098 1.1 christos }
3099 1.1 christos
3100 1.1 christos if(res) ldap_msgfree (res);
3101 1.1 christos return (0);
3102 1.1 christos
3103 1.1 christos }
3104 1.1 christos
3105 1.1 christos #if defined(LDAP_USE_GSSAPI)
3106 1.1 christos static int
3107 1.1 christos _ldap_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *sin)
3108 1.1 christos {
3109 1.1 christos sasl_interact_t *in;
3110 1.1 christos struct ldap_sasl_instance *ldap_inst = defaults;
3111 1.1 christos int ret = LDAP_OTHER;
3112 1.1 christos size_t size;
3113 1.1 christos
3114 1.1 christos if (ld == NULL || sin == NULL)
3115 1.1 christos return LDAP_PARAM_ERROR;
3116 1.1 christos
3117 1.1 christos log_info("doing interactive bind");
3118 1.1 christos for (in = sin; in != NULL && in->id != SASL_CB_LIST_END; in++) {
3119 1.1 christos switch (in->id) {
3120 1.1 christos case SASL_CB_USER:
3121 1.1 christos log_info("got request for SASL_CB_USER %s", ldap_inst->sasl_authz_id);
3122 1.1 christos size = strlen(ldap_inst->sasl_authz_id);
3123 1.1 christos in->result = ldap_inst->sasl_authz_id;
3124 1.1 christos in->len = size;
3125 1.1 christos ret = LDAP_SUCCESS;
3126 1.1 christos break;
3127 1.1 christos case SASL_CB_GETREALM:
3128 1.1 christos log_info("got request for SASL_CB_GETREALM %s", ldap_inst->sasl_realm);
3129 1.1 christos size = strlen(ldap_inst->sasl_realm);
3130 1.1 christos in->result = ldap_inst->sasl_realm;
3131 1.1 christos in->len = size;
3132 1.1 christos ret = LDAP_SUCCESS;
3133 1.1 christos break;
3134 1.1 christos case SASL_CB_AUTHNAME:
3135 1.1 christos log_info("got request for SASL_CB_AUTHNAME %s", ldap_inst->sasl_authc_id);
3136 1.1 christos size = strlen(ldap_inst->sasl_authc_id);
3137 1.1 christos in->result = ldap_inst->sasl_authc_id;
3138 1.1 christos in->len = size;
3139 1.1 christos ret = LDAP_SUCCESS;
3140 1.1 christos break;
3141 1.1 christos case SASL_CB_PASS:
3142 1.1 christos log_info("got request for SASL_CB_PASS %s", ldap_inst->sasl_password);
3143 1.1 christos size = strlen(ldap_inst->sasl_password);
3144 1.1 christos in->result = ldap_inst->sasl_password;
3145 1.1 christos in->len = size;
3146 1.1 christos ret = LDAP_SUCCESS;
3147 1.1 christos break;
3148 1.1 christos default:
3149 1.1 christos goto cleanup;
3150 1.1 christos }
3151 1.1 christos }
3152 1.1 christos return ret;
3153 1.1 christos
3154 1.1 christos cleanup:
3155 1.1 christos in->result = NULL;
3156 1.1 christos in->len = 0;
3157 1.1 christos return LDAP_OTHER;
3158 1.1 christos }
3159 1.1 christos #endif /* LDAP_USE_GSSAPI */
3160 1.1 christos
3161 1.1 christos
3162 1.1 christos #endif
3163