ldap.c revision 1.2 1 1.2 christos /* $NetBSD: ldap.c,v 1.2 2018/04/07 22:37:30 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.1 christos * Copyright (c) 2010-2017 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.2 2018/04/07 22:37:30 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.1 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.1 christos int ret;
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.1 christos db.data != NULL && *db.data != '\0')
1157 1.1 christos {
1158 1.1 christos ret = strtol ((const char *) db.data, NULL, 10);
1159 1.1 christos data_string_forget (&db, MDL);
1160 1.1 christos }
1161 1.1 christos else
1162 1.1 christos ret = 0;
1163 1.1 christos
1164 1.1 christos return (ret);
1165 1.1 christos }
1166 1.1 christos
1167 1.1 christos
1168 1.1 christos static int
1169 1.1 christos _do_lookup_dhcp_enum_option (struct option_state *options, int option_name)
1170 1.1 christos {
1171 1.1 christos struct option_cache *oc;
1172 1.1 christos struct data_string db;
1173 1.1 christos int ret = -1;
1174 1.1 christos
1175 1.1 christos memset (&db, 0, sizeof (db));
1176 1.1 christos oc = lookup_option (&server_universe, options, option_name);
1177 1.1 christos if (oc &&
1178 1.1 christos evaluate_option_cache (&db, (struct packet*) NULL,
1179 1.1 christos (struct lease *) NULL,
1180 1.1 christos (struct client_state *) NULL, options,
1181 1.1 christos (struct option_state *) NULL,
1182 1.1 christos &global_scope, oc, MDL) &&
1183 1.1 christos db.data != NULL && *db.data != '\0')
1184 1.1 christos {
1185 1.1 christos if (db.len == 1)
1186 1.1 christos ret = db.data [0];
1187 1.1 christos else
1188 1.1 christos log_fatal ("invalid option name %d", option_name);
1189 1.1 christos
1190 1.1 christos data_string_forget (&db, MDL);
1191 1.1 christos }
1192 1.1 christos else
1193 1.1 christos ret = 0;
1194 1.1 christos
1195 1.1 christos return (ret);
1196 1.1 christos }
1197 1.1 christos
1198 1.1 christos int
1199 1.1 christos ldap_rebind_cb (LDAP *ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *parms)
1200 1.1 christos {
1201 1.1 christos int ret;
1202 1.1 christos LDAPURLDesc *ldapurl = NULL;
1203 1.1 christos char *who = NULL;
1204 1.1 christos struct berval creds;
1205 1.1 christos
1206 1.1 christos log_info("LDAP rebind to '%s'", url);
1207 1.1 christos if ((ret = ldap_url_parse(url, &ldapurl)) != LDAP_SUCCESS)
1208 1.1 christos {
1209 1.1 christos log_error ("Error: Can not parse ldap rebind url '%s': %s",
1210 1.1 christos url, ldap_err2string(ret));
1211 1.1 christos return ret;
1212 1.1 christos }
1213 1.1 christos
1214 1.1 christos
1215 1.1 christos #if defined (LDAP_USE_SSL)
1216 1.1 christos if (strcasecmp(ldapurl->lud_scheme, "ldaps") == 0)
1217 1.1 christos {
1218 1.1 christos int opt = LDAP_OPT_X_TLS_HARD;
1219 1.1 christos if ((ret = ldap_set_option (ld, LDAP_OPT_X_TLS, &opt)) != LDAP_SUCCESS)
1220 1.1 christos {
1221 1.1 christos log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
1222 1.1 christos ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret));
1223 1.1 christos ldap_free_urldesc(ldapurl);
1224 1.1 christos return ret;
1225 1.1 christos }
1226 1.1 christos else
1227 1.1 christos {
1228 1.1 christos log_info ("LDAPS session successfully enabled to %s", ldap_server);
1229 1.1 christos }
1230 1.1 christos }
1231 1.1 christos else
1232 1.1 christos if (strcasecmp(ldapurl->lud_scheme, "ldap") == 0 &&
1233 1.1 christos ldap_use_ssl != LDAP_SSL_OFF)
1234 1.1 christos {
1235 1.1 christos if ((ret = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS)
1236 1.1 christos {
1237 1.1 christos log_error ("Error: Cannot start TLS session to %s:%d: %s",
1238 1.1 christos ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret));
1239 1.1 christos ldap_free_urldesc(ldapurl);
1240 1.1 christos return ret;
1241 1.1 christos }
1242 1.1 christos else
1243 1.1 christos {
1244 1.1 christos log_info ("TLS session successfully started to %s:%d",
1245 1.1 christos ldapurl->lud_host, ldapurl->lud_port);
1246 1.1 christos }
1247 1.1 christos }
1248 1.1 christos #endif
1249 1.1 christos
1250 1.1 christos #if defined(LDAP_USE_GSSAPI)
1251 1.1 christos if (ldap_gssapi_principal != NULL) {
1252 1.1 christos krb5_get_tgt(ldap_gssapi_principal, ldap_gssapi_keytab);
1253 1.1 christos if ((ret = ldap_sasl_interactive_bind_s(ld, NULL, ldap_sasl_inst->sasl_mech,
1254 1.1 christos NULL, NULL, LDAP_SASL_AUTOMATIC,
1255 1.1 christos _ldap_sasl_interact, ldap_sasl_inst)
1256 1.1 christos ) != LDAP_SUCCESS)
1257 1.1 christos {
1258 1.1 christos log_error ("Error: Cannot SASL bind to ldap server %s:%d: %s",
1259 1.1 christos ldap_server, ldap_port, ldap_err2string (ret));
1260 1.1 christos char *msg=NULL;
1261 1.1 christos ldap_get_option( ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*)&msg);
1262 1.1 christos log_error ("\tAdditional info: %s", msg);
1263 1.1 christos ldap_memfree(msg);
1264 1.1 christos ldap_stop();
1265 1.1 christos }
1266 1.1 christos
1267 1.1 christos ldap_free_urldesc(ldapurl);
1268 1.1 christos return ret;
1269 1.1 christos }
1270 1.1 christos #endif
1271 1.1 christos
1272 1.1 christos if (ldap_username != NULL && *ldap_username != '\0' && ldap_password != NULL)
1273 1.1 christos {
1274 1.1 christos who = ldap_username;
1275 1.1 christos creds.bv_val = strdup(ldap_password);
1276 1.1 christos if (creds.bv_val == NULL)
1277 1.1 christos log_fatal ("Error: Unable to allocate memory to duplicate ldap_password");
1278 1.1 christos
1279 1.1 christos creds.bv_len = strlen(ldap_password);
1280 1.1 christos
1281 1.1 christos if ((ret = ldap_sasl_bind_s (ld, who, LDAP_SASL_SIMPLE, &creds,
1282 1.1 christos NULL, NULL, NULL)) != LDAP_SUCCESS)
1283 1.1 christos {
1284 1.1 christos log_error ("Error: Cannot login into ldap server %s:%d: %s",
1285 1.1 christos ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret));
1286 1.1 christos }
1287 1.1 christos
1288 1.1 christos if (creds.bv_val)
1289 1.1 christos free(creds.bv_val);
1290 1.1 christos }
1291 1.1 christos
1292 1.1 christos ldap_free_urldesc(ldapurl);
1293 1.1 christos return ret;
1294 1.1 christos }
1295 1.1 christos
1296 1.1 christos static int
1297 1.1 christos _do_ldap_retry(int ret, const char *server, int port)
1298 1.1 christos {
1299 1.1 christos static int inform = 1;
1300 1.1 christos
1301 1.1 christos if (ldap_enable_retry > 0 && ret == LDAP_SERVER_DOWN && ldap_init_retry > 0)
1302 1.1 christos {
1303 1.1 christos if (inform || (ldap_init_retry % 10) == 0)
1304 1.1 christos {
1305 1.1 christos inform = 0;
1306 1.1 christos log_info ("Can't contact LDAP server %s:%d: retrying for %d sec",
1307 1.1 christos server, port, ldap_init_retry);
1308 1.1 christos }
1309 1.1 christos sleep(1);
1310 1.1 christos return ldap_init_retry--;
1311 1.1 christos }
1312 1.1 christos return 0;
1313 1.1 christos }
1314 1.1 christos
1315 1.1 christos static struct berval *
1316 1.1 christos _do_ldap_str2esc_filter_bv(const char *str, ber_len_t len, struct berval *bv_o)
1317 1.1 christos {
1318 1.1 christos struct berval bv_i;
1319 1.1 christos
1320 1.1 christos if (!str || !bv_o || (ber_str2bv(str, len, 0, &bv_i) == NULL) ||
1321 1.1 christos (ldap_bv2escaped_filter_value(&bv_i, bv_o) != 0))
1322 1.1 christos return NULL;
1323 1.1 christos return bv_o;
1324 1.1 christos }
1325 1.1 christos
1326 1.1 christos static void
1327 1.1 christos ldap_start (void)
1328 1.1 christos {
1329 1.1 christos struct option_state *options;
1330 1.1 christos int ret, version;
1331 1.1 christos char *uri = NULL;
1332 1.1 christos struct berval creds;
1333 1.1 christos #if defined(LDAP_USE_GSSAPI)
1334 1.1 christos char *gssapi_realm = NULL;
1335 1.1 christos char *gssapi_user = NULL;
1336 1.1 christos char *running = NULL;
1337 1.1 christos const char *gssapi_delim = "@";
1338 1.1 christos #endif
1339 1.1 christos
1340 1.1 christos if (ld != NULL)
1341 1.1 christos return;
1342 1.1 christos
1343 1.1 christos if (ldap_server == NULL)
1344 1.1 christos {
1345 1.1 christos options = NULL;
1346 1.1 christos option_state_allocate (&options, MDL);
1347 1.1 christos
1348 1.1 christos execute_statements_in_scope (NULL, NULL, NULL, NULL, NULL,
1349 1.1 christos options, &global_scope, root_group,
1350 1.1 christos NULL, NULL);
1351 1.1 christos
1352 1.1 christos ldap_server = _do_lookup_dhcp_string_option (options, SV_LDAP_SERVER);
1353 1.1 christos ldap_dhcp_server_cn = _do_lookup_dhcp_string_option (options,
1354 1.1 christos SV_LDAP_DHCP_SERVER_CN);
1355 1.1 christos ldap_port = _do_lookup_dhcp_int_option (options, SV_LDAP_PORT);
1356 1.1 christos ldap_base_dn = _do_lookup_dhcp_string_option (options, SV_LDAP_BASE_DN);
1357 1.1 christos ldap_method = _do_lookup_dhcp_enum_option (options, SV_LDAP_METHOD);
1358 1.1 christos ldap_debug_file = _do_lookup_dhcp_string_option (options,
1359 1.1 christos SV_LDAP_DEBUG_FILE);
1360 1.1 christos ldap_referrals = _do_lookup_dhcp_enum_option (options, SV_LDAP_REFERRALS);
1361 1.1 christos ldap_init_retry = _do_lookup_dhcp_int_option (options, SV_LDAP_INIT_RETRY);
1362 1.1 christos
1363 1.1 christos #if defined (LDAP_USE_SSL)
1364 1.1 christos ldap_use_ssl = _do_lookup_dhcp_enum_option (options, SV_LDAP_SSL);
1365 1.1 christos if( ldap_use_ssl != LDAP_SSL_OFF)
1366 1.1 christos {
1367 1.1 christos ldap_tls_reqcert = _do_lookup_dhcp_enum_option (options, SV_LDAP_TLS_REQCERT);
1368 1.1 christos ldap_tls_ca_file = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CA_FILE);
1369 1.1 christos ldap_tls_ca_dir = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CA_DIR);
1370 1.1 christos ldap_tls_cert = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CERT);
1371 1.1 christos ldap_tls_key = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_KEY);
1372 1.1 christos ldap_tls_crlcheck = _do_lookup_dhcp_enum_option (options, SV_LDAP_TLS_CRLCHECK);
1373 1.1 christos ldap_tls_ciphers = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CIPHERS);
1374 1.1 christos ldap_tls_randfile = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_RANDFILE);
1375 1.1 christos }
1376 1.1 christos #endif
1377 1.1 christos
1378 1.1 christos #if defined (LDAP_USE_GSSAPI)
1379 1.1 christos ldap_gssapi_principal = _do_lookup_dhcp_string_option (options,
1380 1.1 christos SV_LDAP_GSSAPI_PRINCIPAL);
1381 1.1 christos
1382 1.1 christos if (ldap_gssapi_principal == NULL) {
1383 1.1 christos log_error("ldap_gssapi_principal is not set,"
1384 1.1 christos "GSSAPI Authentication for LDAP will not be used");
1385 1.1 christos } else {
1386 1.1 christos ldap_gssapi_keytab = _do_lookup_dhcp_string_option (options,
1387 1.1 christos SV_LDAP_GSSAPI_KEYTAB);
1388 1.1 christos if (ldap_gssapi_keytab == NULL) {
1389 1.1 christos log_fatal("ldap_gssapi_keytab must be specified");
1390 1.1 christos }
1391 1.1 christos
1392 1.1 christos running = strdup(ldap_gssapi_principal);
1393 1.1 christos if (running == NULL)
1394 1.1 christos log_fatal("Could not allocate memory to duplicate gssapi principal");
1395 1.1 christos
1396 1.1 christos gssapi_user = strtok(running, gssapi_delim);
1397 1.1 christos if (!gssapi_user || strlen(gssapi_user) == 0) {
1398 1.1 christos log_fatal ("GSSAPI principal must specify user: user@realm");
1399 1.1 christos }
1400 1.1 christos
1401 1.1 christos gssapi_realm = strtok(NULL, gssapi_delim);
1402 1.1 christos if (!gssapi_realm || strlen(gssapi_realm) == 0) {
1403 1.1 christos log_fatal ("GSSAPI principal must specify realm: user@realm");
1404 1.1 christos }
1405 1.1 christos
1406 1.1 christos ldap_sasl_inst = malloc(sizeof(struct ldap_sasl_instance));
1407 1.1 christos if (ldap_sasl_inst == NULL)
1408 1.1 christos log_fatal("Could not allocate memory for sasl instance! Can not run!");
1409 1.1 christos
1410 1.1 christos ldap_sasl_inst->sasl_mech = ber_strdup("GSSAPI");
1411 1.1 christos if (ldap_sasl_inst->sasl_mech == NULL)
1412 1.1 christos log_fatal("Could not allocate memory to duplicate gssapi mechanism");
1413 1.1 christos
1414 1.1 christos ldap_sasl_inst->sasl_realm = ber_strdup(gssapi_realm);
1415 1.1 christos if (ldap_sasl_inst->sasl_realm == NULL)
1416 1.1 christos log_fatal("Could not allocate memory to duplicate gssapi realm");
1417 1.1 christos
1418 1.1 christos ldap_sasl_inst->sasl_authz_id = ber_strdup(gssapi_user);
1419 1.1 christos if (ldap_sasl_inst->sasl_authz_id == NULL)
1420 1.1 christos log_fatal("Could not allocate memory to duplicate gssapi user");
1421 1.1 christos
1422 1.1 christos ldap_sasl_inst->sasl_authc_id = NULL;
1423 1.1 christos ldap_sasl_inst->sasl_password = NULL; //"" before
1424 1.1 christos free(running);
1425 1.1 christos }
1426 1.1 christos #endif
1427 1.1 christos
1428 1.1 christos #if defined (LDAP_CASA_AUTH)
1429 1.1 christos if (!load_uname_pwd_from_miCASA(&ldap_username,&ldap_password))
1430 1.1 christos {
1431 1.1 christos #if defined (DEBUG_LDAP)
1432 1.1 christos log_info ("Authentication credential taken from file");
1433 1.1 christos #endif
1434 1.1 christos #endif
1435 1.1 christos
1436 1.1 christos ldap_username = _do_lookup_dhcp_string_option (options, SV_LDAP_USERNAME);
1437 1.1 christos ldap_password = _do_lookup_dhcp_string_option (options, SV_LDAP_PASSWORD);
1438 1.1 christos
1439 1.1 christos #if defined (LDAP_CASA_AUTH)
1440 1.1 christos }
1441 1.1 christos #endif
1442 1.1 christos
1443 1.1 christos option_state_dereference (&options, MDL);
1444 1.1 christos }
1445 1.1 christos
1446 1.1 christos if (ldap_server == NULL || ldap_base_dn == NULL)
1447 1.1 christos {
1448 1.1 christos log_info ("Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not specified in the config file");
1449 1.1 christos ldap_method = LDAP_METHOD_STATIC;
1450 1.1 christos return;
1451 1.1 christos }
1452 1.1 christos
1453 1.1 christos if (ldap_debug_file != NULL && ldap_debug_fd == -1)
1454 1.1 christos {
1455 1.1 christos if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY,
1456 1.1 christos S_IRUSR | S_IWUSR)) < 0)
1457 1.1 christos log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file,
1458 1.1 christos strerror (errno));
1459 1.1 christos }
1460 1.1 christos
1461 1.1 christos #if defined (DEBUG_LDAP)
1462 1.1 christos log_info ("Connecting to LDAP server %s:%d", ldap_server, ldap_port);
1463 1.1 christos #endif
1464 1.1 christos
1465 1.1 christos #if defined (LDAP_USE_SSL)
1466 1.1 christos if (ldap_use_ssl == -1)
1467 1.1 christos {
1468 1.1 christos /*
1469 1.1 christos ** There was no "ldap-ssl" option in dhcpd.conf (also not "off").
1470 1.1 christos ** Let's try, if we can use an anonymous TLS session without to
1471 1.1 christos ** verify the server certificate -- if not continue without TLS.
1472 1.1 christos */
1473 1.1 christos int opt = LDAP_OPT_X_TLS_ALLOW;
1474 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
1475 1.1 christos &opt)) != LDAP_SUCCESS)
1476 1.1 christos {
1477 1.1 christos log_error ("Warning: Cannot set LDAP TLS require cert option to 'allow': %s",
1478 1.1 christos ldap_err2string (ret));
1479 1.1 christos }
1480 1.1 christos }
1481 1.1 christos
1482 1.1 christos if (ldap_use_ssl != LDAP_SSL_OFF)
1483 1.1 christos {
1484 1.1 christos if (ldap_tls_reqcert != -1)
1485 1.1 christos {
1486 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
1487 1.1 christos &ldap_tls_reqcert)) != LDAP_SUCCESS)
1488 1.1 christos {
1489 1.1 christos log_error ("Cannot set LDAP TLS require cert option: %s",
1490 1.1 christos ldap_err2string (ret));
1491 1.1 christos }
1492 1.1 christos }
1493 1.1 christos
1494 1.1 christos if( ldap_tls_ca_file != NULL)
1495 1.1 christos {
1496 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE,
1497 1.1 christos ldap_tls_ca_file)) != LDAP_SUCCESS)
1498 1.1 christos {
1499 1.1 christos log_error ("Cannot set LDAP TLS CA certificate file %s: %s",
1500 1.1 christos ldap_tls_ca_file, ldap_err2string (ret));
1501 1.1 christos }
1502 1.1 christos }
1503 1.1 christos if( ldap_tls_ca_dir != NULL)
1504 1.1 christos {
1505 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR,
1506 1.1 christos ldap_tls_ca_dir)) != LDAP_SUCCESS)
1507 1.1 christos {
1508 1.1 christos log_error ("Cannot set LDAP TLS CA certificate dir %s: %s",
1509 1.1 christos ldap_tls_ca_dir, ldap_err2string (ret));
1510 1.1 christos }
1511 1.1 christos }
1512 1.1 christos if( ldap_tls_cert != NULL)
1513 1.1 christos {
1514 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE,
1515 1.1 christos ldap_tls_cert)) != LDAP_SUCCESS)
1516 1.1 christos {
1517 1.1 christos log_error ("Cannot set LDAP TLS client certificate file %s: %s",
1518 1.1 christos ldap_tls_cert, ldap_err2string (ret));
1519 1.1 christos }
1520 1.1 christos }
1521 1.1 christos if( ldap_tls_key != NULL)
1522 1.1 christos {
1523 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE,
1524 1.1 christos ldap_tls_key)) != LDAP_SUCCESS)
1525 1.1 christos {
1526 1.1 christos log_error ("Cannot set LDAP TLS certificate key file %s: %s",
1527 1.1 christos ldap_tls_key, ldap_err2string (ret));
1528 1.1 christos }
1529 1.1 christos }
1530 1.1 christos if( ldap_tls_crlcheck != -1)
1531 1.1 christos {
1532 1.1 christos int opt = ldap_tls_crlcheck;
1533 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CRLCHECK,
1534 1.1 christos &opt)) != LDAP_SUCCESS)
1535 1.1 christos {
1536 1.1 christos log_error ("Cannot set LDAP TLS crl check option: %s",
1537 1.1 christos ldap_err2string (ret));
1538 1.1 christos }
1539 1.1 christos }
1540 1.1 christos if( ldap_tls_ciphers != NULL)
1541 1.1 christos {
1542 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE,
1543 1.1 christos ldap_tls_ciphers)) != LDAP_SUCCESS)
1544 1.1 christos {
1545 1.1 christos log_error ("Cannot set LDAP TLS cipher suite %s: %s",
1546 1.1 christos ldap_tls_ciphers, ldap_err2string (ret));
1547 1.1 christos }
1548 1.1 christos }
1549 1.1 christos if( ldap_tls_randfile != NULL)
1550 1.1 christos {
1551 1.1 christos if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE,
1552 1.1 christos ldap_tls_randfile)) != LDAP_SUCCESS)
1553 1.1 christos {
1554 1.1 christos log_error ("Cannot set LDAP TLS random file %s: %s",
1555 1.1 christos ldap_tls_randfile, ldap_err2string (ret));
1556 1.1 christos }
1557 1.1 christos }
1558 1.1 christos }
1559 1.1 christos #endif
1560 1.1 christos
1561 1.1 christos /* enough for 'ldap://+ + hostname + ':' + port number */
1562 1.1 christos uri = malloc(strlen(ldap_server) + 16);
1563 1.1 christos if (uri == NULL)
1564 1.1 christos {
1565 1.1 christos log_error ("Cannot build ldap init URI %s:%d", ldap_server, ldap_port);
1566 1.1 christos return;
1567 1.1 christos }
1568 1.1 christos
1569 1.1 christos sprintf(uri, "ldap://%s:%d", ldap_server, ldap_port);
1570 1.1 christos ldap_initialize(&ld, uri);
1571 1.1 christos
1572 1.1 christos if (ld == NULL)
1573 1.1 christos {
1574 1.1 christos log_error ("Cannot init ldap session to %s:%d", ldap_server, ldap_port);
1575 1.1 christos return;
1576 1.1 christos }
1577 1.1 christos
1578 1.1 christos free(uri);
1579 1.1 christos
1580 1.1 christos version = LDAP_VERSION3;
1581 1.1 christos if ((ret = ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version)) != LDAP_OPT_SUCCESS)
1582 1.1 christos {
1583 1.1 christos log_error ("Cannot set LDAP version to %d: %s", version,
1584 1.1 christos ldap_err2string (ret));
1585 1.1 christos }
1586 1.1 christos
1587 1.1 christos if (ldap_referrals != -1)
1588 1.1 christos {
1589 1.1 christos if ((ret = ldap_set_option (ld, LDAP_OPT_REFERRALS, ldap_referrals ?
1590 1.1 christos LDAP_OPT_ON : LDAP_OPT_OFF)) != LDAP_OPT_SUCCESS)
1591 1.1 christos {
1592 1.1 christos log_error ("Cannot %s LDAP referrals option: %s",
1593 1.1 christos (ldap_referrals ? "enable" : "disable"),
1594 1.1 christos ldap_err2string (ret));
1595 1.1 christos }
1596 1.1 christos }
1597 1.1 christos
1598 1.1 christos if ((ret = ldap_set_rebind_proc(ld, ldap_rebind_cb, NULL)) != LDAP_SUCCESS)
1599 1.1 christos {
1600 1.1 christos log_error ("Warning: Cannot set ldap rebind procedure: %s",
1601 1.1 christos ldap_err2string (ret));
1602 1.1 christos }
1603 1.1 christos
1604 1.1 christos #if defined (LDAP_USE_SSL)
1605 1.1 christos if (ldap_use_ssl == LDAP_SSL_LDAPS ||
1606 1.1 christos (ldap_use_ssl == LDAP_SSL_ON && ldap_port == LDAPS_PORT))
1607 1.1 christos {
1608 1.1 christos int opt = LDAP_OPT_X_TLS_HARD;
1609 1.1 christos if ((ret = ldap_set_option (ld, LDAP_OPT_X_TLS, &opt)) != LDAP_SUCCESS)
1610 1.1 christos {
1611 1.1 christos log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
1612 1.1 christos ldap_server, ldap_port, ldap_err2string (ret));
1613 1.1 christos ldap_stop();
1614 1.1 christos return;
1615 1.1 christos }
1616 1.1 christos else
1617 1.1 christos {
1618 1.1 christos log_info ("LDAPS session successfully enabled to %s:%d",
1619 1.1 christos ldap_server, ldap_port);
1620 1.1 christos }
1621 1.1 christos }
1622 1.1 christos else if (ldap_use_ssl != LDAP_SSL_OFF)
1623 1.1 christos {
1624 1.1 christos do
1625 1.1 christos {
1626 1.1 christos ret = ldap_start_tls_s (ld, NULL, NULL);
1627 1.1 christos }
1628 1.1 christos while(_do_ldap_retry(ret, ldap_server, ldap_port) > 0);
1629 1.1 christos
1630 1.1 christos if (ret != LDAP_SUCCESS)
1631 1.1 christos {
1632 1.1 christos log_error ("Error: Cannot start TLS session to %s:%d: %s",
1633 1.1 christos ldap_server, ldap_port, ldap_err2string (ret));
1634 1.1 christos ldap_stop();
1635 1.1 christos return;
1636 1.1 christos }
1637 1.1 christos else
1638 1.1 christos {
1639 1.1 christos log_info ("TLS session successfully started to %s:%d",
1640 1.1 christos ldap_server, ldap_port);
1641 1.1 christos }
1642 1.1 christos }
1643 1.1 christos #endif
1644 1.1 christos
1645 1.1 christos #if defined(LDAP_USE_GSSAPI)
1646 1.1 christos if (ldap_gssapi_principal != NULL) {
1647 1.1 christos krb5_get_tgt(ldap_gssapi_principal, ldap_gssapi_keytab);
1648 1.1 christos if ((ret = ldap_sasl_interactive_bind_s(ld, NULL, ldap_sasl_inst->sasl_mech,
1649 1.1 christos NULL, NULL, LDAP_SASL_AUTOMATIC,
1650 1.1 christos _ldap_sasl_interact, ldap_sasl_inst)
1651 1.1 christos ) != LDAP_SUCCESS)
1652 1.1 christos {
1653 1.1 christos log_error ("Error: Cannot SASL bind to ldap server %s:%d: %s",
1654 1.1 christos ldap_server, ldap_port, ldap_err2string (ret));
1655 1.1 christos char *msg=NULL;
1656 1.1 christos ldap_get_option( ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*)&msg);
1657 1.1 christos log_error ("\tAdditional info: %s", msg);
1658 1.1 christos ldap_memfree(msg);
1659 1.1 christos ldap_stop();
1660 1.1 christos return;
1661 1.1 christos }
1662 1.1 christos } else
1663 1.1 christos #endif
1664 1.1 christos
1665 1.1 christos if (ldap_username != NULL && *ldap_username != '\0' && ldap_password != NULL)
1666 1.1 christos {
1667 1.1 christos creds.bv_val = strdup(ldap_password);
1668 1.1 christos if (creds.bv_val == NULL)
1669 1.1 christos log_fatal ("Error: Unable to allocate memory to duplicate ldap_password");
1670 1.1 christos
1671 1.1 christos creds.bv_len = strlen(ldap_password);
1672 1.1 christos
1673 1.1 christos do
1674 1.1 christos {
1675 1.1 christos ret = ldap_sasl_bind_s (ld, ldap_username, LDAP_SASL_SIMPLE,
1676 1.1 christos &creds, NULL, NULL, NULL);
1677 1.1 christos }
1678 1.1 christos while(_do_ldap_retry(ret, ldap_server, ldap_port) > 0);
1679 1.1 christos free(creds.bv_val);
1680 1.1 christos
1681 1.1 christos if (ret != LDAP_SUCCESS)
1682 1.1 christos {
1683 1.1 christos log_error ("Error: Cannot login into ldap server %s:%d: %s",
1684 1.1 christos ldap_server, ldap_port, ldap_err2string (ret));
1685 1.1 christos ldap_stop();
1686 1.1 christos return;
1687 1.1 christos }
1688 1.1 christos }
1689 1.1 christos
1690 1.1 christos #if defined (DEBUG_LDAP)
1691 1.1 christos log_info ("Successfully logged into LDAP server %s", ldap_server);
1692 1.1 christos #endif
1693 1.1 christos }
1694 1.1 christos
1695 1.1 christos
1696 1.1 christos static void
1697 1.1 christos parse_external_dns (LDAPMessage * ent)
1698 1.1 christos {
1699 1.1 christos char *search[] = {"dhcpOptionsDN", "dhcpSharedNetworkDN", "dhcpSubnetDN",
1700 1.1 christos "dhcpGroupDN", "dhcpHostDN", "dhcpClassesDN",
1701 1.1 christos "dhcpPoolDN", "dhcpZoneDN", "dhcpFailOverPeerDN", NULL};
1702 1.1 christos
1703 1.1 christos /* TODO: dhcpKeyDN can't be added. It is referenced in dhcpDnsZone to
1704 1.1 christos retrive the key name (cn). Adding keyDN will reflect adding a key
1705 1.1 christos declaration inside the zone configuration.
1706 1.1 christos
1707 1.1 christos dhcpSubClassesDN cant be added. It is also similar to the above.
1708 1.1 christos Needs schema change.
1709 1.1 christos */
1710 1.1 christos LDAPMessage * newres, * newent;
1711 1.1 christos struct berval **tempbv;
1712 1.1 christos int i, j, ret;
1713 1.1 christos #if defined (DEBUG_LDAP)
1714 1.1 christos char *dn;
1715 1.1 christos
1716 1.1 christos dn = ldap_get_dn (ld, ent);
1717 1.1 christos if (dn != NULL)
1718 1.1 christos {
1719 1.1 christos log_info ("Parsing external DNs for '%s'", dn);
1720 1.1 christos ldap_memfree (dn);
1721 1.1 christos }
1722 1.1 christos #endif
1723 1.1 christos
1724 1.1 christos if (ld == NULL)
1725 1.1 christos ldap_start ();
1726 1.1 christos if (ld == NULL)
1727 1.1 christos return;
1728 1.1 christos
1729 1.1 christos for (i=0; search[i] != NULL; i++)
1730 1.1 christos {
1731 1.1 christos if ((tempbv = ldap_get_values_len (ld, ent, search[i])) == NULL)
1732 1.1 christos continue;
1733 1.1 christos
1734 1.1 christos for (j=0; tempbv[j] != NULL; j++)
1735 1.1 christos {
1736 1.1 christos if (*tempbv[j]->bv_val == '\0')
1737 1.1 christos continue;
1738 1.1 christos
1739 1.1 christos if ((ret = ldap_search_ext_s(ld, tempbv[j]->bv_val, LDAP_SCOPE_BASE,
1740 1.1 christos "objectClass=*", NULL, 0, NULL,
1741 1.1 christos NULL, NULL, 0, &newres)) != LDAP_SUCCESS)
1742 1.1 christos {
1743 1.1 christos ldap_value_free_len (tempbv);
1744 1.1 christos ldap_stop();
1745 1.1 christos return;
1746 1.1 christos }
1747 1.1 christos
1748 1.1 christos #if defined (DEBUG_LDAP)
1749 1.1 christos log_info ("Adding contents of subtree '%s' to config stack from '%s' reference", tempbv[j]->bv_val, search[i]);
1750 1.1 christos #endif
1751 1.1 christos for (newent = ldap_first_entry (ld, newres);
1752 1.1 christos newent != NULL;
1753 1.1 christos newent = ldap_next_entry (ld, newent))
1754 1.1 christos {
1755 1.1 christos #if defined (DEBUG_LDAP)
1756 1.1 christos dn = ldap_get_dn (ld, newent);
1757 1.1 christos if (dn != NULL)
1758 1.1 christos {
1759 1.1 christos log_info ("Adding LDAP result set starting with '%s' to config stack", dn);
1760 1.1 christos ldap_memfree (dn);
1761 1.1 christos }
1762 1.1 christos #endif
1763 1.1 christos
1764 1.1 christos add_to_config_stack (newres, newent);
1765 1.1 christos /* don't free newres here */
1766 1.1 christos }
1767 1.1 christos }
1768 1.1 christos
1769 1.1 christos ldap_value_free_len (tempbv);
1770 1.1 christos }
1771 1.1 christos }
1772 1.1 christos
1773 1.1 christos
1774 1.1 christos static void
1775 1.1 christos free_stack_entry (struct ldap_config_stack *item)
1776 1.1 christos {
1777 1.1 christos struct ldap_config_stack *look_ahead_pointer = item;
1778 1.1 christos int may_free_msg = 1;
1779 1.1 christos
1780 1.1 christos while (look_ahead_pointer->next != NULL)
1781 1.1 christos {
1782 1.1 christos look_ahead_pointer = look_ahead_pointer->next;
1783 1.1 christos if (look_ahead_pointer->res == item->res)
1784 1.1 christos {
1785 1.1 christos may_free_msg = 0;
1786 1.1 christos break;
1787 1.1 christos }
1788 1.1 christos }
1789 1.1 christos
1790 1.1 christos if (may_free_msg)
1791 1.1 christos ldap_msgfree (item->res);
1792 1.1 christos
1793 1.1 christos dfree (item, MDL);
1794 1.1 christos }
1795 1.1 christos
1796 1.1 christos
1797 1.1 christos static void
1798 1.1 christos next_ldap_entry (struct parse *cfile)
1799 1.1 christos {
1800 1.1 christos struct ldap_config_stack *temp_stack;
1801 1.1 christos
1802 1.1 christos if (ldap_stack != NULL && ldap_stack->close_brace)
1803 1.1 christos {
1804 1.1 christos x_parser_strcat (cfile, "}\n");
1805 1.1 christos ldap_stack->close_brace = 0;
1806 1.1 christos }
1807 1.1 christos
1808 1.1 christos while (ldap_stack != NULL &&
1809 1.1 christos (ldap_stack->ldent == NULL || ( ldap_stack->processed &&
1810 1.1 christos (ldap_stack->ldent = ldap_next_entry (ld, ldap_stack->ldent)) == NULL)))
1811 1.1 christos {
1812 1.1 christos if (ldap_stack->close_brace)
1813 1.1 christos {
1814 1.1 christos x_parser_strcat (cfile, "}\n");
1815 1.1 christos ldap_stack->close_brace = 0;
1816 1.1 christos }
1817 1.1 christos
1818 1.1 christos temp_stack = ldap_stack;
1819 1.1 christos ldap_stack = ldap_stack->next;
1820 1.1 christos free_stack_entry (temp_stack);
1821 1.1 christos }
1822 1.1 christos
1823 1.1 christos if (ldap_stack != NULL && ldap_stack->close_brace)
1824 1.1 christos {
1825 1.1 christos x_parser_strcat (cfile, "}\n");
1826 1.1 christos ldap_stack->close_brace = 0;
1827 1.1 christos }
1828 1.1 christos }
1829 1.1 christos
1830 1.1 christos
1831 1.1 christos static char
1832 1.1 christos check_statement_end (const char *statement)
1833 1.1 christos {
1834 1.1 christos char *ptr;
1835 1.1 christos
1836 1.1 christos if (statement == NULL || *statement == '\0')
1837 1.1 christos return ('\0');
1838 1.1 christos
1839 1.1 christos /*
1840 1.1 christos ** check if it ends with "}", e.g.:
1841 1.1 christos ** "zone my.domain. { ... }"
1842 1.1 christos ** optionally followed by spaces
1843 1.1 christos */
1844 1.1 christos ptr = strrchr (statement, '}');
1845 1.1 christos if (ptr != NULL)
1846 1.1 christos {
1847 1.1 christos /* skip following white-spaces */
1848 1.1 christos for (++ptr; isspace ((int)*ptr); ptr++);
1849 1.1 christos
1850 1.1 christos /* check if we reached the end */
1851 1.1 christos if (*ptr == '\0')
1852 1.1 christos return ('}'); /* yes, block end */
1853 1.1 christos else
1854 1.1 christos return (*ptr);
1855 1.1 christos }
1856 1.1 christos
1857 1.1 christos /*
1858 1.1 christos ** this should not happen, but...
1859 1.1 christos ** check if it ends with ";", e.g.:
1860 1.1 christos ** "authoritative;"
1861 1.1 christos ** optionally followed by spaces
1862 1.1 christos */
1863 1.1 christos ptr = strrchr (statement, ';');
1864 1.1 christos if (ptr != NULL)
1865 1.1 christos {
1866 1.1 christos /* skip following white-spaces */
1867 1.1 christos for (++ptr; isspace ((int)*ptr); ptr++);
1868 1.1 christos
1869 1.1 christos /* check if we reached the end */
1870 1.1 christos if (*ptr == '\0')
1871 1.1 christos return (';'); /* ends with a ; */
1872 1.1 christos else
1873 1.1 christos return (*ptr);
1874 1.1 christos }
1875 1.1 christos
1876 1.1 christos return ('\0');
1877 1.1 christos }
1878 1.1 christos
1879 1.1 christos
1880 1.1 christos static isc_result_t
1881 1.1 christos ldap_parse_entry_options (LDAPMessage *ent, struct parse *cfile,
1882 1.1 christos int *lease_limit)
1883 1.1 christos {
1884 1.1 christos struct berval **tempbv;
1885 1.1 christos int i;
1886 1.1 christos
1887 1.1 christos if (ent == NULL || cfile == NULL)
1888 1.1 christos return (ISC_R_FAILURE);
1889 1.1 christos
1890 1.1 christos if ((tempbv = ldap_get_values_len (ld, ent, "dhcpStatements")) != NULL)
1891 1.1 christos {
1892 1.1 christos for (i=0; tempbv[i] != NULL; i++)
1893 1.1 christos {
1894 1.1 christos if (lease_limit != NULL &&
1895 1.1 christos strncasecmp ("lease limit ", tempbv[i]->bv_val, 12) == 0)
1896 1.1 christos {
1897 1.1 christos *lease_limit = (int) strtol ((tempbv[i]->bv_val) + 12, NULL, 10);
1898 1.1 christos continue;
1899 1.1 christos }
1900 1.1 christos
1901 1.1 christos x_parser_strcat (cfile, tempbv[i]->bv_val);
1902 1.1 christos
1903 1.1 christos switch((int) check_statement_end (tempbv[i]->bv_val))
1904 1.1 christos {
1905 1.1 christos case '}':
1906 1.1 christos case ';':
1907 1.1 christos x_parser_strcat (cfile, "\n");
1908 1.1 christos break;
1909 1.1 christos default:
1910 1.1 christos x_parser_strcat (cfile, ";\n");
1911 1.1 christos break;
1912 1.1 christos }
1913 1.1 christos }
1914 1.1 christos ldap_value_free_len (tempbv);
1915 1.1 christos }
1916 1.1 christos
1917 1.1 christos if ((tempbv = ldap_get_values_len (ld, ent, "dhcpOption")) != NULL)
1918 1.1 christos {
1919 1.1 christos for (i=0; tempbv[i] != NULL; i++)
1920 1.1 christos {
1921 1.1 christos x_parser_strcat (cfile, "option ");
1922 1.1 christos x_parser_strcat (cfile, tempbv[i]->bv_val);
1923 1.1 christos switch ((int) check_statement_end (tempbv[i]->bv_val))
1924 1.1 christos {
1925 1.1 christos case ';':
1926 1.1 christos x_parser_strcat (cfile, "\n");
1927 1.1 christos break;
1928 1.1 christos default:
1929 1.1 christos x_parser_strcat (cfile, ";\n");
1930 1.1 christos break;
1931 1.1 christos }
1932 1.1 christos }
1933 1.1 christos ldap_value_free_len (tempbv);
1934 1.1 christos }
1935 1.1 christos
1936 1.1 christos return (ISC_R_SUCCESS);
1937 1.1 christos }
1938 1.1 christos
1939 1.1 christos
1940 1.1 christos static void
1941 1.1 christos ldap_generate_config_string (struct parse *cfile)
1942 1.1 christos {
1943 1.1 christos struct berval **objectClass;
1944 1.1 christos char *dn;
1945 1.1 christos struct ldap_config_stack *entry;
1946 1.1 christos LDAPMessage * ent, * res, *entfirst, *resfirst;
1947 1.1 christos int i, ignore, found;
1948 1.1 christos int ret, parsedn = 1;
1949 1.1 christos size_t len = cfile->buflen;
1950 1.1 christos
1951 1.1 christos if (ld == NULL)
1952 1.1 christos ldap_start ();
1953 1.1 christos if (ld == NULL)
1954 1.1 christos return;
1955 1.1 christos
1956 1.1 christos entry = ldap_stack;
1957 1.1 christos if ((objectClass = ldap_get_values_len (ld, entry->ldent,
1958 1.1 christos "objectClass")) == NULL)
1959 1.1 christos return;
1960 1.1 christos
1961 1.1 christos entry->processed = 1;
1962 1.1 christos ignore = 0;
1963 1.1 christos found = 1;
1964 1.1 christos for (i=0; objectClass[i] != NULL; i++)
1965 1.1 christos {
1966 1.1 christos if (strcasecmp (objectClass[i]->bv_val, "dhcpSharedNetwork") == 0)
1967 1.1 christos ldap_parse_shared_network (entry, cfile);
1968 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpClass") == 0)
1969 1.1 christos ldap_parse_class (entry, cfile);
1970 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpSubnet") == 0)
1971 1.1 christos ldap_parse_subnet (entry, cfile);
1972 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpSubnet6") == 0)
1973 1.1 christos ldap_parse_subnet6 (entry, cfile);
1974 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpPool") == 0)
1975 1.1 christos ldap_parse_pool (entry, cfile);
1976 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpPool6") == 0)
1977 1.1 christos ldap_parse_pool6 (entry, cfile);
1978 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpGroup") == 0)
1979 1.1 christos ldap_parse_group (entry, cfile);
1980 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpTSigKey") == 0)
1981 1.1 christos ldap_parse_key (entry, cfile);
1982 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpDnsZone") == 0)
1983 1.1 christos ldap_parse_zone (entry, cfile);
1984 1.1 christos #if defined(HAVE_IFADDRS_H)
1985 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpFailOverPeer") == 0)
1986 1.1 christos ldap_parse_failover (entry, cfile);
1987 1.1 christos #endif
1988 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpHost") == 0)
1989 1.1 christos {
1990 1.1 christos if (ldap_method == LDAP_METHOD_STATIC)
1991 1.1 christos ldap_parse_host (entry, cfile);
1992 1.1 christos else
1993 1.1 christos {
1994 1.1 christos ignore = 1;
1995 1.1 christos break;
1996 1.1 christos }
1997 1.1 christos }
1998 1.1 christos else if (strcasecmp (objectClass[i]->bv_val, "dhcpSubClass") == 0)
1999 1.1 christos {
2000 1.1 christos if (ldap_method == LDAP_METHOD_STATIC)
2001 1.1 christos ldap_parse_subclass (entry, cfile);
2002 1.1 christos else
2003 1.1 christos {
2004 1.1 christos ignore = 1;
2005 1.1 christos break;
2006 1.1 christos }
2007 1.1 christos }
2008 1.1 christos else
2009 1.1 christos found = 0;
2010 1.1 christos
2011 1.1 christos if (found && x_parser_length(cfile) <= len)
2012 1.1 christos {
2013 1.1 christos ignore = 1;
2014 1.1 christos break;
2015 1.1 christos }
2016 1.1 christos }
2017 1.1 christos
2018 1.1 christos ldap_value_free_len (objectClass);
2019 1.1 christos
2020 1.1 christos if (ignore)
2021 1.1 christos {
2022 1.1 christos next_ldap_entry (cfile);
2023 1.1 christos return;
2024 1.1 christos }
2025 1.1 christos
2026 1.1 christos ldap_parse_entry_options(entry->ldent, cfile, NULL);
2027 1.1 christos
2028 1.1 christos dn = ldap_get_dn (ld, entry->ldent);
2029 1.1 christos if (dn == NULL)
2030 1.1 christos {
2031 1.1 christos ldap_stop();
2032 1.1 christos return;
2033 1.1 christos }
2034 1.1 christos #if defined(DEBUG_LDAP)
2035 1.1 christos log_info ("Found LDAP entry '%s'", dn);
2036 1.1 christos #endif
2037 1.1 christos
2038 1.1 christos if ((ret = ldap_search_ext_s (ld, dn, LDAP_SCOPE_ONELEVEL,
2039 1.1 christos "(!(|(|(objectClass=dhcpTSigKey)(objectClass=dhcpClass)) (objectClass=dhcpFailOverPeer)))",
2040 1.1 christos NULL, 0, NULL, NULL,
2041 1.1 christos NULL, 0, &res)) != LDAP_SUCCESS)
2042 1.1 christos {
2043 1.1 christos ldap_memfree (dn);
2044 1.1 christos
2045 1.1 christos ldap_stop();
2046 1.1 christos return;
2047 1.1 christos }
2048 1.1 christos
2049 1.1 christos if ((ret = ldap_search_ext_s (ld, dn, LDAP_SCOPE_ONELEVEL,
2050 1.1 christos "(|(|(objectClass=dhcpTSigKey)(objectClass=dhcpClass)) (objectClass=dhcpFailOverPeer))",
2051 1.1 christos NULL, 0, NULL, NULL,
2052 1.1 christos NULL, 0, &resfirst)) != LDAP_SUCCESS)
2053 1.1 christos {
2054 1.1 christos ldap_memfree (dn);
2055 1.1 christos ldap_msgfree (res);
2056 1.1 christos
2057 1.1 christos ldap_stop();
2058 1.1 christos return;
2059 1.1 christos }
2060 1.1 christos
2061 1.1 christos ldap_memfree (dn);
2062 1.1 christos
2063 1.1 christos ent = ldap_first_entry(ld, res);
2064 1.1 christos entfirst = ldap_first_entry(ld, resfirst);
2065 1.1 christos
2066 1.1 christos if (ent == NULL && entfirst == NULL)
2067 1.1 christos {
2068 1.1 christos parse_external_dns (entry->ldent);
2069 1.1 christos next_ldap_entry (cfile);
2070 1.1 christos }
2071 1.1 christos
2072 1.1 christos if (ent != NULL)
2073 1.1 christos {
2074 1.1 christos add_to_config_stack (res, ent);
2075 1.1 christos parse_external_dns (entry->ldent);
2076 1.1 christos parsedn = 0;
2077 1.1 christos }
2078 1.1 christos else
2079 1.1 christos ldap_msgfree (res);
2080 1.1 christos
2081 1.1 christos if (entfirst != NULL)
2082 1.1 christos {
2083 1.1 christos add_to_config_stack (resfirst, entfirst);
2084 1.1 christos if(parsedn)
2085 1.1 christos parse_external_dns (entry->ldent);
2086 1.1 christos
2087 1.1 christos }
2088 1.1 christos else
2089 1.1 christos ldap_msgfree (resfirst);
2090 1.1 christos }
2091 1.1 christos
2092 1.1 christos
2093 1.1 christos static void
2094 1.1 christos ldap_close_debug_fd()
2095 1.1 christos {
2096 1.1 christos if (ldap_debug_fd != -1)
2097 1.1 christos {
2098 1.1 christos close (ldap_debug_fd);
2099 1.1 christos ldap_debug_fd = -1;
2100 1.1 christos }
2101 1.1 christos }
2102 1.1 christos
2103 1.1 christos
2104 1.1 christos static void
2105 1.1 christos ldap_write_debug (const void *buff, size_t size)
2106 1.1 christos {
2107 1.1 christos if (ldap_debug_fd != -1)
2108 1.1 christos {
2109 1.1 christos if (write (ldap_debug_fd, buff, size) < 0)
2110 1.1 christos {
2111 1.1 christos log_error ("Error writing to LDAP debug file %s: %s."
2112 1.1 christos " Disabling log file.", ldap_debug_file,
2113 1.1 christos strerror (errno));
2114 1.1 christos ldap_close_debug_fd();
2115 1.1 christos }
2116 1.1 christos }
2117 1.1 christos }
2118 1.1 christos
2119 1.1 christos static int
2120 1.1 christos ldap_read_function (struct parse *cfile)
2121 1.1 christos {
2122 1.1 christos size_t len;
2123 1.1 christos
2124 1.1 christos /* append when in saved state */
2125 1.1 christos if (cfile->saved_state == NULL)
2126 1.1 christos {
2127 1.1 christos cfile->inbuf[0] = '\0';
2128 1.1 christos cfile->bufix = 0;
2129 1.1 christos cfile->buflen = 0;
2130 1.1 christos }
2131 1.1 christos len = cfile->buflen;
2132 1.1 christos
2133 1.1 christos while (ldap_stack != NULL && x_parser_length(cfile) <= len)
2134 1.1 christos ldap_generate_config_string (cfile);
2135 1.1 christos
2136 1.1 christos if (x_parser_length(cfile) <= len && ldap_stack == NULL)
2137 1.1 christos return (EOF);
2138 1.1 christos
2139 1.1 christos if (cfile->buflen > len)
2140 1.1 christos ldap_write_debug (cfile->inbuf + len, cfile->buflen - len);
2141 1.1 christos #if defined (DEBUG_LDAP)
2142 1.1 christos log_info ("Sending config portion '%s'", cfile->inbuf + len);
2143 1.1 christos #endif
2144 1.1 christos
2145 1.1 christos return (cfile->inbuf[cfile->bufix++]);
2146 1.1 christos }
2147 1.1 christos
2148 1.1 christos
2149 1.1 christos static char *
2150 1.1 christos ldap_get_host_name (LDAPMessage * ent)
2151 1.1 christos {
2152 1.1 christos struct berval **name;
2153 1.1 christos char *ret;
2154 1.1 christos
2155 1.1 christos ret = NULL;
2156 1.1 christos if ((name = ldap_get_values_len (ld, ent, "cn")) == NULL || name[0] == NULL)
2157 1.1 christos {
2158 1.1 christos if (name != NULL)
2159 1.1 christos ldap_value_free_len (name);
2160 1.1 christos
2161 1.1 christos #if defined (DEBUG_LDAP)
2162 1.1 christos ret = ldap_get_dn (ld, ent);
2163 1.1 christos if (ret != NULL)
2164 1.1 christos {
2165 1.1 christos log_info ("Cannot get cn attribute for LDAP entry %s", ret);
2166 1.1 christos ldap_memfree(ret);
2167 1.1 christos }
2168 1.1 christos #endif
2169 1.1 christos return (NULL);
2170 1.1 christos }
2171 1.1 christos
2172 1.1 christos ret = dmalloc (strlen (name[0]->bv_val) + 1, MDL);
2173 1.1 christos strcpy (ret, name[0]->bv_val);
2174 1.1 christos ldap_value_free_len (name);
2175 1.1 christos
2176 1.1 christos return (ret);
2177 1.1 christos }
2178 1.1 christos
2179 1.1 christos
2180 1.1 christos isc_result_t
2181 1.1 christos ldap_read_config (void)
2182 1.1 christos {
2183 1.1 christos LDAPMessage * ldres, * hostres, * ent, * hostent;
2184 1.1 christos char hfilter[1024], sfilter[1024], fqdn[257];
2185 1.1 christos char *hostdn;
2186 1.1 christos ldap_dn_node *curr = NULL;
2187 1.1 christos struct parse *cfile;
2188 1.1 christos struct utsname unme;
2189 1.1 christos isc_result_t res;
2190 1.1 christos size_t length;
2191 1.1 christos int ret, cnt;
2192 1.1 christos struct berval **tempbv = NULL;
2193 1.1 christos struct berval bv_o[2];
2194 1.1 christos
2195 1.1 christos cfile = x_parser_init("LDAP");
2196 1.1 christos if (cfile == NULL)
2197 1.1 christos return (ISC_R_NOMEMORY);
2198 1.1 christos
2199 1.1 christos ldap_enable_retry = 1;
2200 1.1 christos if (ld == NULL)
2201 1.1 christos ldap_start ();
2202 1.1 christos ldap_enable_retry = 0;
2203 1.1 christos
2204 1.1 christos if (ld == NULL)
2205 1.1 christos {
2206 1.1 christos x_parser_free(&cfile);
2207 1.1 christos return (ldap_server == NULL ? ISC_R_SUCCESS : ISC_R_FAILURE);
2208 1.1 christos }
2209 1.1 christos
2210 1.1 christos uname (&unme);
2211 1.1 christos if (ldap_dhcp_server_cn != NULL)
2212 1.1 christos {
2213 1.1 christos if (_do_ldap_str2esc_filter_bv(ldap_dhcp_server_cn, 0, &bv_o[0]) == NULL)
2214 1.1 christos {
2215 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", ldap_dhcp_server_cn);
2216 1.1 christos x_parser_free(&cfile);
2217 1.1 christos return (ISC_R_FAILURE);
2218 1.1 christos }
2219 1.1 christos
2220 1.1 christos snprintf (hfilter, sizeof (hfilter),
2221 1.1 christos "(&(objectClass=dhcpServer)(cn=%s))", bv_o[0].bv_val);
2222 1.1 christos
2223 1.1 christos ber_memfree(bv_o[0].bv_val);
2224 1.1 christos }
2225 1.1 christos else
2226 1.1 christos {
2227 1.1 christos if (_do_ldap_str2esc_filter_bv(unme.nodename, 0, &bv_o[0]) == NULL)
2228 1.1 christos {
2229 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", unme.nodename);
2230 1.1 christos x_parser_free(&cfile);
2231 1.1 christos return (ISC_R_FAILURE);
2232 1.1 christos }
2233 1.1 christos
2234 1.1 christos *fqdn ='\0';
2235 1.1 christos if(0 == get_host_entry(fqdn, sizeof(fqdn), NULL, 0))
2236 1.1 christos {
2237 1.1 christos if (_do_ldap_str2esc_filter_bv(fqdn, 0, &bv_o[1]) == NULL)
2238 1.1 christos {
2239 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", fqdn);
2240 1.1 christos ber_memfree(bv_o[0].bv_val);
2241 1.1 christos x_parser_free(&cfile);
2242 1.1 christos return (ISC_R_FAILURE);
2243 1.1 christos }
2244 1.1 christos }
2245 1.1 christos
2246 1.1 christos // If we have fqdn and it isn't the same as nodename, use it in filter
2247 1.1 christos // otherwise just use nodename
2248 1.1 christos if ((*fqdn) && (strcmp(unme.nodename, fqdn))) {
2249 1.1 christos snprintf (hfilter, sizeof (hfilter),
2250 1.1 christos "(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))",
2251 1.1 christos bv_o[0].bv_val, bv_o[1].bv_val);
2252 1.1 christos
2253 1.1 christos ber_memfree(bv_o[1].bv_val);
2254 1.1 christos }
2255 1.1 christos else
2256 1.1 christos {
2257 1.1 christos snprintf (hfilter, sizeof (hfilter),
2258 1.1 christos "(&(objectClass=dhcpServer)(cn=%s))",
2259 1.1 christos bv_o[0].bv_val);
2260 1.1 christos }
2261 1.1 christos
2262 1.1 christos ber_memfree(bv_o[0].bv_val);
2263 1.1 christos }
2264 1.1 christos
2265 1.1 christos ldap_enable_retry = 1;
2266 1.1 christos do
2267 1.1 christos {
2268 1.1 christos hostres = NULL;
2269 1.1 christos ret = ldap_search_ext_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE,
2270 1.1 christos hfilter, NULL, 0, NULL, NULL, NULL, 0,
2271 1.1 christos &hostres);
2272 1.1 christos }
2273 1.1 christos while(_do_ldap_retry(ret, ldap_server, ldap_port) > 0);
2274 1.1 christos ldap_enable_retry = 0;
2275 1.1 christos
2276 1.1 christos if(ret != LDAP_SUCCESS)
2277 1.1 christos {
2278 1.1 christos log_error ("Cannot find host LDAP entry %s %s",
2279 1.1 christos ((ldap_dhcp_server_cn == NULL)?(unme.nodename):(ldap_dhcp_server_cn)), hfilter);
2280 1.1 christos if(NULL != hostres)
2281 1.1 christos ldap_msgfree (hostres);
2282 1.1 christos ldap_stop();
2283 1.1 christos x_parser_free(&cfile);
2284 1.1 christos return (ISC_R_FAILURE);
2285 1.1 christos }
2286 1.1 christos
2287 1.1 christos if ((hostent = ldap_first_entry (ld, hostres)) == NULL)
2288 1.1 christos {
2289 1.1 christos log_error ("Error: Cannot find LDAP entry matching %s", hfilter);
2290 1.1 christos ldap_msgfree (hostres);
2291 1.1 christos ldap_stop();
2292 1.1 christos x_parser_free(&cfile);
2293 1.1 christos return (ISC_R_FAILURE);
2294 1.1 christos }
2295 1.1 christos
2296 1.1 christos hostdn = ldap_get_dn (ld, hostent);
2297 1.1 christos #if defined(DEBUG_LDAP)
2298 1.1 christos if (hostdn != NULL)
2299 1.1 christos log_info ("Found dhcpServer LDAP entry '%s'", hostdn);
2300 1.1 christos #endif
2301 1.1 christos
2302 1.1 christos if (hostdn == NULL ||
2303 1.1 christos (tempbv = ldap_get_values_len (ld, hostent, "dhcpServiceDN")) == NULL ||
2304 1.1 christos tempbv[0] == NULL)
2305 1.1 christos {
2306 1.1 christos log_error ("Error: No dhcp service is associated with the server %s %s",
2307 1.1 christos (hostdn ? "dn" : "name"), (hostdn ? hostdn :
2308 1.1 christos (ldap_dhcp_server_cn ? ldap_dhcp_server_cn : unme.nodename)));
2309 1.1 christos
2310 1.1 christos if (tempbv != NULL)
2311 1.1 christos ldap_value_free_len (tempbv);
2312 1.1 christos
2313 1.1 christos if (hostdn)
2314 1.1 christos ldap_memfree (hostdn);
2315 1.1 christos ldap_msgfree (hostres);
2316 1.1 christos ldap_stop();
2317 1.1 christos x_parser_free(&cfile);
2318 1.1 christos return (ISC_R_FAILURE);
2319 1.1 christos }
2320 1.1 christos
2321 1.1 christos #if defined(DEBUG_LDAP)
2322 1.1 christos log_info ("LDAP: Parsing dhcpServer options '%s' ...", hostdn);
2323 1.1 christos #endif
2324 1.1 christos
2325 1.1 christos res = ldap_parse_entry_options(hostent, cfile, NULL);
2326 1.1 christos if (res != ISC_R_SUCCESS)
2327 1.1 christos {
2328 1.1 christos ldap_value_free_len (tempbv);
2329 1.1 christos ldap_msgfree (hostres);
2330 1.1 christos ldap_memfree (hostdn);
2331 1.1 christos ldap_stop();
2332 1.1 christos x_parser_free(&cfile);
2333 1.1 christos return res;
2334 1.1 christos }
2335 1.1 christos
2336 1.1 christos if (x_parser_length(cfile) > 0)
2337 1.1 christos {
2338 1.1 christos ldap_write_debug(cfile->inbuf, cfile->buflen);
2339 1.1 christos
2340 1.1 christos res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
2341 1.1 christos if (res != ISC_R_SUCCESS)
2342 1.1 christos {
2343 1.1 christos log_error ("LDAP: cannot parse dhcpServer entry '%s'", hostdn);
2344 1.1 christos ldap_value_free_len (tempbv);
2345 1.1 christos ldap_msgfree (hostres);
2346 1.1 christos ldap_memfree (hostdn);
2347 1.1 christos ldap_stop();
2348 1.1 christos x_parser_free(&cfile);
2349 1.1 christos return res;
2350 1.1 christos }
2351 1.1 christos x_parser_reset(cfile);
2352 1.1 christos }
2353 1.1 christos ldap_msgfree (hostres);
2354 1.1 christos
2355 1.1 christos res = ISC_R_SUCCESS;
2356 1.1 christos for (cnt=0; tempbv[cnt] != NULL; cnt++)
2357 1.1 christos {
2358 1.1 christos
2359 1.1 christos if (_do_ldap_str2esc_filter_bv(hostdn, 0, &bv_o[0]) == NULL)
2360 1.1 christos {
2361 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", hostdn);
2362 1.1 christos res = ISC_R_FAILURE;
2363 1.1 christos break;
2364 1.1 christos }
2365 1.1 christos
2366 1.1 christos snprintf(sfilter, sizeof(sfilter), "(&(objectClass=dhcpService)"
2367 1.1 christos "(|(|(dhcpPrimaryDN=%s)(dhcpSecondaryDN=%s))(dhcpServerDN=%s)))",
2368 1.1 christos bv_o[0].bv_val, bv_o[0].bv_val, bv_o[0].bv_val);
2369 1.1 christos
2370 1.1 christos ber_memfree(bv_o[0].bv_val);
2371 1.1 christos
2372 1.1 christos ldres = NULL;
2373 1.1 christos if ((ret = ldap_search_ext_s (ld, tempbv[cnt]->bv_val, LDAP_SCOPE_BASE,
2374 1.1 christos sfilter, NULL, 0, NULL, NULL, NULL,
2375 1.1 christos 0, &ldres)) != LDAP_SUCCESS)
2376 1.1 christos {
2377 1.1 christos log_error ("Error searching for dhcpServiceDN '%s': %s. Please update the LDAP entry '%s'",
2378 1.1 christos tempbv[cnt]->bv_val, ldap_err2string (ret), hostdn);
2379 1.1 christos if(NULL != ldres)
2380 1.1 christos ldap_msgfree(ldres);
2381 1.1 christos res = ISC_R_FAILURE;
2382 1.1 christos break;
2383 1.1 christos }
2384 1.1 christos
2385 1.1 christos if ((ent = ldap_first_entry (ld, ldres)) == NULL)
2386 1.1 christos {
2387 1.1 christos log_error ("Error: Cannot find dhcpService DN '%s' with server reference. Please update the LDAP server entry '%s'",
2388 1.1 christos tempbv[cnt]->bv_val, hostdn);
2389 1.1 christos
2390 1.1 christos ldap_msgfree(ldres);
2391 1.1 christos res = ISC_R_FAILURE;
2392 1.1 christos break;
2393 1.1 christos }
2394 1.1 christos
2395 1.1 christos /*
2396 1.1 christos ** FIXME: how to free the remembered dn's on exit?
2397 1.1 christos ** This should be OK if dmalloc registers the
2398 1.1 christos ** memory it allocated and frees it on exit..
2399 1.1 christos */
2400 1.1 christos
2401 1.1 christos curr = dmalloc (sizeof (*curr), MDL);
2402 1.1 christos if (curr != NULL)
2403 1.1 christos {
2404 1.1 christos length = strlen (tempbv[cnt]->bv_val);
2405 1.1 christos curr->dn = dmalloc (length + 1, MDL);
2406 1.1 christos if (curr->dn == NULL)
2407 1.1 christos {
2408 1.1 christos dfree (curr, MDL);
2409 1.1 christos curr = NULL;
2410 1.1 christos }
2411 1.1 christos else
2412 1.1 christos strcpy (curr->dn, tempbv[cnt]->bv_val);
2413 1.1 christos }
2414 1.1 christos
2415 1.1 christos if (curr != NULL)
2416 1.1 christos {
2417 1.1 christos curr->refs++;
2418 1.1 christos
2419 1.1 christos /* append to service-dn list */
2420 1.1 christos if (ldap_service_dn_tail != NULL)
2421 1.1 christos ldap_service_dn_tail->next = curr;
2422 1.1 christos else
2423 1.1 christos ldap_service_dn_head = curr;
2424 1.1 christos
2425 1.1 christos ldap_service_dn_tail = curr;
2426 1.1 christos }
2427 1.1 christos else
2428 1.1 christos log_fatal ("no memory to remember ldap service dn");
2429 1.1 christos
2430 1.1 christos #if defined (DEBUG_LDAP)
2431 1.1 christos log_info ("LDAP: Parsing dhcpService DN '%s' ...", tempbv[cnt]->bv_val);
2432 1.1 christos #endif
2433 1.1 christos add_to_config_stack (ldres, ent);
2434 1.1 christos res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
2435 1.1 christos if (res != ISC_R_SUCCESS)
2436 1.1 christos {
2437 1.1 christos log_error ("LDAP: cannot parse dhcpService entry '%s'", tempbv[cnt]->bv_val);
2438 1.1 christos break;
2439 1.1 christos }
2440 1.1 christos }
2441 1.1 christos
2442 1.1 christos x_parser_free(&cfile);
2443 1.1 christos ldap_close_debug_fd();
2444 1.1 christos
2445 1.1 christos ldap_memfree (hostdn);
2446 1.1 christos ldap_value_free_len (tempbv);
2447 1.1 christos
2448 1.1 christos if (res != ISC_R_SUCCESS)
2449 1.1 christos {
2450 1.1 christos struct ldap_config_stack *temp_stack;
2451 1.1 christos
2452 1.1 christos while ((curr = ldap_service_dn_head) != NULL)
2453 1.1 christos {
2454 1.1 christos ldap_service_dn_head = curr->next;
2455 1.1 christos dfree (curr->dn, MDL);
2456 1.1 christos dfree (curr, MDL);
2457 1.1 christos }
2458 1.1 christos
2459 1.1 christos ldap_service_dn_tail = NULL;
2460 1.1 christos
2461 1.1 christos while ((temp_stack = ldap_stack) != NULL)
2462 1.1 christos {
2463 1.1 christos ldap_stack = temp_stack->next;
2464 1.1 christos free_stack_entry (temp_stack);
2465 1.1 christos }
2466 1.1 christos
2467 1.1 christos ldap_stop();
2468 1.1 christos }
2469 1.1 christos
2470 1.1 christos /* Unbind from ldap immediately after reading config in static mode. */
2471 1.1 christos if (ldap_method == LDAP_METHOD_STATIC)
2472 1.1 christos ldap_stop();
2473 1.1 christos
2474 1.1 christos return (res);
2475 1.1 christos }
2476 1.1 christos
2477 1.1 christos
2478 1.1 christos /* This function will parse the dhcpOption and dhcpStatements field in the LDAP
2479 1.1 christos entry if it exists. Right now, type will be either HOST_DECL or CLASS_DECL.
2480 1.1 christos If we are parsing a HOST_DECL, this always returns 0. If we are parsing a
2481 1.1 christos CLASS_DECL, this will return what the current lease limit is in LDAP. If
2482 1.1 christos there is no lease limit specified, we return 0 */
2483 1.1 christos
2484 1.1 christos static int
2485 1.1 christos ldap_parse_options (LDAPMessage * ent, struct group *group,
2486 1.1 christos int type, struct host_decl *host,
2487 1.1 christos struct class **class)
2488 1.1 christos {
2489 1.1 christos int declaration, lease_limit;
2490 1.1 christos enum dhcp_token token;
2491 1.1 christos struct parse *cfile;
2492 1.1 christos isc_result_t res;
2493 1.1 christos const char *val;
2494 1.1 christos
2495 1.1 christos lease_limit = 0;
2496 1.1 christos cfile = x_parser_init(type == HOST_DECL ? "LDAP-HOST" : "LDAP-SUBCLASS");
2497 1.1 christos if (cfile == NULL)
2498 1.1 christos return (lease_limit);
2499 1.1 christos
2500 1.1 christos /* This block of code will try to find the parent of the host, and
2501 1.1 christos if it is a group object, fetch the options and apply to the host. */
2502 1.1 christos if (type == HOST_DECL)
2503 1.1 christos {
2504 1.1 christos char *hostdn, *basedn, *temp1, *temp2, filter[1024];
2505 1.1 christos LDAPMessage *groupdn, *entry;
2506 1.1 christos int ret;
2507 1.1 christos
2508 1.1 christos hostdn = ldap_get_dn (ld, ent);
2509 1.1 christos if( hostdn != NULL)
2510 1.1 christos {
2511 1.1 christos basedn = NULL;
2512 1.1 christos
2513 1.1 christos temp1 = strchr (hostdn, '=');
2514 1.1 christos if (temp1 != NULL)
2515 1.1 christos temp1 = strchr (++temp1, '=');
2516 1.1 christos if (temp1 != NULL)
2517 1.1 christos temp2 = strchr (++temp1, ',');
2518 1.1 christos else
2519 1.1 christos temp2 = NULL;
2520 1.1 christos
2521 1.1 christos if (temp2 != NULL)
2522 1.1 christos {
2523 1.1 christos struct berval bv_o;
2524 1.1 christos
2525 1.1 christos if (_do_ldap_str2esc_filter_bv(temp1, (temp2 - temp1), &bv_o) == NULL)
2526 1.1 christos {
2527 1.1 christos log_error ("Cannot escape ldap filter value %.*s: %m",
2528 1.1 christos (int)(temp2 - temp1), temp1);
2529 1.1 christos filter[0] = '\0';
2530 1.1 christos }
2531 1.1 christos else
2532 1.1 christos {
2533 1.1 christos snprintf (filter, sizeof(filter),
2534 1.1 christos "(&(cn=%s)(objectClass=dhcpGroup))",
2535 1.1 christos bv_o.bv_val);
2536 1.1 christos
2537 1.1 christos ber_memfree(bv_o.bv_val);
2538 1.1 christos }
2539 1.1 christos
2540 1.1 christos basedn = strchr (temp1, ',');
2541 1.1 christos if (basedn != NULL)
2542 1.1 christos ++basedn;
2543 1.1 christos }
2544 1.1 christos
2545 1.1 christos if (basedn != NULL && *basedn != '\0' && filter[0] != '\0')
2546 1.1 christos {
2547 1.1 christos ret = ldap_search_ext_s (ld, basedn, LDAP_SCOPE_SUBTREE, filter,
2548 1.1 christos NULL, 0, NULL, NULL, NULL, 0, &groupdn);
2549 1.1 christos if (ret == LDAP_SUCCESS)
2550 1.1 christos {
2551 1.1 christos if ((entry = ldap_first_entry (ld, groupdn)) != NULL)
2552 1.1 christos {
2553 1.1 christos res = ldap_parse_entry_options (entry, cfile, &lease_limit);
2554 1.1 christos if (res != ISC_R_SUCCESS)
2555 1.1 christos {
2556 1.1 christos /* reset option buffer discarding any results */
2557 1.1 christos x_parser_reset(cfile);
2558 1.1 christos lease_limit = 0;
2559 1.1 christos }
2560 1.1 christos }
2561 1.1 christos ldap_msgfree( groupdn);
2562 1.1 christos }
2563 1.1 christos }
2564 1.1 christos ldap_memfree( hostdn);
2565 1.1 christos }
2566 1.1 christos }
2567 1.1 christos
2568 1.1 christos res = ldap_parse_entry_options (ent, cfile, &lease_limit);
2569 1.1 christos if (res != ISC_R_SUCCESS)
2570 1.1 christos {
2571 1.1 christos x_parser_free(&cfile);
2572 1.1 christos return (lease_limit);
2573 1.1 christos }
2574 1.1 christos
2575 1.1 christos if (x_parser_length(cfile) == 0)
2576 1.1 christos {
2577 1.1 christos x_parser_free(&cfile);
2578 1.1 christos return (lease_limit);
2579 1.1 christos }
2580 1.1 christos
2581 1.1 christos declaration = 0;
2582 1.1 christos do
2583 1.1 christos {
2584 1.1 christos token = peek_token (&val, NULL, cfile);
2585 1.1 christos if (token == END_OF_FILE)
2586 1.1 christos break;
2587 1.1 christos declaration = parse_statement (cfile, group, type, host, declaration);
2588 1.1 christos } while (1);
2589 1.1 christos
2590 1.1 christos x_parser_free(&cfile);
2591 1.1 christos
2592 1.1 christos return (lease_limit);
2593 1.1 christos }
2594 1.1 christos
2595 1.1 christos
2596 1.1 christos
2597 1.1 christos int
2598 1.1 christos find_haddr_in_ldap (struct host_decl **hp, int htype, unsigned hlen,
2599 1.1 christos const unsigned char *haddr, const char *file, int line)
2600 1.1 christos {
2601 1.1 christos char buf[128], *type_str;
2602 1.1 christos LDAPMessage * res, *ent;
2603 1.1 christos struct host_decl * host;
2604 1.1 christos isc_result_t status;
2605 1.1 christos ldap_dn_node *curr;
2606 1.1 christos char up_hwaddr[20];
2607 1.1 christos char lo_hwaddr[20];
2608 1.1 christos int ret;
2609 1.1 christos struct berval bv_o[2];
2610 1.1 christos
2611 1.1 christos *hp = NULL;
2612 1.1 christos
2613 1.1 christos
2614 1.1 christos if (ldap_method == LDAP_METHOD_STATIC)
2615 1.1 christos return (0);
2616 1.1 christos
2617 1.1 christos if (ld == NULL)
2618 1.1 christos ldap_start ();
2619 1.1 christos if (ld == NULL)
2620 1.1 christos return (0);
2621 1.1 christos
2622 1.1 christos switch (htype)
2623 1.1 christos {
2624 1.1 christos case HTYPE_ETHER:
2625 1.1 christos type_str = "ethernet";
2626 1.1 christos break;
2627 1.1 christos case HTYPE_IEEE802:
2628 1.1 christos type_str = "token-ring";
2629 1.1 christos break;
2630 1.1 christos case HTYPE_FDDI:
2631 1.1 christos type_str = "fddi";
2632 1.1 christos break;
2633 1.1 christos default:
2634 1.1 christos log_info ("Ignoring unknown type %d", htype);
2635 1.1 christos return (0);
2636 1.1 christos }
2637 1.1 christos
2638 1.1 christos /*
2639 1.1 christos ** FIXME: It is not guaranteed, that the dhcpHWAddress attribute
2640 1.1 christos ** contains _exactly_ "type addr" with one space between!
2641 1.1 christos */
2642 1.1 christos snprintf(lo_hwaddr, sizeof(lo_hwaddr), "%s",
2643 1.1 christos print_hw_addr (htype, hlen, haddr));
2644 1.1 christos x_strxform(up_hwaddr, lo_hwaddr, sizeof(up_hwaddr), toupper);
2645 1.1 christos
2646 1.1 christos if (_do_ldap_str2esc_filter_bv(lo_hwaddr, 0, &bv_o[0]) == NULL)
2647 1.1 christos {
2648 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", lo_hwaddr);
2649 1.1 christos return (0);
2650 1.1 christos }
2651 1.1 christos if (_do_ldap_str2esc_filter_bv(up_hwaddr, 0, &bv_o[1]) == NULL)
2652 1.1 christos {
2653 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", up_hwaddr);
2654 1.1 christos ber_memfree(bv_o[0].bv_val);
2655 1.1 christos return (0);
2656 1.1 christos }
2657 1.1 christos
2658 1.1 christos snprintf (buf, sizeof (buf),
2659 1.1 christos "(&(objectClass=dhcpHost)(|(dhcpHWAddress=%s %s)(dhcpHWAddress=%s %s)))",
2660 1.1 christos type_str, bv_o[0].bv_val, type_str, bv_o[1].bv_val);
2661 1.1 christos
2662 1.1 christos ber_memfree(bv_o[0].bv_val);
2663 1.1 christos ber_memfree(bv_o[1].bv_val);
2664 1.1 christos
2665 1.1 christos res = ent = NULL;
2666 1.1 christos for (curr = ldap_service_dn_head;
2667 1.1 christos curr != NULL && *curr->dn != '\0';
2668 1.1 christos curr = curr->next)
2669 1.1 christos {
2670 1.1 christos #if defined (DEBUG_LDAP)
2671 1.1 christos log_info ("Searching for %s in LDAP tree %s", buf, curr->dn);
2672 1.1 christos #endif
2673 1.1 christos ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL, 0,
2674 1.1 christos NULL, NULL, NULL, 0, &res);
2675 1.1 christos
2676 1.1 christos if(ret == LDAP_SERVER_DOWN)
2677 1.1 christos {
2678 1.1 christos log_info ("LDAP server was down, trying to reconnect...");
2679 1.1 christos
2680 1.1 christos ldap_stop();
2681 1.1 christos ldap_start();
2682 1.1 christos if(ld == NULL)
2683 1.1 christos {
2684 1.1 christos log_info ("LDAP reconnect failed - try again later...");
2685 1.1 christos return (0);
2686 1.1 christos }
2687 1.1 christos
2688 1.1 christos ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL,
2689 1.1 christos 0, NULL, NULL, NULL, 0, &res);
2690 1.1 christos }
2691 1.1 christos
2692 1.1 christos if (ret == LDAP_SUCCESS)
2693 1.1 christos {
2694 1.1 christos ent = ldap_first_entry (ld, res);
2695 1.1 christos #if defined (DEBUG_LDAP)
2696 1.1 christos if (ent == NULL) {
2697 1.1 christos log_info ("No host entry for %s in LDAP tree %s",
2698 1.1 christos buf, curr->dn);
2699 1.1 christos }
2700 1.1 christos #endif
2701 1.1 christos while (ent != NULL) {
2702 1.1 christos #if defined (DEBUG_LDAP)
2703 1.1 christos char *dn = ldap_get_dn (ld, ent);
2704 1.1 christos if (dn != NULL)
2705 1.1 christos {
2706 1.1 christos log_info ("Found dhcpHWAddress LDAP entry %s", dn);
2707 1.1 christos ldap_memfree(dn);
2708 1.1 christos }
2709 1.1 christos #endif
2710 1.1 christos
2711 1.1 christos host = (struct host_decl *)0;
2712 1.1 christos status = host_allocate (&host, MDL);
2713 1.1 christos if (status != ISC_R_SUCCESS)
2714 1.1 christos {
2715 1.1 christos log_fatal ("can't allocate host decl struct: %s",
2716 1.1 christos isc_result_totext (status));
2717 1.1 christos ldap_msgfree (res);
2718 1.1 christos return (0);
2719 1.1 christos }
2720 1.1 christos
2721 1.1 christos host->name = ldap_get_host_name (ent);
2722 1.1 christos if (host->name == NULL)
2723 1.1 christos {
2724 1.1 christos host_dereference (&host, MDL);
2725 1.1 christos ldap_msgfree (res);
2726 1.1 christos return (0);
2727 1.1 christos }
2728 1.1 christos
2729 1.1 christos if (!clone_group (&host->group, root_group, MDL))
2730 1.1 christos {
2731 1.1 christos log_fatal ("can't clone group for host %s", host->name);
2732 1.1 christos host_dereference (&host, MDL);
2733 1.1 christos ldap_msgfree (res);
2734 1.1 christos return (0);
2735 1.1 christos }
2736 1.1 christos
2737 1.1 christos ldap_parse_options (ent, host->group, HOST_DECL, host, NULL);
2738 1.1 christos
2739 1.1 christos host->n_ipaddr = *hp;
2740 1.1 christos *hp = host;
2741 1.1 christos ent = ldap_next_entry (ld, ent);
2742 1.1 christos }
2743 1.1 christos if(res)
2744 1.1 christos {
2745 1.1 christos ldap_msgfree (res);
2746 1.1 christos res = NULL;
2747 1.1 christos }
2748 1.1 christos return (*hp != NULL);
2749 1.1 christos }
2750 1.1 christos else
2751 1.1 christos {
2752 1.1 christos if(res)
2753 1.1 christos {
2754 1.1 christos ldap_msgfree (res);
2755 1.1 christos res = NULL;
2756 1.1 christos }
2757 1.1 christos
2758 1.1 christos if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
2759 1.1 christos {
2760 1.1 christos log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
2761 1.1 christos curr->dn, ldap_err2string (ret));
2762 1.1 christos ldap_stop();
2763 1.1 christos return (0);
2764 1.1 christos }
2765 1.1 christos #if defined (DEBUG_LDAP)
2766 1.1 christos else
2767 1.1 christos {
2768 1.1 christos log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
2769 1.1 christos ldap_err2string (ret), buf, curr->dn);
2770 1.1 christos }
2771 1.1 christos #endif
2772 1.1 christos }
2773 1.1 christos }
2774 1.1 christos
2775 1.1 christos return (0);
2776 1.1 christos }
2777 1.1 christos
2778 1.1 christos
2779 1.1 christos int
2780 1.1 christos find_subclass_in_ldap (struct class *class, struct class **newclass,
2781 1.1 christos struct data_string *data)
2782 1.1 christos {
2783 1.1 christos LDAPMessage * res, * ent;
2784 1.1 christos int ret, lease_limit;
2785 1.1 christos isc_result_t status;
2786 1.1 christos ldap_dn_node *curr;
2787 1.1 christos char buf[2048];
2788 1.1 christos struct berval bv_class;
2789 1.1 christos struct berval bv_cdata;
2790 1.1 christos char *hex_1;
2791 1.1 christos
2792 1.1 christos if (ldap_method == LDAP_METHOD_STATIC)
2793 1.1 christos return (0);
2794 1.1 christos
2795 1.1 christos if (ld == NULL)
2796 1.1 christos ldap_start ();
2797 1.1 christos if (ld == NULL)
2798 1.1 christos return (0);
2799 1.1 christos
2800 1.1 christos hex_1 = print_hex_1 (data->len, data->data, 1024);
2801 1.1 christos if (*hex_1 == '"')
2802 1.1 christos {
2803 1.1 christos /* result is a quotted not hex string: ldap escape the original string */
2804 1.1 christos if (_do_ldap_str2esc_filter_bv((const char*)data->data, data->len, &bv_cdata) == NULL)
2805 1.1 christos {
2806 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", hex_1);
2807 1.1 christos return (0);
2808 1.1 christos }
2809 1.1 christos hex_1 = NULL;
2810 1.1 christos }
2811 1.1 christos if (_do_ldap_str2esc_filter_bv(class->name, strlen (class->name), &bv_class) == NULL)
2812 1.1 christos {
2813 1.1 christos log_error ("Cannot escape ldap filter value %s: %m", class->name);
2814 1.1 christos if (hex_1 == NULL)
2815 1.1 christos ber_memfree(bv_cdata.bv_val);
2816 1.1 christos return (0);
2817 1.1 christos }
2818 1.1 christos
2819 1.1 christos snprintf (buf, sizeof (buf),
2820 1.1 christos "(&(objectClass=dhcpSubClass)(cn=%s)(dhcpClassData=%s))",
2821 1.1 christos (hex_1 == NULL ? bv_cdata.bv_val : hex_1), bv_class.bv_val);
2822 1.1 christos
2823 1.1 christos if (hex_1 == NULL)
2824 1.1 christos ber_memfree(bv_cdata.bv_val);
2825 1.1 christos ber_memfree(bv_class.bv_val);
2826 1.1 christos
2827 1.1 christos #if defined (DEBUG_LDAP)
2828 1.1 christos log_info ("Searching LDAP for %s", buf);
2829 1.1 christos #endif
2830 1.1 christos
2831 1.1 christos res = ent = NULL;
2832 1.1 christos for (curr = ldap_service_dn_head;
2833 1.1 christos curr != NULL && *curr->dn != '\0';
2834 1.1 christos curr = curr->next)
2835 1.1 christos {
2836 1.1 christos #if defined (DEBUG_LDAP)
2837 1.1 christos log_info ("Searching for %s in LDAP tree %s", buf, curr->dn);
2838 1.1 christos #endif
2839 1.1 christos ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL, 0,
2840 1.1 christos NULL, NULL, NULL, 0, &res);
2841 1.1 christos
2842 1.1 christos if(ret == LDAP_SERVER_DOWN)
2843 1.1 christos {
2844 1.1 christos log_info ("LDAP server was down, trying to reconnect...");
2845 1.1 christos
2846 1.1 christos ldap_stop();
2847 1.1 christos ldap_start();
2848 1.1 christos
2849 1.1 christos if(ld == NULL)
2850 1.1 christos {
2851 1.1 christos log_info ("LDAP reconnect failed - try again later...");
2852 1.1 christos return (0);
2853 1.1 christos }
2854 1.1 christos
2855 1.1 christos ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf,
2856 1.1 christos NULL, 0, NULL, NULL, NULL, 0, &res);
2857 1.1 christos }
2858 1.1 christos
2859 1.1 christos if (ret == LDAP_SUCCESS)
2860 1.1 christos {
2861 1.1 christos if( (ent = ldap_first_entry (ld, res)) != NULL)
2862 1.1 christos break; /* search OK and have entry */
2863 1.1 christos
2864 1.1 christos #if defined (DEBUG_LDAP)
2865 1.1 christos log_info ("No subclass entry for %s in LDAP tree %s",
2866 1.1 christos buf, curr->dn);
2867 1.1 christos #endif
2868 1.1 christos if(res)
2869 1.1 christos {
2870 1.1 christos ldap_msgfree (res);
2871 1.1 christos res = NULL;
2872 1.1 christos }
2873 1.1 christos }
2874 1.1 christos else
2875 1.1 christos {
2876 1.1 christos if(res)
2877 1.1 christos {
2878 1.1 christos ldap_msgfree (res);
2879 1.1 christos res = NULL;
2880 1.1 christos }
2881 1.1 christos
2882 1.1 christos if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
2883 1.1 christos {
2884 1.1 christos log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
2885 1.1 christos curr->dn, ldap_err2string (ret));
2886 1.1 christos ldap_stop();
2887 1.1 christos return (0);
2888 1.1 christos }
2889 1.1 christos #if defined (DEBUG_LDAP)
2890 1.1 christos else
2891 1.1 christos {
2892 1.1 christos log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
2893 1.1 christos ldap_err2string (ret), buf, curr->dn);
2894 1.1 christos }
2895 1.1 christos #endif
2896 1.1 christos }
2897 1.1 christos }
2898 1.1 christos
2899 1.1 christos if (res && ent)
2900 1.1 christos {
2901 1.1 christos #if defined (DEBUG_LDAP)
2902 1.1 christos char *dn = ldap_get_dn (ld, ent);
2903 1.1 christos if (dn != NULL)
2904 1.1 christos {
2905 1.1 christos log_info ("Found subclass LDAP entry %s", dn);
2906 1.1 christos ldap_memfree(dn);
2907 1.1 christos }
2908 1.1 christos #endif
2909 1.1 christos
2910 1.1 christos status = class_allocate (newclass, MDL);
2911 1.1 christos if (status != ISC_R_SUCCESS)
2912 1.1 christos {
2913 1.1 christos log_error ("Cannot allocate memory for a new class");
2914 1.1 christos ldap_msgfree (res);
2915 1.1 christos return (0);
2916 1.1 christos }
2917 1.1 christos
2918 1.1 christos group_reference (&(*newclass)->group, class->group, MDL);
2919 1.1 christos class_reference (&(*newclass)->superclass, class, MDL);
2920 1.1 christos lease_limit = ldap_parse_options (ent, (*newclass)->group,
2921 1.1 christos CLASS_DECL, NULL, newclass);
2922 1.1 christos if (lease_limit == 0)
2923 1.1 christos (*newclass)->lease_limit = class->lease_limit;
2924 1.1 christos else
2925 1.1 christos class->lease_limit = lease_limit;
2926 1.1 christos
2927 1.1 christos if ((*newclass)->lease_limit)
2928 1.1 christos {
2929 1.1 christos (*newclass)->billed_leases =
2930 1.1 christos dmalloc ((*newclass)->lease_limit * sizeof (struct lease *), MDL);
2931 1.1 christos if (!(*newclass)->billed_leases)
2932 1.1 christos {
2933 1.1 christos log_error ("no memory for billing");
2934 1.1 christos class_dereference (newclass, MDL);
2935 1.1 christos ldap_msgfree (res);
2936 1.1 christos return (0);
2937 1.1 christos }
2938 1.1 christos memset ((*newclass)->billed_leases, 0,
2939 1.1 christos ((*newclass)->lease_limit * sizeof (struct lease *)));
2940 1.1 christos }
2941 1.1 christos
2942 1.1 christos data_string_copy (&(*newclass)->hash_string, data, MDL);
2943 1.1 christos
2944 1.1 christos ldap_msgfree (res);
2945 1.1 christos return (1);
2946 1.1 christos }
2947 1.1 christos
2948 1.1 christos if(res) ldap_msgfree (res);
2949 1.1 christos return (0);
2950 1.1 christos }
2951 1.1 christos
2952 1.1 christos int find_client_in_ldap (struct host_decl **hp, struct packet *packet,
2953 1.1 christos struct option_state *state, const char *file, int line)
2954 1.1 christos {
2955 1.1 christos LDAPMessage * res, * ent;
2956 1.1 christos ldap_dn_node *curr;
2957 1.1 christos struct host_decl * host;
2958 1.1 christos isc_result_t status;
2959 1.1 christos struct data_string client_id;
2960 1.1 christos char buf[1024], buf1[1024];
2961 1.1 christos int ret;
2962 1.1 christos
2963 1.1 christos if (ldap_method == LDAP_METHOD_STATIC)
2964 1.1 christos return (0);
2965 1.1 christos
2966 1.1 christos if (ld == NULL)
2967 1.1 christos ldap_start ();
2968 1.1 christos if (ld == NULL)
2969 1.1 christos return (0);
2970 1.1 christos
2971 1.1 christos memset(&client_id, 0, sizeof(client_id));
2972 1.1 christos if (get_client_id(packet, &client_id) != ISC_R_SUCCESS)
2973 1.1 christos return (0);
2974 1.1 christos snprintf(buf, sizeof(buf),
2975 1.1 christos "(&(objectClass=dhcpHost)(dhcpClientId=%s))",
2976 1.1 christos print_hw_addr(0, client_id.len, client_id.data));
2977 1.1 christos
2978 1.1 christos /* log_info ("Searching LDAP for %s (%s)", buf, packet->interface->shared_network->name); */
2979 1.1 christos
2980 1.1 christos res = ent = NULL;
2981 1.1 christos for (curr = ldap_service_dn_head;
2982 1.1 christos curr != NULL && *curr->dn != '\0';
2983 1.1 christos curr = curr->next)
2984 1.1 christos {
2985 1.1 christos snprintf(buf1, sizeof(buf1), "cn=%s,%s", packet->interface->shared_network->name, curr->dn);
2986 1.1 christos #if defined (DEBUG_LDAP)
2987 1.1 christos log_info ("Searching for %s in LDAP tree %s", buf, buf1);
2988 1.1 christos #endif
2989 1.1 christos ret = ldap_search_ext_s (ld, buf1, LDAP_SCOPE_SUBTREE, buf, NULL, 0,
2990 1.1 christos NULL, NULL, NULL, 0, &res);
2991 1.1 christos
2992 1.1 christos if(ret == LDAP_SERVER_DOWN)
2993 1.1 christos {
2994 1.1 christos log_info ("LDAP server was down, trying to reconnect...");
2995 1.1 christos
2996 1.1 christos ldap_stop();
2997 1.1 christos ldap_start();
2998 1.1 christos
2999 1.1 christos if(ld == NULL)
3000 1.1 christos {
3001 1.1 christos log_info ("LDAP reconnect failed - try again later...");
3002 1.1 christos return (0);
3003 1.1 christos }
3004 1.1 christos
3005 1.1 christos ret = ldap_search_ext_s (ld, buf1, LDAP_SCOPE_SUBTREE, buf,
3006 1.1 christos NULL, 0, NULL, NULL, NULL, 0, &res);
3007 1.1 christos }
3008 1.1 christos
3009 1.1 christos if (ret == LDAP_SUCCESS)
3010 1.1 christos {
3011 1.1 christos if( (ent = ldap_first_entry (ld, res)) != NULL) {
3012 1.1 christos log_info ("found entry in search %s", buf1);
3013 1.1 christos break; /* search OK and have entry */
3014 1.1 christos }
3015 1.1 christos
3016 1.1 christos #if defined (DEBUG_LDAP)
3017 1.1 christos log_info ("No subclass entry for %s in LDAP tree %s", buf, curr->dn);
3018 1.1 christos #endif
3019 1.1 christos if(res)
3020 1.1 christos {
3021 1.1 christos ldap_msgfree (res);
3022 1.1 christos res = NULL;
3023 1.1 christos }
3024 1.1 christos }
3025 1.1 christos else
3026 1.1 christos {
3027 1.1 christos if(res)
3028 1.1 christos {
3029 1.1 christos ldap_msgfree (res);
3030 1.1 christos res = NULL;
3031 1.1 christos }
3032 1.1 christos
3033 1.1 christos if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
3034 1.1 christos {
3035 1.1 christos log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
3036 1.1 christos curr->dn, ldap_err2string (ret));
3037 1.1 christos ldap_stop();
3038 1.1 christos return (0);
3039 1.1 christos }
3040 1.1 christos else
3041 1.1 christos {
3042 1.1 christos log_info ("did not find: %s", buf);
3043 1.1 christos }
3044 1.1 christos }
3045 1.1 christos }
3046 1.1 christos
3047 1.1 christos if (res && ent)
3048 1.1 christos {
3049 1.1 christos #if defined (DEBUG_LDAP)
3050 1.1 christos log_info ("ldap_get_dn %s", curr->dn);
3051 1.1 christos char *dn = ldap_get_dn (ld, ent);
3052 1.1 christos if (dn != NULL)
3053 1.1 christos {
3054 1.1 christos log_info ("Found subclass LDAP entry %s", dn);
3055 1.1 christos ldap_memfree(dn);
3056 1.1 christos } else {
3057 1.1 christos log_info ("DN is null %s", dn);
3058 1.1 christos }
3059 1.1 christos #endif
3060 1.1 christos
3061 1.1 christos host = (struct host_decl *)0;
3062 1.1 christos status = host_allocate (&host, MDL);
3063 1.1 christos if (status != ISC_R_SUCCESS)
3064 1.1 christos {
3065 1.1 christos log_fatal ("can't allocate host decl struct: %s",
3066 1.1 christos isc_result_totext (status));
3067 1.1 christos ldap_msgfree (res);
3068 1.1 christos return (0);
3069 1.1 christos }
3070 1.1 christos
3071 1.1 christos host->name = ldap_get_host_name (ent);
3072 1.1 christos if (host->name == NULL)
3073 1.1 christos {
3074 1.1 christos host_dereference (&host, MDL);
3075 1.1 christos ldap_msgfree (res);
3076 1.1 christos return (0);
3077 1.1 christos }
3078 1.1 christos /* log_info ("Host name %s", host->name); */
3079 1.1 christos
3080 1.1 christos if (!clone_group (&host->group, root_group, MDL))
3081 1.1 christos {
3082 1.1 christos log_fatal ("can't clone group for host %s", host->name);
3083 1.1 christos host_dereference (&host, MDL);
3084 1.1 christos ldap_msgfree (res);
3085 1.1 christos return (0);
3086 1.1 christos }
3087 1.1 christos
3088 1.1 christos ldap_parse_options (ent, host->group, HOST_DECL, host, NULL);
3089 1.1 christos
3090 1.1 christos *hp = host;
3091 1.1 christos ldap_msgfree (res);
3092 1.1 christos return (1);
3093 1.1 christos }
3094 1.1 christos else
3095 1.1 christos {
3096 1.1 christos log_info ("did not find clientid: %s", buf);
3097 1.1 christos }
3098 1.1 christos
3099 1.1 christos if(res) ldap_msgfree (res);
3100 1.1 christos return (0);
3101 1.1 christos
3102 1.1 christos }
3103 1.1 christos
3104 1.1 christos #if defined(LDAP_USE_GSSAPI)
3105 1.1 christos static int
3106 1.1 christos _ldap_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *sin)
3107 1.1 christos {
3108 1.1 christos sasl_interact_t *in;
3109 1.1 christos struct ldap_sasl_instance *ldap_inst = defaults;
3110 1.1 christos int ret = LDAP_OTHER;
3111 1.1 christos size_t size;
3112 1.1 christos
3113 1.1 christos if (ld == NULL || sin == NULL)
3114 1.1 christos return LDAP_PARAM_ERROR;
3115 1.1 christos
3116 1.1 christos log_info("doing interactive bind");
3117 1.1 christos for (in = sin; in != NULL && in->id != SASL_CB_LIST_END; in++) {
3118 1.1 christos switch (in->id) {
3119 1.1 christos case SASL_CB_USER:
3120 1.1 christos log_info("got request for SASL_CB_USER %s", ldap_inst->sasl_authz_id);
3121 1.1 christos size = strlen(ldap_inst->sasl_authz_id);
3122 1.1 christos in->result = ldap_inst->sasl_authz_id;
3123 1.1 christos in->len = size;
3124 1.1 christos ret = LDAP_SUCCESS;
3125 1.1 christos break;
3126 1.1 christos case SASL_CB_GETREALM:
3127 1.1 christos log_info("got request for SASL_CB_GETREALM %s", ldap_inst->sasl_realm);
3128 1.1 christos size = strlen(ldap_inst->sasl_realm);
3129 1.1 christos in->result = ldap_inst->sasl_realm;
3130 1.1 christos in->len = size;
3131 1.1 christos ret = LDAP_SUCCESS;
3132 1.1 christos break;
3133 1.1 christos case SASL_CB_AUTHNAME:
3134 1.1 christos log_info("got request for SASL_CB_AUTHNAME %s", ldap_inst->sasl_authc_id);
3135 1.1 christos size = strlen(ldap_inst->sasl_authc_id);
3136 1.1 christos in->result = ldap_inst->sasl_authc_id;
3137 1.1 christos in->len = size;
3138 1.1 christos ret = LDAP_SUCCESS;
3139 1.1 christos break;
3140 1.1 christos case SASL_CB_PASS:
3141 1.1 christos log_info("got request for SASL_CB_PASS %s", ldap_inst->sasl_password);
3142 1.1 christos size = strlen(ldap_inst->sasl_password);
3143 1.1 christos in->result = ldap_inst->sasl_password;
3144 1.1 christos in->len = size;
3145 1.1 christos ret = LDAP_SUCCESS;
3146 1.1 christos break;
3147 1.1 christos default:
3148 1.1 christos goto cleanup;
3149 1.1 christos }
3150 1.1 christos }
3151 1.1 christos return ret;
3152 1.1 christos
3153 1.1 christos cleanup:
3154 1.1 christos in->result = NULL;
3155 1.1 christos in->len = 0;
3156 1.1 christos return LDAP_OTHER;
3157 1.1 christos }
3158 1.1 christos #endif /* LDAP_USE_GSSAPI */
3159 1.1 christos
3160 1.1 christos
3161 1.1 christos #endif
3162