Home | History | Annotate | Line # | Download | only in server
      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