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