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