1*83ee113eSDavid van Moolenbroek /* $NetBSD: ldap.c,v 1.1.1.4 2014/07/12 11:58:13 spz Exp $ */
2*83ee113eSDavid van Moolenbroek /* ldap.c
3*83ee113eSDavid van Moolenbroek
4*83ee113eSDavid van Moolenbroek Routines for reading the configuration from LDAP */
5*83ee113eSDavid van Moolenbroek
6*83ee113eSDavid van Moolenbroek /*
7*83ee113eSDavid van Moolenbroek * Copyright (c) 2003-2006 Ntelos, Inc.
8*83ee113eSDavid van Moolenbroek * All rights reserved.
9*83ee113eSDavid van Moolenbroek *
10*83ee113eSDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
11*83ee113eSDavid van Moolenbroek * modification, are permitted provided that the following conditions
12*83ee113eSDavid van Moolenbroek * are met:
13*83ee113eSDavid van Moolenbroek *
14*83ee113eSDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
15*83ee113eSDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
16*83ee113eSDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
17*83ee113eSDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the
18*83ee113eSDavid van Moolenbroek * documentation and/or other materials provided with the distribution.
19*83ee113eSDavid van Moolenbroek * 3. Neither the name of The Internet Software Consortium nor the names
20*83ee113eSDavid van Moolenbroek * of its contributors may be used to endorse or promote products derived
21*83ee113eSDavid van Moolenbroek * from this software without specific prior written permission.
22*83ee113eSDavid van Moolenbroek *
23*83ee113eSDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
24*83ee113eSDavid van Moolenbroek * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25*83ee113eSDavid van Moolenbroek * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26*83ee113eSDavid van Moolenbroek * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27*83ee113eSDavid van Moolenbroek * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
28*83ee113eSDavid van Moolenbroek * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29*83ee113eSDavid van Moolenbroek * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30*83ee113eSDavid van Moolenbroek * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
31*83ee113eSDavid van Moolenbroek * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32*83ee113eSDavid van Moolenbroek * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33*83ee113eSDavid van Moolenbroek * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34*83ee113eSDavid van Moolenbroek * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35*83ee113eSDavid van Moolenbroek * SUCH DAMAGE.
36*83ee113eSDavid van Moolenbroek *
37*83ee113eSDavid van Moolenbroek * This LDAP module was written by Brian Masney <masneyb@ntelos.net>. Its
38*83ee113eSDavid van Moolenbroek * development was sponsored by Ntelos, Inc. (www.ntelos.com).
39*83ee113eSDavid van Moolenbroek */
40*83ee113eSDavid van Moolenbroek
41*83ee113eSDavid van Moolenbroek #include <sys/cdefs.h>
42*83ee113eSDavid van Moolenbroek __RCSID("$NetBSD: ldap.c,v 1.1.1.4 2014/07/12 11:58:13 spz Exp $");
43*83ee113eSDavid van Moolenbroek
44*83ee113eSDavid van Moolenbroek #include "dhcpd.h"
45*83ee113eSDavid van Moolenbroek #include <signal.h>
46*83ee113eSDavid van Moolenbroek #include <errno.h>
47*83ee113eSDavid van Moolenbroek
48*83ee113eSDavid van Moolenbroek #if defined(LDAP_CONFIGURATION)
49*83ee113eSDavid van Moolenbroek
50*83ee113eSDavid van Moolenbroek #if defined(LDAP_CASA_AUTH)
51*83ee113eSDavid van Moolenbroek #include "ldap_casa.h"
52*83ee113eSDavid van Moolenbroek #endif
53*83ee113eSDavid van Moolenbroek
54*83ee113eSDavid van Moolenbroek static LDAP * ld = NULL;
55*83ee113eSDavid van Moolenbroek static char *ldap_server = NULL,
56*83ee113eSDavid van Moolenbroek *ldap_username = NULL,
57*83ee113eSDavid van Moolenbroek *ldap_password = NULL,
58*83ee113eSDavid van Moolenbroek *ldap_base_dn = NULL,
59*83ee113eSDavid van Moolenbroek *ldap_dhcp_server_cn = NULL,
60*83ee113eSDavid van Moolenbroek *ldap_debug_file = NULL;
61*83ee113eSDavid van Moolenbroek static int ldap_port = LDAP_PORT,
62*83ee113eSDavid van Moolenbroek ldap_method = LDAP_METHOD_DYNAMIC,
63*83ee113eSDavid van Moolenbroek ldap_referrals = -1,
64*83ee113eSDavid van Moolenbroek ldap_debug_fd = -1;
65*83ee113eSDavid van Moolenbroek #if defined (LDAP_USE_SSL)
66*83ee113eSDavid van Moolenbroek static int ldap_use_ssl = -1, /* try TLS if possible */
67*83ee113eSDavid van Moolenbroek ldap_tls_reqcert = -1,
68*83ee113eSDavid van Moolenbroek ldap_tls_crlcheck = -1;
69*83ee113eSDavid van Moolenbroek static char *ldap_tls_ca_file = NULL,
70*83ee113eSDavid van Moolenbroek *ldap_tls_ca_dir = NULL,
71*83ee113eSDavid van Moolenbroek *ldap_tls_cert = NULL,
72*83ee113eSDavid van Moolenbroek *ldap_tls_key = NULL,
73*83ee113eSDavid van Moolenbroek *ldap_tls_ciphers = NULL,
74*83ee113eSDavid van Moolenbroek *ldap_tls_randfile = NULL;
75*83ee113eSDavid van Moolenbroek #endif
76*83ee113eSDavid van Moolenbroek static struct ldap_config_stack *ldap_stack = NULL;
77*83ee113eSDavid van Moolenbroek
78*83ee113eSDavid van Moolenbroek typedef struct ldap_dn_node {
79*83ee113eSDavid van Moolenbroek struct ldap_dn_node *next;
80*83ee113eSDavid van Moolenbroek size_t refs;
81*83ee113eSDavid van Moolenbroek char *dn;
82*83ee113eSDavid van Moolenbroek } ldap_dn_node;
83*83ee113eSDavid van Moolenbroek
84*83ee113eSDavid van Moolenbroek static ldap_dn_node *ldap_service_dn_head = NULL;
85*83ee113eSDavid van Moolenbroek static ldap_dn_node *ldap_service_dn_tail = NULL;
86*83ee113eSDavid van Moolenbroek
87*83ee113eSDavid van Moolenbroek
88*83ee113eSDavid van Moolenbroek static char *
x_strncat(char * dst,const char * src,size_t dst_size)89*83ee113eSDavid van Moolenbroek x_strncat(char *dst, const char *src, size_t dst_size)
90*83ee113eSDavid van Moolenbroek {
91*83ee113eSDavid van Moolenbroek size_t len = strlen(dst);
92*83ee113eSDavid van Moolenbroek return strncat(dst, src, dst_size > len ? dst_size - len - 1: 0);
93*83ee113eSDavid van Moolenbroek }
94*83ee113eSDavid van Moolenbroek
95*83ee113eSDavid van Moolenbroek static void
ldap_parse_class(struct ldap_config_stack * item,struct parse * cfile)96*83ee113eSDavid van Moolenbroek ldap_parse_class (struct ldap_config_stack *item, struct parse *cfile)
97*83ee113eSDavid van Moolenbroek {
98*83ee113eSDavid van Moolenbroek struct berval **tempbv;
99*83ee113eSDavid van Moolenbroek
100*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
101*83ee113eSDavid van Moolenbroek tempbv[0] == NULL)
102*83ee113eSDavid van Moolenbroek {
103*83ee113eSDavid van Moolenbroek if (tempbv != NULL)
104*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
105*83ee113eSDavid van Moolenbroek
106*83ee113eSDavid van Moolenbroek return;
107*83ee113eSDavid van Moolenbroek }
108*83ee113eSDavid van Moolenbroek
109*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "class \"", LDAP_BUFFER_SIZE);
110*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
111*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "\" {\n", LDAP_BUFFER_SIZE);
112*83ee113eSDavid van Moolenbroek
113*83ee113eSDavid van Moolenbroek item->close_brace = 1;
114*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
115*83ee113eSDavid van Moolenbroek }
116*83ee113eSDavid van Moolenbroek
117*83ee113eSDavid van Moolenbroek
118*83ee113eSDavid van Moolenbroek static void
ldap_parse_subclass(struct ldap_config_stack * item,struct parse * cfile)119*83ee113eSDavid van Moolenbroek ldap_parse_subclass (struct ldap_config_stack *item, struct parse *cfile)
120*83ee113eSDavid van Moolenbroek {
121*83ee113eSDavid van Moolenbroek struct berval **tempbv, **classdata;
122*83ee113eSDavid van Moolenbroek
123*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
124*83ee113eSDavid van Moolenbroek tempbv[0] == NULL)
125*83ee113eSDavid van Moolenbroek {
126*83ee113eSDavid van Moolenbroek if (tempbv != NULL)
127*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
128*83ee113eSDavid van Moolenbroek
129*83ee113eSDavid van Moolenbroek return;
130*83ee113eSDavid van Moolenbroek }
131*83ee113eSDavid van Moolenbroek
132*83ee113eSDavid van Moolenbroek if ((classdata = ldap_get_values_len (ld, item->ldent,
133*83ee113eSDavid van Moolenbroek "dhcpClassData")) == NULL ||
134*83ee113eSDavid van Moolenbroek classdata[0] == NULL)
135*83ee113eSDavid van Moolenbroek {
136*83ee113eSDavid van Moolenbroek if (classdata != NULL)
137*83ee113eSDavid van Moolenbroek ldap_value_free_len (classdata);
138*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
139*83ee113eSDavid van Moolenbroek
140*83ee113eSDavid van Moolenbroek return;
141*83ee113eSDavid van Moolenbroek }
142*83ee113eSDavid van Moolenbroek
143*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "subclass ", LDAP_BUFFER_SIZE);
144*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, classdata[0]->bv_val, LDAP_BUFFER_SIZE);
145*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
146*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
147*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
148*83ee113eSDavid van Moolenbroek
149*83ee113eSDavid van Moolenbroek item->close_brace = 1;
150*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
151*83ee113eSDavid van Moolenbroek ldap_value_free_len (classdata);
152*83ee113eSDavid van Moolenbroek }
153*83ee113eSDavid van Moolenbroek
154*83ee113eSDavid van Moolenbroek
155*83ee113eSDavid van Moolenbroek static void
ldap_parse_host(struct ldap_config_stack * item,struct parse * cfile)156*83ee113eSDavid van Moolenbroek ldap_parse_host (struct ldap_config_stack *item, struct parse *cfile)
157*83ee113eSDavid van Moolenbroek {
158*83ee113eSDavid van Moolenbroek struct berval **tempbv, **hwaddr;
159*83ee113eSDavid van Moolenbroek
160*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
161*83ee113eSDavid van Moolenbroek tempbv[0] == NULL)
162*83ee113eSDavid van Moolenbroek {
163*83ee113eSDavid van Moolenbroek if (tempbv != NULL)
164*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
165*83ee113eSDavid van Moolenbroek
166*83ee113eSDavid van Moolenbroek return;
167*83ee113eSDavid van Moolenbroek }
168*83ee113eSDavid van Moolenbroek
169*83ee113eSDavid van Moolenbroek hwaddr = ldap_get_values_len (ld, item->ldent, "dhcpHWAddress");
170*83ee113eSDavid van Moolenbroek
171*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "host ", LDAP_BUFFER_SIZE);
172*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
173*83ee113eSDavid van Moolenbroek
174*83ee113eSDavid van Moolenbroek if (hwaddr != NULL && hwaddr[0] != NULL)
175*83ee113eSDavid van Moolenbroek {
176*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, " {\nhardware ", LDAP_BUFFER_SIZE);
177*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, hwaddr[0]->bv_val, LDAP_BUFFER_SIZE);
178*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
179*83ee113eSDavid van Moolenbroek ldap_value_free_len (hwaddr);
180*83ee113eSDavid van Moolenbroek }
181*83ee113eSDavid van Moolenbroek
182*83ee113eSDavid van Moolenbroek item->close_brace = 1;
183*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
184*83ee113eSDavid van Moolenbroek }
185*83ee113eSDavid van Moolenbroek
186*83ee113eSDavid van Moolenbroek
187*83ee113eSDavid van Moolenbroek static void
ldap_parse_shared_network(struct ldap_config_stack * item,struct parse * cfile)188*83ee113eSDavid van Moolenbroek ldap_parse_shared_network (struct ldap_config_stack *item, struct parse *cfile)
189*83ee113eSDavid van Moolenbroek {
190*83ee113eSDavid van Moolenbroek struct berval **tempbv;
191*83ee113eSDavid van Moolenbroek
192*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
193*83ee113eSDavid van Moolenbroek tempbv[0] == NULL)
194*83ee113eSDavid van Moolenbroek {
195*83ee113eSDavid van Moolenbroek if (tempbv != NULL)
196*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
197*83ee113eSDavid van Moolenbroek
198*83ee113eSDavid van Moolenbroek return;
199*83ee113eSDavid van Moolenbroek }
200*83ee113eSDavid van Moolenbroek
201*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "shared-network \"", LDAP_BUFFER_SIZE);
202*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
203*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "\" {\n", LDAP_BUFFER_SIZE);
204*83ee113eSDavid van Moolenbroek
205*83ee113eSDavid van Moolenbroek item->close_brace = 1;
206*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
207*83ee113eSDavid van Moolenbroek }
208*83ee113eSDavid van Moolenbroek
209*83ee113eSDavid van Moolenbroek
210*83ee113eSDavid van Moolenbroek static void
parse_netmask(int netmask,char * netmaskbuf)211*83ee113eSDavid van Moolenbroek parse_netmask (int netmask, char *netmaskbuf)
212*83ee113eSDavid van Moolenbroek {
213*83ee113eSDavid van Moolenbroek unsigned long nm;
214*83ee113eSDavid van Moolenbroek int i;
215*83ee113eSDavid van Moolenbroek
216*83ee113eSDavid van Moolenbroek nm = 0;
217*83ee113eSDavid van Moolenbroek for (i=1; i <= netmask; i++)
218*83ee113eSDavid van Moolenbroek {
219*83ee113eSDavid van Moolenbroek nm |= 1 << (32 - i);
220*83ee113eSDavid van Moolenbroek }
221*83ee113eSDavid van Moolenbroek
222*83ee113eSDavid van Moolenbroek sprintf (netmaskbuf, "%d.%d.%d.%d", (int) (nm >> 24) & 0xff,
223*83ee113eSDavid van Moolenbroek (int) (nm >> 16) & 0xff,
224*83ee113eSDavid van Moolenbroek (int) (nm >> 8) & 0xff,
225*83ee113eSDavid van Moolenbroek (int) nm & 0xff);
226*83ee113eSDavid van Moolenbroek }
227*83ee113eSDavid van Moolenbroek
228*83ee113eSDavid van Moolenbroek
229*83ee113eSDavid van Moolenbroek static void
ldap_parse_subnet(struct ldap_config_stack * item,struct parse * cfile)230*83ee113eSDavid van Moolenbroek ldap_parse_subnet (struct ldap_config_stack *item, struct parse *cfile)
231*83ee113eSDavid van Moolenbroek {
232*83ee113eSDavid van Moolenbroek struct berval **tempbv, **netmaskstr;
233*83ee113eSDavid van Moolenbroek char netmaskbuf[sizeof("255.255.255.255")];
234*83ee113eSDavid van Moolenbroek int i;
235*83ee113eSDavid van Moolenbroek
236*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
237*83ee113eSDavid van Moolenbroek tempbv[0] == NULL)
238*83ee113eSDavid van Moolenbroek {
239*83ee113eSDavid van Moolenbroek if (tempbv != NULL)
240*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
241*83ee113eSDavid van Moolenbroek
242*83ee113eSDavid van Moolenbroek return;
243*83ee113eSDavid van Moolenbroek }
244*83ee113eSDavid van Moolenbroek
245*83ee113eSDavid van Moolenbroek if ((netmaskstr = ldap_get_values_len (ld, item->ldent,
246*83ee113eSDavid van Moolenbroek "dhcpNetmask")) == NULL ||
247*83ee113eSDavid van Moolenbroek netmaskstr[0] == NULL)
248*83ee113eSDavid van Moolenbroek {
249*83ee113eSDavid van Moolenbroek if (netmaskstr != NULL)
250*83ee113eSDavid van Moolenbroek ldap_value_free_len (netmaskstr);
251*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
252*83ee113eSDavid van Moolenbroek
253*83ee113eSDavid van Moolenbroek return;
254*83ee113eSDavid van Moolenbroek }
255*83ee113eSDavid van Moolenbroek
256*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "subnet ", LDAP_BUFFER_SIZE);
257*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
258*83ee113eSDavid van Moolenbroek
259*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, " netmask ", LDAP_BUFFER_SIZE);
260*83ee113eSDavid van Moolenbroek parse_netmask (strtol (netmaskstr[0]->bv_val, NULL, 10), netmaskbuf);
261*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, netmaskbuf, LDAP_BUFFER_SIZE);
262*83ee113eSDavid van Moolenbroek
263*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
264*83ee113eSDavid van Moolenbroek
265*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
266*83ee113eSDavid van Moolenbroek ldap_value_free_len (netmaskstr);
267*83ee113eSDavid van Moolenbroek
268*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpRange")) != NULL)
269*83ee113eSDavid van Moolenbroek {
270*83ee113eSDavid van Moolenbroek for (i=0; tempbv[i] != NULL; i++)
271*83ee113eSDavid van Moolenbroek {
272*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE);
273*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
274*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, tempbv[i]->bv_val, LDAP_BUFFER_SIZE);
275*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
276*83ee113eSDavid van Moolenbroek }
277*83ee113eSDavid van Moolenbroek }
278*83ee113eSDavid van Moolenbroek
279*83ee113eSDavid van Moolenbroek item->close_brace = 1;
280*83ee113eSDavid van Moolenbroek }
281*83ee113eSDavid van Moolenbroek
282*83ee113eSDavid van Moolenbroek
283*83ee113eSDavid van Moolenbroek static void
ldap_parse_pool(struct ldap_config_stack * item,struct parse * cfile)284*83ee113eSDavid van Moolenbroek ldap_parse_pool (struct ldap_config_stack *item, struct parse *cfile)
285*83ee113eSDavid van Moolenbroek {
286*83ee113eSDavid van Moolenbroek struct berval **tempbv;
287*83ee113eSDavid van Moolenbroek int i;
288*83ee113eSDavid van Moolenbroek
289*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "pool {\n", LDAP_BUFFER_SIZE);
290*83ee113eSDavid van Moolenbroek
291*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpRange")) != NULL)
292*83ee113eSDavid van Moolenbroek {
293*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE);
294*83ee113eSDavid van Moolenbroek for (i=0; tempbv[i] != NULL; i++)
295*83ee113eSDavid van Moolenbroek {
296*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
297*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, tempbv[i]->bv_val, LDAP_BUFFER_SIZE);
298*83ee113eSDavid van Moolenbroek }
299*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
300*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
301*83ee113eSDavid van Moolenbroek }
302*83ee113eSDavid van Moolenbroek
303*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpPermitList")) != NULL)
304*83ee113eSDavid van Moolenbroek {
305*83ee113eSDavid van Moolenbroek for (i=0; tempbv[i] != NULL; i++)
306*83ee113eSDavid van Moolenbroek {
307*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, tempbv[i]->bv_val, LDAP_BUFFER_SIZE);
308*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
309*83ee113eSDavid van Moolenbroek }
310*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
311*83ee113eSDavid van Moolenbroek }
312*83ee113eSDavid van Moolenbroek
313*83ee113eSDavid van Moolenbroek item->close_brace = 1;
314*83ee113eSDavid van Moolenbroek }
315*83ee113eSDavid van Moolenbroek
316*83ee113eSDavid van Moolenbroek
317*83ee113eSDavid van Moolenbroek static void
ldap_parse_group(struct ldap_config_stack * item,struct parse * cfile)318*83ee113eSDavid van Moolenbroek ldap_parse_group (struct ldap_config_stack *item, struct parse *cfile)
319*83ee113eSDavid van Moolenbroek {
320*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "group {\n", LDAP_BUFFER_SIZE);
321*83ee113eSDavid van Moolenbroek item->close_brace = 1;
322*83ee113eSDavid van Moolenbroek }
323*83ee113eSDavid van Moolenbroek
324*83ee113eSDavid van Moolenbroek
325*83ee113eSDavid van Moolenbroek static void
ldap_parse_key(struct ldap_config_stack * item,struct parse * cfile)326*83ee113eSDavid van Moolenbroek ldap_parse_key (struct ldap_config_stack *item, struct parse *cfile)
327*83ee113eSDavid van Moolenbroek {
328*83ee113eSDavid van Moolenbroek struct berval **tempbv;
329*83ee113eSDavid van Moolenbroek
330*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) != NULL)
331*83ee113eSDavid van Moolenbroek {
332*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "key ", LDAP_BUFFER_SIZE);
333*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
334*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
335*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
336*83ee113eSDavid van Moolenbroek }
337*83ee113eSDavid van Moolenbroek
338*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpKeyAlgorithm")) != NULL)
339*83ee113eSDavid van Moolenbroek {
340*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "algorithm ", LDAP_BUFFER_SIZE);
341*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
342*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
343*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
344*83ee113eSDavid van Moolenbroek }
345*83ee113eSDavid van Moolenbroek
346*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpKeySecret")) != NULL)
347*83ee113eSDavid van Moolenbroek {
348*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "secret ", LDAP_BUFFER_SIZE);
349*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
350*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
351*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
352*83ee113eSDavid van Moolenbroek }
353*83ee113eSDavid van Moolenbroek
354*83ee113eSDavid van Moolenbroek item->close_brace = 1;
355*83ee113eSDavid van Moolenbroek }
356*83ee113eSDavid van Moolenbroek
357*83ee113eSDavid van Moolenbroek
358*83ee113eSDavid van Moolenbroek static void
ldap_parse_zone(struct ldap_config_stack * item,struct parse * cfile)359*83ee113eSDavid van Moolenbroek ldap_parse_zone (struct ldap_config_stack *item, struct parse *cfile)
360*83ee113eSDavid van Moolenbroek {
361*83ee113eSDavid van Moolenbroek char *cnFindStart, *cnFindEnd;
362*83ee113eSDavid van Moolenbroek struct berval **tempbv;
363*83ee113eSDavid van Moolenbroek char *keyCn;
364*83ee113eSDavid van Moolenbroek size_t len;
365*83ee113eSDavid van Moolenbroek
366*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "cn")) != NULL)
367*83ee113eSDavid van Moolenbroek {
368*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "zone ", LDAP_BUFFER_SIZE);
369*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
370*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
371*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
372*83ee113eSDavid van Moolenbroek }
373*83ee113eSDavid van Moolenbroek
374*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpDnsZoneServer")) != NULL)
375*83ee113eSDavid van Moolenbroek {
376*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "primary ", LDAP_BUFFER_SIZE);
377*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, tempbv[0]->bv_val, LDAP_BUFFER_SIZE);
378*83ee113eSDavid van Moolenbroek
379*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
380*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
381*83ee113eSDavid van Moolenbroek }
382*83ee113eSDavid van Moolenbroek
383*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, item->ldent, "dhcpKeyDN")) != NULL)
384*83ee113eSDavid van Moolenbroek {
385*83ee113eSDavid van Moolenbroek cnFindStart = strchr(tempbv[0]->bv_val,'=');
386*83ee113eSDavid van Moolenbroek if (cnFindStart != NULL)
387*83ee113eSDavid van Moolenbroek cnFindEnd = strchr(++cnFindStart,',');
388*83ee113eSDavid van Moolenbroek else
389*83ee113eSDavid van Moolenbroek cnFindEnd = NULL;
390*83ee113eSDavid van Moolenbroek
391*83ee113eSDavid van Moolenbroek if (cnFindEnd != NULL && cnFindEnd > cnFindStart)
392*83ee113eSDavid van Moolenbroek {
393*83ee113eSDavid van Moolenbroek len = cnFindEnd - cnFindStart;
394*83ee113eSDavid van Moolenbroek keyCn = dmalloc (len + 1, MDL);
395*83ee113eSDavid van Moolenbroek }
396*83ee113eSDavid van Moolenbroek else
397*83ee113eSDavid van Moolenbroek {
398*83ee113eSDavid van Moolenbroek len = 0;
399*83ee113eSDavid van Moolenbroek keyCn = NULL;
400*83ee113eSDavid van Moolenbroek }
401*83ee113eSDavid van Moolenbroek
402*83ee113eSDavid van Moolenbroek if (keyCn != NULL)
403*83ee113eSDavid van Moolenbroek {
404*83ee113eSDavid van Moolenbroek strncpy (keyCn, cnFindStart, len);
405*83ee113eSDavid van Moolenbroek keyCn[len] = '\0';
406*83ee113eSDavid van Moolenbroek
407*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "key ", LDAP_BUFFER_SIZE);
408*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, keyCn, LDAP_BUFFER_SIZE);
409*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
410*83ee113eSDavid van Moolenbroek
411*83ee113eSDavid van Moolenbroek dfree (keyCn, MDL);
412*83ee113eSDavid van Moolenbroek }
413*83ee113eSDavid van Moolenbroek
414*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
415*83ee113eSDavid van Moolenbroek }
416*83ee113eSDavid van Moolenbroek
417*83ee113eSDavid van Moolenbroek item->close_brace = 1;
418*83ee113eSDavid van Moolenbroek }
419*83ee113eSDavid van Moolenbroek
420*83ee113eSDavid van Moolenbroek
421*83ee113eSDavid van Moolenbroek static void
add_to_config_stack(LDAPMessage * res,LDAPMessage * ent)422*83ee113eSDavid van Moolenbroek add_to_config_stack (LDAPMessage * res, LDAPMessage * ent)
423*83ee113eSDavid van Moolenbroek {
424*83ee113eSDavid van Moolenbroek struct ldap_config_stack *ns;
425*83ee113eSDavid van Moolenbroek
426*83ee113eSDavid van Moolenbroek ns = dmalloc (sizeof (*ns), MDL);
427*83ee113eSDavid van Moolenbroek ns->res = res;
428*83ee113eSDavid van Moolenbroek ns->ldent = ent;
429*83ee113eSDavid van Moolenbroek ns->close_brace = 0;
430*83ee113eSDavid van Moolenbroek ns->processed = 0;
431*83ee113eSDavid van Moolenbroek ns->next = ldap_stack;
432*83ee113eSDavid van Moolenbroek ldap_stack = ns;
433*83ee113eSDavid van Moolenbroek }
434*83ee113eSDavid van Moolenbroek
435*83ee113eSDavid van Moolenbroek
436*83ee113eSDavid van Moolenbroek static void
ldap_stop()437*83ee113eSDavid van Moolenbroek ldap_stop()
438*83ee113eSDavid van Moolenbroek {
439*83ee113eSDavid van Moolenbroek struct sigaction old, new;
440*83ee113eSDavid van Moolenbroek
441*83ee113eSDavid van Moolenbroek if (ld == NULL)
442*83ee113eSDavid van Moolenbroek return;
443*83ee113eSDavid van Moolenbroek
444*83ee113eSDavid van Moolenbroek /*
445*83ee113eSDavid van Moolenbroek ** ldap_unbind after a LDAP_SERVER_DOWN result
446*83ee113eSDavid van Moolenbroek ** causes a SIGPIPE and dhcpd gets terminated,
447*83ee113eSDavid van Moolenbroek ** since it doesn't handle it...
448*83ee113eSDavid van Moolenbroek */
449*83ee113eSDavid van Moolenbroek
450*83ee113eSDavid van Moolenbroek new.sa_flags = 0;
451*83ee113eSDavid van Moolenbroek new.sa_handler = SIG_IGN;
452*83ee113eSDavid van Moolenbroek sigemptyset (&new.sa_mask);
453*83ee113eSDavid van Moolenbroek sigaction (SIGPIPE, &new, &old);
454*83ee113eSDavid van Moolenbroek
455*83ee113eSDavid van Moolenbroek ldap_unbind_ext_s (ld, NULL, NULL);
456*83ee113eSDavid van Moolenbroek ld = NULL;
457*83ee113eSDavid van Moolenbroek
458*83ee113eSDavid van Moolenbroek sigaction (SIGPIPE, &old, &new);
459*83ee113eSDavid van Moolenbroek }
460*83ee113eSDavid van Moolenbroek
461*83ee113eSDavid van Moolenbroek
462*83ee113eSDavid van Moolenbroek static char *
_do_lookup_dhcp_string_option(struct option_state * options,int option_name)463*83ee113eSDavid van Moolenbroek _do_lookup_dhcp_string_option (struct option_state *options, int option_name)
464*83ee113eSDavid van Moolenbroek {
465*83ee113eSDavid van Moolenbroek struct option_cache *oc;
466*83ee113eSDavid van Moolenbroek struct data_string db;
467*83ee113eSDavid van Moolenbroek char *ret;
468*83ee113eSDavid van Moolenbroek
469*83ee113eSDavid van Moolenbroek memset (&db, 0, sizeof (db));
470*83ee113eSDavid van Moolenbroek oc = lookup_option (&server_universe, options, option_name);
471*83ee113eSDavid van Moolenbroek if (oc &&
472*83ee113eSDavid van Moolenbroek evaluate_option_cache (&db, (struct packet*) NULL,
473*83ee113eSDavid van Moolenbroek (struct lease *) NULL,
474*83ee113eSDavid van Moolenbroek (struct client_state *) NULL, options,
475*83ee113eSDavid van Moolenbroek (struct option_state *) NULL,
476*83ee113eSDavid van Moolenbroek &global_scope, oc, MDL) &&
477*83ee113eSDavid van Moolenbroek db.data != NULL && *db.data != '\0')
478*83ee113eSDavid van Moolenbroek
479*83ee113eSDavid van Moolenbroek {
480*83ee113eSDavid van Moolenbroek ret = dmalloc (db.len + 1, MDL);
481*83ee113eSDavid van Moolenbroek if (ret == NULL)
482*83ee113eSDavid van Moolenbroek log_fatal ("no memory for ldap option %d value", option_name);
483*83ee113eSDavid van Moolenbroek
484*83ee113eSDavid van Moolenbroek memcpy (ret, db.data, db.len);
485*83ee113eSDavid van Moolenbroek ret[db.len] = 0;
486*83ee113eSDavid van Moolenbroek data_string_forget (&db, MDL);
487*83ee113eSDavid van Moolenbroek }
488*83ee113eSDavid van Moolenbroek else
489*83ee113eSDavid van Moolenbroek ret = NULL;
490*83ee113eSDavid van Moolenbroek
491*83ee113eSDavid van Moolenbroek return (ret);
492*83ee113eSDavid van Moolenbroek }
493*83ee113eSDavid van Moolenbroek
494*83ee113eSDavid van Moolenbroek
495*83ee113eSDavid van Moolenbroek static int
_do_lookup_dhcp_int_option(struct option_state * options,int option_name)496*83ee113eSDavid van Moolenbroek _do_lookup_dhcp_int_option (struct option_state *options, int option_name)
497*83ee113eSDavid van Moolenbroek {
498*83ee113eSDavid van Moolenbroek struct option_cache *oc;
499*83ee113eSDavid van Moolenbroek struct data_string db;
500*83ee113eSDavid van Moolenbroek int ret;
501*83ee113eSDavid van Moolenbroek
502*83ee113eSDavid van Moolenbroek memset (&db, 0, sizeof (db));
503*83ee113eSDavid van Moolenbroek oc = lookup_option (&server_universe, options, option_name);
504*83ee113eSDavid van Moolenbroek if (oc &&
505*83ee113eSDavid van Moolenbroek evaluate_option_cache (&db, (struct packet*) NULL,
506*83ee113eSDavid van Moolenbroek (struct lease *) NULL,
507*83ee113eSDavid van Moolenbroek (struct client_state *) NULL, options,
508*83ee113eSDavid van Moolenbroek (struct option_state *) NULL,
509*83ee113eSDavid van Moolenbroek &global_scope, oc, MDL) &&
510*83ee113eSDavid van Moolenbroek db.data != NULL && *db.data != '\0')
511*83ee113eSDavid van Moolenbroek {
512*83ee113eSDavid van Moolenbroek ret = strtol ((const char *) db.data, NULL, 10);
513*83ee113eSDavid van Moolenbroek data_string_forget (&db, MDL);
514*83ee113eSDavid van Moolenbroek }
515*83ee113eSDavid van Moolenbroek else
516*83ee113eSDavid van Moolenbroek ret = 0;
517*83ee113eSDavid van Moolenbroek
518*83ee113eSDavid van Moolenbroek return (ret);
519*83ee113eSDavid van Moolenbroek }
520*83ee113eSDavid van Moolenbroek
521*83ee113eSDavid van Moolenbroek
522*83ee113eSDavid van Moolenbroek static int
_do_lookup_dhcp_enum_option(struct option_state * options,int option_name)523*83ee113eSDavid van Moolenbroek _do_lookup_dhcp_enum_option (struct option_state *options, int option_name)
524*83ee113eSDavid van Moolenbroek {
525*83ee113eSDavid van Moolenbroek struct option_cache *oc;
526*83ee113eSDavid van Moolenbroek struct data_string db;
527*83ee113eSDavid van Moolenbroek int ret = -1;
528*83ee113eSDavid van Moolenbroek
529*83ee113eSDavid van Moolenbroek memset (&db, 0, sizeof (db));
530*83ee113eSDavid van Moolenbroek oc = lookup_option (&server_universe, options, option_name);
531*83ee113eSDavid van Moolenbroek if (oc &&
532*83ee113eSDavid van Moolenbroek evaluate_option_cache (&db, (struct packet*) NULL,
533*83ee113eSDavid van Moolenbroek (struct lease *) NULL,
534*83ee113eSDavid van Moolenbroek (struct client_state *) NULL, options,
535*83ee113eSDavid van Moolenbroek (struct option_state *) NULL,
536*83ee113eSDavid van Moolenbroek &global_scope, oc, MDL) &&
537*83ee113eSDavid van Moolenbroek db.data != NULL && *db.data != '\0')
538*83ee113eSDavid van Moolenbroek {
539*83ee113eSDavid van Moolenbroek if (db.len == 1)
540*83ee113eSDavid van Moolenbroek ret = db.data [0];
541*83ee113eSDavid van Moolenbroek else
542*83ee113eSDavid van Moolenbroek log_fatal ("invalid option name %d", option_name);
543*83ee113eSDavid van Moolenbroek
544*83ee113eSDavid van Moolenbroek data_string_forget (&db, MDL);
545*83ee113eSDavid van Moolenbroek }
546*83ee113eSDavid van Moolenbroek else
547*83ee113eSDavid van Moolenbroek ret = 0;
548*83ee113eSDavid van Moolenbroek
549*83ee113eSDavid van Moolenbroek return (ret);
550*83ee113eSDavid van Moolenbroek }
551*83ee113eSDavid van Moolenbroek
552*83ee113eSDavid van Moolenbroek int
ldap_rebind_cb(LDAP * ld,LDAP_CONST char * url,ber_tag_t request,ber_int_t msgid,void * parms)553*83ee113eSDavid van Moolenbroek ldap_rebind_cb (LDAP *ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *parms)
554*83ee113eSDavid van Moolenbroek {
555*83ee113eSDavid van Moolenbroek int ret;
556*83ee113eSDavid van Moolenbroek LDAPURLDesc *ldapurl = NULL;
557*83ee113eSDavid van Moolenbroek char *who = NULL;
558*83ee113eSDavid van Moolenbroek struct berval creds;
559*83ee113eSDavid van Moolenbroek
560*83ee113eSDavid van Moolenbroek log_info("LDAP rebind to '%s'", url);
561*83ee113eSDavid van Moolenbroek if ((ret = ldap_url_parse(url, &ldapurl)) != LDAP_SUCCESS)
562*83ee113eSDavid van Moolenbroek {
563*83ee113eSDavid van Moolenbroek log_error ("Error: Can not parse ldap rebind url '%s': %s",
564*83ee113eSDavid van Moolenbroek url, ldap_err2string(ret));
565*83ee113eSDavid van Moolenbroek return ret;
566*83ee113eSDavid van Moolenbroek }
567*83ee113eSDavid van Moolenbroek
568*83ee113eSDavid van Moolenbroek
569*83ee113eSDavid van Moolenbroek #if defined (LDAP_USE_SSL)
570*83ee113eSDavid van Moolenbroek if (strcasecmp(ldapurl->lud_scheme, "ldaps") == 0)
571*83ee113eSDavid van Moolenbroek {
572*83ee113eSDavid van Moolenbroek int opt = LDAP_OPT_X_TLS_HARD;
573*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_option (ld, LDAP_OPT_X_TLS, &opt)) != LDAP_SUCCESS)
574*83ee113eSDavid van Moolenbroek {
575*83ee113eSDavid van Moolenbroek log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
576*83ee113eSDavid van Moolenbroek ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret));
577*83ee113eSDavid van Moolenbroek return ret;
578*83ee113eSDavid van Moolenbroek }
579*83ee113eSDavid van Moolenbroek else
580*83ee113eSDavid van Moolenbroek {
581*83ee113eSDavid van Moolenbroek log_info ("LDAPS session successfully enabled to %s", ldap_server);
582*83ee113eSDavid van Moolenbroek }
583*83ee113eSDavid van Moolenbroek }
584*83ee113eSDavid van Moolenbroek else
585*83ee113eSDavid van Moolenbroek if (strcasecmp(ldapurl->lud_scheme, "ldap") == 0 &&
586*83ee113eSDavid van Moolenbroek ldap_use_ssl != LDAP_SSL_OFF)
587*83ee113eSDavid van Moolenbroek {
588*83ee113eSDavid van Moolenbroek if ((ret = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS)
589*83ee113eSDavid van Moolenbroek {
590*83ee113eSDavid van Moolenbroek log_error ("Error: Cannot start TLS session to %s:%d: %s",
591*83ee113eSDavid van Moolenbroek ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret));
592*83ee113eSDavid van Moolenbroek return ret;
593*83ee113eSDavid van Moolenbroek }
594*83ee113eSDavid van Moolenbroek else
595*83ee113eSDavid van Moolenbroek {
596*83ee113eSDavid van Moolenbroek log_info ("TLS session successfully started to %s:%d",
597*83ee113eSDavid van Moolenbroek ldapurl->lud_host, ldapurl->lud_port);
598*83ee113eSDavid van Moolenbroek }
599*83ee113eSDavid van Moolenbroek }
600*83ee113eSDavid van Moolenbroek #endif
601*83ee113eSDavid van Moolenbroek
602*83ee113eSDavid van Moolenbroek
603*83ee113eSDavid van Moolenbroek if (ldap_username != NULL || *ldap_username != '\0')
604*83ee113eSDavid van Moolenbroek {
605*83ee113eSDavid van Moolenbroek who = ldap_username;
606*83ee113eSDavid van Moolenbroek creds.bv_val = strdup(ldap_password);
607*83ee113eSDavid van Moolenbroek creds.bv_len = strlen(ldap_password);
608*83ee113eSDavid van Moolenbroek }
609*83ee113eSDavid van Moolenbroek
610*83ee113eSDavid van Moolenbroek if ((ret = ldap_sasl_bind_s (ld, who, LDAP_SASL_SIMPLE, &creds,
611*83ee113eSDavid van Moolenbroek NULL, NULL, NULL)) != LDAP_SUCCESS)
612*83ee113eSDavid van Moolenbroek {
613*83ee113eSDavid van Moolenbroek log_error ("Error: Cannot login into ldap server %s:%d: %s",
614*83ee113eSDavid van Moolenbroek ldapurl->lud_host, ldapurl->lud_port, ldap_err2string (ret));
615*83ee113eSDavid van Moolenbroek }
616*83ee113eSDavid van Moolenbroek return ret;
617*83ee113eSDavid van Moolenbroek }
618*83ee113eSDavid van Moolenbroek
619*83ee113eSDavid van Moolenbroek static void
ldap_start(void)620*83ee113eSDavid van Moolenbroek ldap_start (void)
621*83ee113eSDavid van Moolenbroek {
622*83ee113eSDavid van Moolenbroek struct option_state *options;
623*83ee113eSDavid van Moolenbroek int ret, version;
624*83ee113eSDavid van Moolenbroek char *uri = NULL;
625*83ee113eSDavid van Moolenbroek struct berval creds;
626*83ee113eSDavid van Moolenbroek
627*83ee113eSDavid van Moolenbroek if (ld != NULL)
628*83ee113eSDavid van Moolenbroek return;
629*83ee113eSDavid van Moolenbroek
630*83ee113eSDavid van Moolenbroek if (ldap_server == NULL)
631*83ee113eSDavid van Moolenbroek {
632*83ee113eSDavid van Moolenbroek options = NULL;
633*83ee113eSDavid van Moolenbroek option_state_allocate (&options, MDL);
634*83ee113eSDavid van Moolenbroek
635*83ee113eSDavid van Moolenbroek execute_statements_in_scope (NULL, NULL, NULL, NULL, NULL,
636*83ee113eSDavid van Moolenbroek options, &global_scope, root_group,
637*83ee113eSDavid van Moolenbroek NULL, NULL);
638*83ee113eSDavid van Moolenbroek
639*83ee113eSDavid van Moolenbroek ldap_server = _do_lookup_dhcp_string_option (options, SV_LDAP_SERVER);
640*83ee113eSDavid van Moolenbroek ldap_dhcp_server_cn = _do_lookup_dhcp_string_option (options,
641*83ee113eSDavid van Moolenbroek SV_LDAP_DHCP_SERVER_CN);
642*83ee113eSDavid van Moolenbroek ldap_port = _do_lookup_dhcp_int_option (options, SV_LDAP_PORT);
643*83ee113eSDavid van Moolenbroek ldap_base_dn = _do_lookup_dhcp_string_option (options, SV_LDAP_BASE_DN);
644*83ee113eSDavid van Moolenbroek ldap_method = _do_lookup_dhcp_enum_option (options, SV_LDAP_METHOD);
645*83ee113eSDavid van Moolenbroek ldap_debug_file = _do_lookup_dhcp_string_option (options,
646*83ee113eSDavid van Moolenbroek SV_LDAP_DEBUG_FILE);
647*83ee113eSDavid van Moolenbroek ldap_referrals = _do_lookup_dhcp_enum_option (options, SV_LDAP_REFERRALS);
648*83ee113eSDavid van Moolenbroek
649*83ee113eSDavid van Moolenbroek #if defined (LDAP_USE_SSL)
650*83ee113eSDavid van Moolenbroek ldap_use_ssl = _do_lookup_dhcp_enum_option (options, SV_LDAP_SSL);
651*83ee113eSDavid van Moolenbroek if( ldap_use_ssl != LDAP_SSL_OFF)
652*83ee113eSDavid van Moolenbroek {
653*83ee113eSDavid van Moolenbroek ldap_tls_reqcert = _do_lookup_dhcp_enum_option (options, SV_LDAP_TLS_REQCERT);
654*83ee113eSDavid van Moolenbroek ldap_tls_ca_file = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CA_FILE);
655*83ee113eSDavid van Moolenbroek ldap_tls_ca_dir = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CA_DIR);
656*83ee113eSDavid van Moolenbroek ldap_tls_cert = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CERT);
657*83ee113eSDavid van Moolenbroek ldap_tls_key = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_KEY);
658*83ee113eSDavid van Moolenbroek ldap_tls_crlcheck = _do_lookup_dhcp_enum_option (options, SV_LDAP_TLS_CRLCHECK);
659*83ee113eSDavid van Moolenbroek ldap_tls_ciphers = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_CIPHERS);
660*83ee113eSDavid van Moolenbroek ldap_tls_randfile = _do_lookup_dhcp_string_option (options, SV_LDAP_TLS_RANDFILE);
661*83ee113eSDavid van Moolenbroek }
662*83ee113eSDavid van Moolenbroek #endif
663*83ee113eSDavid van Moolenbroek
664*83ee113eSDavid van Moolenbroek #if defined (LDAP_CASA_AUTH)
665*83ee113eSDavid van Moolenbroek if (!load_uname_pwd_from_miCASA(&ldap_username,&ldap_password))
666*83ee113eSDavid van Moolenbroek {
667*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
668*83ee113eSDavid van Moolenbroek log_info ("Authentication credential taken from file");
669*83ee113eSDavid van Moolenbroek #endif
670*83ee113eSDavid van Moolenbroek #endif
671*83ee113eSDavid van Moolenbroek
672*83ee113eSDavid van Moolenbroek ldap_username = _do_lookup_dhcp_string_option (options, SV_LDAP_USERNAME);
673*83ee113eSDavid van Moolenbroek ldap_password = _do_lookup_dhcp_string_option (options, SV_LDAP_PASSWORD);
674*83ee113eSDavid van Moolenbroek
675*83ee113eSDavid van Moolenbroek #if defined (LDAP_CASA_AUTH)
676*83ee113eSDavid van Moolenbroek }
677*83ee113eSDavid van Moolenbroek #endif
678*83ee113eSDavid van Moolenbroek
679*83ee113eSDavid van Moolenbroek option_state_dereference (&options, MDL);
680*83ee113eSDavid van Moolenbroek }
681*83ee113eSDavid van Moolenbroek
682*83ee113eSDavid van Moolenbroek if (ldap_server == NULL || ldap_base_dn == NULL)
683*83ee113eSDavid van Moolenbroek {
684*83ee113eSDavid van Moolenbroek log_info ("Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not specified in the config file");
685*83ee113eSDavid van Moolenbroek ldap_method = LDAP_METHOD_STATIC;
686*83ee113eSDavid van Moolenbroek return;
687*83ee113eSDavid van Moolenbroek }
688*83ee113eSDavid van Moolenbroek
689*83ee113eSDavid van Moolenbroek if (ldap_debug_file != NULL && ldap_debug_fd == -1)
690*83ee113eSDavid van Moolenbroek {
691*83ee113eSDavid van Moolenbroek if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY,
692*83ee113eSDavid van Moolenbroek S_IRUSR | S_IWUSR)) < 0)
693*83ee113eSDavid van Moolenbroek log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file,
694*83ee113eSDavid van Moolenbroek strerror (errno));
695*83ee113eSDavid van Moolenbroek }
696*83ee113eSDavid van Moolenbroek
697*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
698*83ee113eSDavid van Moolenbroek log_info ("Connecting to LDAP server %s:%d", ldap_server, ldap_port);
699*83ee113eSDavid van Moolenbroek #endif
700*83ee113eSDavid van Moolenbroek
701*83ee113eSDavid van Moolenbroek #if defined (LDAP_USE_SSL)
702*83ee113eSDavid van Moolenbroek if (ldap_use_ssl == -1)
703*83ee113eSDavid van Moolenbroek {
704*83ee113eSDavid van Moolenbroek /*
705*83ee113eSDavid van Moolenbroek ** There was no "ldap-ssl" option in dhcpd.conf (also not "off").
706*83ee113eSDavid van Moolenbroek ** Let's try, if we can use an anonymous TLS session without to
707*83ee113eSDavid van Moolenbroek ** verify the server certificate -- if not continue without TLS.
708*83ee113eSDavid van Moolenbroek */
709*83ee113eSDavid van Moolenbroek int opt = LDAP_OPT_X_TLS_ALLOW;
710*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
711*83ee113eSDavid van Moolenbroek &opt)) != LDAP_SUCCESS)
712*83ee113eSDavid van Moolenbroek {
713*83ee113eSDavid van Moolenbroek log_error ("Warning: Cannot set LDAP TLS require cert option to 'allow': %s",
714*83ee113eSDavid van Moolenbroek ldap_err2string (ret));
715*83ee113eSDavid van Moolenbroek }
716*83ee113eSDavid van Moolenbroek }
717*83ee113eSDavid van Moolenbroek
718*83ee113eSDavid van Moolenbroek if (ldap_use_ssl != LDAP_SSL_OFF)
719*83ee113eSDavid van Moolenbroek {
720*83ee113eSDavid van Moolenbroek if (ldap_tls_reqcert != -1)
721*83ee113eSDavid van Moolenbroek {
722*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
723*83ee113eSDavid van Moolenbroek &ldap_tls_reqcert)) != LDAP_SUCCESS)
724*83ee113eSDavid van Moolenbroek {
725*83ee113eSDavid van Moolenbroek log_error ("Cannot set LDAP TLS require cert option: %s",
726*83ee113eSDavid van Moolenbroek ldap_err2string (ret));
727*83ee113eSDavid van Moolenbroek }
728*83ee113eSDavid van Moolenbroek }
729*83ee113eSDavid van Moolenbroek
730*83ee113eSDavid van Moolenbroek if( ldap_tls_ca_file != NULL)
731*83ee113eSDavid van Moolenbroek {
732*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE,
733*83ee113eSDavid van Moolenbroek ldap_tls_ca_file)) != LDAP_SUCCESS)
734*83ee113eSDavid van Moolenbroek {
735*83ee113eSDavid van Moolenbroek log_error ("Cannot set LDAP TLS CA certificate file %s: %s",
736*83ee113eSDavid van Moolenbroek ldap_tls_ca_file, ldap_err2string (ret));
737*83ee113eSDavid van Moolenbroek }
738*83ee113eSDavid van Moolenbroek }
739*83ee113eSDavid van Moolenbroek if( ldap_tls_ca_dir != NULL)
740*83ee113eSDavid van Moolenbroek {
741*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR,
742*83ee113eSDavid van Moolenbroek ldap_tls_ca_dir)) != LDAP_SUCCESS)
743*83ee113eSDavid van Moolenbroek {
744*83ee113eSDavid van Moolenbroek log_error ("Cannot set LDAP TLS CA certificate dir %s: %s",
745*83ee113eSDavid van Moolenbroek ldap_tls_ca_dir, ldap_err2string (ret));
746*83ee113eSDavid van Moolenbroek }
747*83ee113eSDavid van Moolenbroek }
748*83ee113eSDavid van Moolenbroek if( ldap_tls_cert != NULL)
749*83ee113eSDavid van Moolenbroek {
750*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CERTFILE,
751*83ee113eSDavid van Moolenbroek ldap_tls_cert)) != LDAP_SUCCESS)
752*83ee113eSDavid van Moolenbroek {
753*83ee113eSDavid van Moolenbroek log_error ("Cannot set LDAP TLS client certificate file %s: %s",
754*83ee113eSDavid van Moolenbroek ldap_tls_cert, ldap_err2string (ret));
755*83ee113eSDavid van Moolenbroek }
756*83ee113eSDavid van Moolenbroek }
757*83ee113eSDavid van Moolenbroek if( ldap_tls_key != NULL)
758*83ee113eSDavid van Moolenbroek {
759*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_KEYFILE,
760*83ee113eSDavid van Moolenbroek ldap_tls_key)) != LDAP_SUCCESS)
761*83ee113eSDavid van Moolenbroek {
762*83ee113eSDavid van Moolenbroek log_error ("Cannot set LDAP TLS certificate key file %s: %s",
763*83ee113eSDavid van Moolenbroek ldap_tls_key, ldap_err2string (ret));
764*83ee113eSDavid van Moolenbroek }
765*83ee113eSDavid van Moolenbroek }
766*83ee113eSDavid van Moolenbroek if( ldap_tls_crlcheck != -1)
767*83ee113eSDavid van Moolenbroek {
768*83ee113eSDavid van Moolenbroek int opt = ldap_tls_crlcheck;
769*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CRLCHECK,
770*83ee113eSDavid van Moolenbroek &opt)) != LDAP_SUCCESS)
771*83ee113eSDavid van Moolenbroek {
772*83ee113eSDavid van Moolenbroek log_error ("Cannot set LDAP TLS crl check option: %s",
773*83ee113eSDavid van Moolenbroek ldap_err2string (ret));
774*83ee113eSDavid van Moolenbroek }
775*83ee113eSDavid van Moolenbroek }
776*83ee113eSDavid van Moolenbroek if( ldap_tls_ciphers != NULL)
777*83ee113eSDavid van Moolenbroek {
778*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_CIPHER_SUITE,
779*83ee113eSDavid van Moolenbroek ldap_tls_ciphers)) != LDAP_SUCCESS)
780*83ee113eSDavid van Moolenbroek {
781*83ee113eSDavid van Moolenbroek log_error ("Cannot set LDAP TLS cipher suite %s: %s",
782*83ee113eSDavid van Moolenbroek ldap_tls_ciphers, ldap_err2string (ret));
783*83ee113eSDavid van Moolenbroek }
784*83ee113eSDavid van Moolenbroek }
785*83ee113eSDavid van Moolenbroek if( ldap_tls_randfile != NULL)
786*83ee113eSDavid van Moolenbroek {
787*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_option (NULL, LDAP_OPT_X_TLS_RANDOM_FILE,
788*83ee113eSDavid van Moolenbroek ldap_tls_randfile)) != LDAP_SUCCESS)
789*83ee113eSDavid van Moolenbroek {
790*83ee113eSDavid van Moolenbroek log_error ("Cannot set LDAP TLS random file %s: %s",
791*83ee113eSDavid van Moolenbroek ldap_tls_randfile, ldap_err2string (ret));
792*83ee113eSDavid van Moolenbroek }
793*83ee113eSDavid van Moolenbroek }
794*83ee113eSDavid van Moolenbroek }
795*83ee113eSDavid van Moolenbroek #endif
796*83ee113eSDavid van Moolenbroek
797*83ee113eSDavid van Moolenbroek /* enough for 'ldap://+ + hostname + ':' + port number */
798*83ee113eSDavid van Moolenbroek uri = malloc(strlen(ldap_server) + 16);
799*83ee113eSDavid van Moolenbroek if (uri == NULL)
800*83ee113eSDavid van Moolenbroek {
801*83ee113eSDavid van Moolenbroek log_error ("Cannot build ldap init URI %s:%d", ldap_server, ldap_port);
802*83ee113eSDavid van Moolenbroek return;
803*83ee113eSDavid van Moolenbroek }
804*83ee113eSDavid van Moolenbroek
805*83ee113eSDavid van Moolenbroek sprintf(uri, "ldap://%s:%d", ldap_server, ldap_port);
806*83ee113eSDavid van Moolenbroek ldap_initialize(&ld, uri);
807*83ee113eSDavid van Moolenbroek
808*83ee113eSDavid van Moolenbroek if (ld == NULL)
809*83ee113eSDavid van Moolenbroek {
810*83ee113eSDavid van Moolenbroek log_error ("Cannot init ldap session to %s:%d", ldap_server, ldap_port);
811*83ee113eSDavid van Moolenbroek return;
812*83ee113eSDavid van Moolenbroek }
813*83ee113eSDavid van Moolenbroek
814*83ee113eSDavid van Moolenbroek free(uri);
815*83ee113eSDavid van Moolenbroek
816*83ee113eSDavid van Moolenbroek version = LDAP_VERSION3;
817*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version)) != LDAP_OPT_SUCCESS)
818*83ee113eSDavid van Moolenbroek {
819*83ee113eSDavid van Moolenbroek log_error ("Cannot set LDAP version to %d: %s", version,
820*83ee113eSDavid van Moolenbroek ldap_err2string (ret));
821*83ee113eSDavid van Moolenbroek }
822*83ee113eSDavid van Moolenbroek
823*83ee113eSDavid van Moolenbroek if (ldap_referrals != -1)
824*83ee113eSDavid van Moolenbroek {
825*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_option (ld, LDAP_OPT_REFERRALS, ldap_referrals ?
826*83ee113eSDavid van Moolenbroek LDAP_OPT_ON : LDAP_OPT_OFF)) != LDAP_OPT_SUCCESS)
827*83ee113eSDavid van Moolenbroek {
828*83ee113eSDavid van Moolenbroek log_error ("Cannot %s LDAP referrals option: %s",
829*83ee113eSDavid van Moolenbroek (ldap_referrals ? "enable" : "disable"),
830*83ee113eSDavid van Moolenbroek ldap_err2string (ret));
831*83ee113eSDavid van Moolenbroek }
832*83ee113eSDavid van Moolenbroek }
833*83ee113eSDavid van Moolenbroek
834*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_rebind_proc(ld, ldap_rebind_cb, NULL)) != LDAP_SUCCESS)
835*83ee113eSDavid van Moolenbroek {
836*83ee113eSDavid van Moolenbroek log_error ("Warning: Cannot set ldap rebind procedure: %s",
837*83ee113eSDavid van Moolenbroek ldap_err2string (ret));
838*83ee113eSDavid van Moolenbroek }
839*83ee113eSDavid van Moolenbroek
840*83ee113eSDavid van Moolenbroek #if defined (LDAP_USE_SSL)
841*83ee113eSDavid van Moolenbroek if (ldap_use_ssl == LDAP_SSL_LDAPS ||
842*83ee113eSDavid van Moolenbroek (ldap_use_ssl == LDAP_SSL_ON && ldap_port == LDAPS_PORT))
843*83ee113eSDavid van Moolenbroek {
844*83ee113eSDavid van Moolenbroek int opt = LDAP_OPT_X_TLS_HARD;
845*83ee113eSDavid van Moolenbroek if ((ret = ldap_set_option (ld, LDAP_OPT_X_TLS, &opt)) != LDAP_SUCCESS)
846*83ee113eSDavid van Moolenbroek {
847*83ee113eSDavid van Moolenbroek log_error ("Error: Cannot init LDAPS session to %s:%d: %s",
848*83ee113eSDavid van Moolenbroek ldap_server, ldap_port, ldap_err2string (ret));
849*83ee113eSDavid van Moolenbroek ldap_stop();
850*83ee113eSDavid van Moolenbroek return;
851*83ee113eSDavid van Moolenbroek }
852*83ee113eSDavid van Moolenbroek else
853*83ee113eSDavid van Moolenbroek {
854*83ee113eSDavid van Moolenbroek log_info ("LDAPS session successfully enabled to %s:%d",
855*83ee113eSDavid van Moolenbroek ldap_server, ldap_port);
856*83ee113eSDavid van Moolenbroek }
857*83ee113eSDavid van Moolenbroek }
858*83ee113eSDavid van Moolenbroek else if (ldap_use_ssl != LDAP_SSL_OFF)
859*83ee113eSDavid van Moolenbroek {
860*83ee113eSDavid van Moolenbroek if ((ret = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS)
861*83ee113eSDavid van Moolenbroek {
862*83ee113eSDavid van Moolenbroek log_error ("Error: Cannot start TLS session to %s:%d: %s",
863*83ee113eSDavid van Moolenbroek ldap_server, ldap_port, ldap_err2string (ret));
864*83ee113eSDavid van Moolenbroek ldap_stop();
865*83ee113eSDavid van Moolenbroek return;
866*83ee113eSDavid van Moolenbroek }
867*83ee113eSDavid van Moolenbroek else
868*83ee113eSDavid van Moolenbroek {
869*83ee113eSDavid van Moolenbroek log_info ("TLS session successfully started to %s:%d",
870*83ee113eSDavid van Moolenbroek ldap_server, ldap_port);
871*83ee113eSDavid van Moolenbroek }
872*83ee113eSDavid van Moolenbroek }
873*83ee113eSDavid van Moolenbroek #endif
874*83ee113eSDavid van Moolenbroek
875*83ee113eSDavid van Moolenbroek if (ldap_username != NULL && *ldap_username != '\0')
876*83ee113eSDavid van Moolenbroek {
877*83ee113eSDavid van Moolenbroek creds.bv_val = strdup(ldap_password);
878*83ee113eSDavid van Moolenbroek creds.bv_len = strlen(ldap_password);
879*83ee113eSDavid van Moolenbroek
880*83ee113eSDavid van Moolenbroek if ((ret = ldap_sasl_bind_s (ld, ldap_username, LDAP_SASL_SIMPLE,
881*83ee113eSDavid van Moolenbroek &creds, NULL, NULL, NULL)) != LDAP_SUCCESS)
882*83ee113eSDavid van Moolenbroek {
883*83ee113eSDavid van Moolenbroek log_error ("Error: Cannot login into ldap server %s:%d: %s",
884*83ee113eSDavid van Moolenbroek ldap_server, ldap_port, ldap_err2string (ret));
885*83ee113eSDavid van Moolenbroek ldap_stop();
886*83ee113eSDavid van Moolenbroek return;
887*83ee113eSDavid van Moolenbroek }
888*83ee113eSDavid van Moolenbroek }
889*83ee113eSDavid van Moolenbroek
890*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
891*83ee113eSDavid van Moolenbroek log_info ("Successfully logged into LDAP server %s", ldap_server);
892*83ee113eSDavid van Moolenbroek #endif
893*83ee113eSDavid van Moolenbroek }
894*83ee113eSDavid van Moolenbroek
895*83ee113eSDavid van Moolenbroek
896*83ee113eSDavid van Moolenbroek static void
parse_external_dns(LDAPMessage * ent)897*83ee113eSDavid van Moolenbroek parse_external_dns (LDAPMessage * ent)
898*83ee113eSDavid van Moolenbroek {
899*83ee113eSDavid van Moolenbroek char *search[] = {"dhcpOptionsDN", "dhcpSharedNetworkDN", "dhcpSubnetDN",
900*83ee113eSDavid van Moolenbroek "dhcpGroupDN", "dhcpHostDN", "dhcpClassesDN",
901*83ee113eSDavid van Moolenbroek "dhcpPoolDN", NULL};
902*83ee113eSDavid van Moolenbroek LDAPMessage * newres, * newent;
903*83ee113eSDavid van Moolenbroek struct berval **tempbv;
904*83ee113eSDavid van Moolenbroek int i, j, ret;
905*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
906*83ee113eSDavid van Moolenbroek char *dn;
907*83ee113eSDavid van Moolenbroek
908*83ee113eSDavid van Moolenbroek dn = ldap_get_dn (ld, ent);
909*83ee113eSDavid van Moolenbroek if (dn != NULL)
910*83ee113eSDavid van Moolenbroek {
911*83ee113eSDavid van Moolenbroek log_info ("Parsing external DNs for '%s'", dn);
912*83ee113eSDavid van Moolenbroek ldap_memfree (dn);
913*83ee113eSDavid van Moolenbroek }
914*83ee113eSDavid van Moolenbroek #endif
915*83ee113eSDavid van Moolenbroek
916*83ee113eSDavid van Moolenbroek if (ld == NULL)
917*83ee113eSDavid van Moolenbroek ldap_start ();
918*83ee113eSDavid van Moolenbroek if (ld == NULL)
919*83ee113eSDavid van Moolenbroek return;
920*83ee113eSDavid van Moolenbroek
921*83ee113eSDavid van Moolenbroek for (i=0; search[i] != NULL; i++)
922*83ee113eSDavid van Moolenbroek {
923*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, ent, search[i])) == NULL)
924*83ee113eSDavid van Moolenbroek continue;
925*83ee113eSDavid van Moolenbroek
926*83ee113eSDavid van Moolenbroek for (j=0; tempbv[j] != NULL; j++)
927*83ee113eSDavid van Moolenbroek {
928*83ee113eSDavid van Moolenbroek if (*tempbv[j]->bv_val == '\0')
929*83ee113eSDavid van Moolenbroek continue;
930*83ee113eSDavid van Moolenbroek
931*83ee113eSDavid van Moolenbroek if ((ret = ldap_search_ext_s(ld, tempbv[j]->bv_val, LDAP_SCOPE_BASE,
932*83ee113eSDavid van Moolenbroek "objectClass=*", NULL, 0, NULL,
933*83ee113eSDavid van Moolenbroek NULL, NULL, 0, &newres)) != LDAP_SUCCESS)
934*83ee113eSDavid van Moolenbroek {
935*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
936*83ee113eSDavid van Moolenbroek ldap_stop();
937*83ee113eSDavid van Moolenbroek return;
938*83ee113eSDavid van Moolenbroek }
939*83ee113eSDavid van Moolenbroek
940*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
941*83ee113eSDavid van Moolenbroek log_info ("Adding contents of subtree '%s' to config stack from '%s' reference", tempbv[j], search[i]);
942*83ee113eSDavid van Moolenbroek #endif
943*83ee113eSDavid van Moolenbroek for (newent = ldap_first_entry (ld, newres);
944*83ee113eSDavid van Moolenbroek newent != NULL;
945*83ee113eSDavid van Moolenbroek newent = ldap_next_entry (ld, newent))
946*83ee113eSDavid van Moolenbroek {
947*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
948*83ee113eSDavid van Moolenbroek dn = ldap_get_dn (ld, newent);
949*83ee113eSDavid van Moolenbroek if (dn != NULL)
950*83ee113eSDavid van Moolenbroek {
951*83ee113eSDavid van Moolenbroek log_info ("Adding LDAP result set starting with '%s' to config stack", dn);
952*83ee113eSDavid van Moolenbroek ldap_memfree (dn);
953*83ee113eSDavid van Moolenbroek }
954*83ee113eSDavid van Moolenbroek #endif
955*83ee113eSDavid van Moolenbroek
956*83ee113eSDavid van Moolenbroek add_to_config_stack (newres, newent);
957*83ee113eSDavid van Moolenbroek /* don't free newres here */
958*83ee113eSDavid van Moolenbroek }
959*83ee113eSDavid van Moolenbroek }
960*83ee113eSDavid van Moolenbroek
961*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
962*83ee113eSDavid van Moolenbroek }
963*83ee113eSDavid van Moolenbroek }
964*83ee113eSDavid van Moolenbroek
965*83ee113eSDavid van Moolenbroek
966*83ee113eSDavid van Moolenbroek static void
free_stack_entry(struct ldap_config_stack * item)967*83ee113eSDavid van Moolenbroek free_stack_entry (struct ldap_config_stack *item)
968*83ee113eSDavid van Moolenbroek {
969*83ee113eSDavid van Moolenbroek struct ldap_config_stack *look_ahead_pointer = item;
970*83ee113eSDavid van Moolenbroek int may_free_msg = 1;
971*83ee113eSDavid van Moolenbroek
972*83ee113eSDavid van Moolenbroek while (look_ahead_pointer->next != NULL)
973*83ee113eSDavid van Moolenbroek {
974*83ee113eSDavid van Moolenbroek look_ahead_pointer = look_ahead_pointer->next;
975*83ee113eSDavid van Moolenbroek if (look_ahead_pointer->res == item->res)
976*83ee113eSDavid van Moolenbroek {
977*83ee113eSDavid van Moolenbroek may_free_msg = 0;
978*83ee113eSDavid van Moolenbroek break;
979*83ee113eSDavid van Moolenbroek }
980*83ee113eSDavid van Moolenbroek }
981*83ee113eSDavid van Moolenbroek
982*83ee113eSDavid van Moolenbroek if (may_free_msg)
983*83ee113eSDavid van Moolenbroek ldap_msgfree (item->res);
984*83ee113eSDavid van Moolenbroek
985*83ee113eSDavid van Moolenbroek dfree (item, MDL);
986*83ee113eSDavid van Moolenbroek }
987*83ee113eSDavid van Moolenbroek
988*83ee113eSDavid van Moolenbroek
989*83ee113eSDavid van Moolenbroek static void
next_ldap_entry(struct parse * cfile)990*83ee113eSDavid van Moolenbroek next_ldap_entry (struct parse *cfile)
991*83ee113eSDavid van Moolenbroek {
992*83ee113eSDavid van Moolenbroek struct ldap_config_stack *temp_stack;
993*83ee113eSDavid van Moolenbroek
994*83ee113eSDavid van Moolenbroek if (ldap_stack != NULL && ldap_stack->close_brace)
995*83ee113eSDavid van Moolenbroek {
996*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
997*83ee113eSDavid van Moolenbroek ldap_stack->close_brace = 0;
998*83ee113eSDavid van Moolenbroek }
999*83ee113eSDavid van Moolenbroek
1000*83ee113eSDavid van Moolenbroek while (ldap_stack != NULL &&
1001*83ee113eSDavid van Moolenbroek (ldap_stack->ldent == NULL ||
1002*83ee113eSDavid van Moolenbroek (ldap_stack->ldent = ldap_next_entry (ld, ldap_stack->ldent)) == NULL))
1003*83ee113eSDavid van Moolenbroek {
1004*83ee113eSDavid van Moolenbroek if (ldap_stack->close_brace)
1005*83ee113eSDavid van Moolenbroek {
1006*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
1007*83ee113eSDavid van Moolenbroek ldap_stack->close_brace = 0;
1008*83ee113eSDavid van Moolenbroek }
1009*83ee113eSDavid van Moolenbroek
1010*83ee113eSDavid van Moolenbroek temp_stack = ldap_stack;
1011*83ee113eSDavid van Moolenbroek ldap_stack = ldap_stack->next;
1012*83ee113eSDavid van Moolenbroek free_stack_entry (temp_stack);
1013*83ee113eSDavid van Moolenbroek }
1014*83ee113eSDavid van Moolenbroek
1015*83ee113eSDavid van Moolenbroek if (ldap_stack != NULL && ldap_stack->close_brace)
1016*83ee113eSDavid van Moolenbroek {
1017*83ee113eSDavid van Moolenbroek x_strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
1018*83ee113eSDavid van Moolenbroek ldap_stack->close_brace = 0;
1019*83ee113eSDavid van Moolenbroek }
1020*83ee113eSDavid van Moolenbroek }
1021*83ee113eSDavid van Moolenbroek
1022*83ee113eSDavid van Moolenbroek
1023*83ee113eSDavid van Moolenbroek static char
check_statement_end(const char * statement)1024*83ee113eSDavid van Moolenbroek check_statement_end (const char *statement)
1025*83ee113eSDavid van Moolenbroek {
1026*83ee113eSDavid van Moolenbroek char *ptr;
1027*83ee113eSDavid van Moolenbroek
1028*83ee113eSDavid van Moolenbroek if (statement == NULL || *statement == '\0')
1029*83ee113eSDavid van Moolenbroek return ('\0');
1030*83ee113eSDavid van Moolenbroek
1031*83ee113eSDavid van Moolenbroek /*
1032*83ee113eSDavid van Moolenbroek ** check if it ends with "}", e.g.:
1033*83ee113eSDavid van Moolenbroek ** "zone my.domain. { ... }"
1034*83ee113eSDavid van Moolenbroek ** optionally followed by spaces
1035*83ee113eSDavid van Moolenbroek */
1036*83ee113eSDavid van Moolenbroek ptr = strrchr (statement, '}');
1037*83ee113eSDavid van Moolenbroek if (ptr != NULL)
1038*83ee113eSDavid van Moolenbroek {
1039*83ee113eSDavid van Moolenbroek /* skip following white-spaces */
1040*83ee113eSDavid van Moolenbroek for (++ptr; isspace ((int)*ptr); ptr++);
1041*83ee113eSDavid van Moolenbroek
1042*83ee113eSDavid van Moolenbroek /* check if we reached the end */
1043*83ee113eSDavid van Moolenbroek if (*ptr == '\0')
1044*83ee113eSDavid van Moolenbroek return ('}'); /* yes, block end */
1045*83ee113eSDavid van Moolenbroek else
1046*83ee113eSDavid van Moolenbroek return (*ptr);
1047*83ee113eSDavid van Moolenbroek }
1048*83ee113eSDavid van Moolenbroek
1049*83ee113eSDavid van Moolenbroek /*
1050*83ee113eSDavid van Moolenbroek ** this should not happen, but...
1051*83ee113eSDavid van Moolenbroek ** check if it ends with ";", e.g.:
1052*83ee113eSDavid van Moolenbroek ** "authoritative;"
1053*83ee113eSDavid van Moolenbroek ** optionally followed by spaces
1054*83ee113eSDavid van Moolenbroek */
1055*83ee113eSDavid van Moolenbroek ptr = strrchr (statement, ';');
1056*83ee113eSDavid van Moolenbroek if (ptr != NULL)
1057*83ee113eSDavid van Moolenbroek {
1058*83ee113eSDavid van Moolenbroek /* skip following white-spaces */
1059*83ee113eSDavid van Moolenbroek for (++ptr; isspace ((int)*ptr); ptr++);
1060*83ee113eSDavid van Moolenbroek
1061*83ee113eSDavid van Moolenbroek /* check if we reached the end */
1062*83ee113eSDavid van Moolenbroek if (*ptr == '\0')
1063*83ee113eSDavid van Moolenbroek return (';'); /* ends with a ; */
1064*83ee113eSDavid van Moolenbroek else
1065*83ee113eSDavid van Moolenbroek return (*ptr);
1066*83ee113eSDavid van Moolenbroek }
1067*83ee113eSDavid van Moolenbroek
1068*83ee113eSDavid van Moolenbroek return ('\0');
1069*83ee113eSDavid van Moolenbroek }
1070*83ee113eSDavid van Moolenbroek
1071*83ee113eSDavid van Moolenbroek
1072*83ee113eSDavid van Moolenbroek static isc_result_t
ldap_parse_entry_options(LDAPMessage * ent,char * buffer,size_t size,int * lease_limit)1073*83ee113eSDavid van Moolenbroek ldap_parse_entry_options (LDAPMessage *ent, char *buffer, size_t size,
1074*83ee113eSDavid van Moolenbroek int *lease_limit)
1075*83ee113eSDavid van Moolenbroek {
1076*83ee113eSDavid van Moolenbroek struct berval **tempbv;
1077*83ee113eSDavid van Moolenbroek int i;
1078*83ee113eSDavid van Moolenbroek
1079*83ee113eSDavid van Moolenbroek if (ent == NULL || buffer == NULL || size == 0)
1080*83ee113eSDavid van Moolenbroek return (ISC_R_FAILURE);
1081*83ee113eSDavid van Moolenbroek
1082*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, ent, "dhcpStatements")) != NULL)
1083*83ee113eSDavid van Moolenbroek {
1084*83ee113eSDavid van Moolenbroek for (i=0; tempbv[i] != NULL; i++)
1085*83ee113eSDavid van Moolenbroek {
1086*83ee113eSDavid van Moolenbroek if (lease_limit != NULL &&
1087*83ee113eSDavid van Moolenbroek strncasecmp ("lease limit ", tempbv[i]->bv_val, 12) == 0)
1088*83ee113eSDavid van Moolenbroek {
1089*83ee113eSDavid van Moolenbroek *lease_limit = (int) strtol ((tempbv[i]->bv_val) + 12, NULL, 10);
1090*83ee113eSDavid van Moolenbroek continue;
1091*83ee113eSDavid van Moolenbroek }
1092*83ee113eSDavid van Moolenbroek
1093*83ee113eSDavid van Moolenbroek x_strncat (buffer, tempbv[i]->bv_val, size);
1094*83ee113eSDavid van Moolenbroek
1095*83ee113eSDavid van Moolenbroek switch((int) check_statement_end (tempbv[i]->bv_val))
1096*83ee113eSDavid van Moolenbroek {
1097*83ee113eSDavid van Moolenbroek case '}':
1098*83ee113eSDavid van Moolenbroek case ';':
1099*83ee113eSDavid van Moolenbroek x_strncat (buffer, "\n", size);
1100*83ee113eSDavid van Moolenbroek break;
1101*83ee113eSDavid van Moolenbroek default:
1102*83ee113eSDavid van Moolenbroek x_strncat (buffer, ";\n", size);
1103*83ee113eSDavid van Moolenbroek break;
1104*83ee113eSDavid van Moolenbroek }
1105*83ee113eSDavid van Moolenbroek }
1106*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
1107*83ee113eSDavid van Moolenbroek }
1108*83ee113eSDavid van Moolenbroek
1109*83ee113eSDavid van Moolenbroek if ((tempbv = ldap_get_values_len (ld, ent, "dhcpOption")) != NULL)
1110*83ee113eSDavid van Moolenbroek {
1111*83ee113eSDavid van Moolenbroek for (i=0; tempbv[i] != NULL; i++)
1112*83ee113eSDavid van Moolenbroek {
1113*83ee113eSDavid van Moolenbroek x_strncat (buffer, "option ", size);
1114*83ee113eSDavid van Moolenbroek x_strncat (buffer, tempbv[i]->bv_val, size);
1115*83ee113eSDavid van Moolenbroek switch ((int) check_statement_end (tempbv[i]->bv_val))
1116*83ee113eSDavid van Moolenbroek {
1117*83ee113eSDavid van Moolenbroek case ';':
1118*83ee113eSDavid van Moolenbroek x_strncat (buffer, "\n", size);
1119*83ee113eSDavid van Moolenbroek break;
1120*83ee113eSDavid van Moolenbroek default:
1121*83ee113eSDavid van Moolenbroek x_strncat (buffer, ";\n", size);
1122*83ee113eSDavid van Moolenbroek break;
1123*83ee113eSDavid van Moolenbroek }
1124*83ee113eSDavid van Moolenbroek }
1125*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
1126*83ee113eSDavid van Moolenbroek }
1127*83ee113eSDavid van Moolenbroek
1128*83ee113eSDavid van Moolenbroek return (ISC_R_SUCCESS);
1129*83ee113eSDavid van Moolenbroek }
1130*83ee113eSDavid van Moolenbroek
1131*83ee113eSDavid van Moolenbroek
1132*83ee113eSDavid van Moolenbroek static void
ldap_generate_config_string(struct parse * cfile)1133*83ee113eSDavid van Moolenbroek ldap_generate_config_string (struct parse *cfile)
1134*83ee113eSDavid van Moolenbroek {
1135*83ee113eSDavid van Moolenbroek struct berval **objectClass;
1136*83ee113eSDavid van Moolenbroek char *dn;
1137*83ee113eSDavid van Moolenbroek struct ldap_config_stack *entry;
1138*83ee113eSDavid van Moolenbroek LDAPMessage * ent, * res;
1139*83ee113eSDavid van Moolenbroek int i, ignore, found;
1140*83ee113eSDavid van Moolenbroek int ret;
1141*83ee113eSDavid van Moolenbroek
1142*83ee113eSDavid van Moolenbroek if (ld == NULL)
1143*83ee113eSDavid van Moolenbroek ldap_start ();
1144*83ee113eSDavid van Moolenbroek if (ld == NULL)
1145*83ee113eSDavid van Moolenbroek return;
1146*83ee113eSDavid van Moolenbroek
1147*83ee113eSDavid van Moolenbroek entry = ldap_stack;
1148*83ee113eSDavid van Moolenbroek if ((objectClass = ldap_get_values_len (ld, entry->ldent,
1149*83ee113eSDavid van Moolenbroek "objectClass")) == NULL)
1150*83ee113eSDavid van Moolenbroek return;
1151*83ee113eSDavid van Moolenbroek
1152*83ee113eSDavid van Moolenbroek ignore = 0;
1153*83ee113eSDavid van Moolenbroek found = 1;
1154*83ee113eSDavid van Moolenbroek for (i=0; objectClass[i] != NULL; i++)
1155*83ee113eSDavid van Moolenbroek {
1156*83ee113eSDavid van Moolenbroek if (strcasecmp (objectClass[i]->bv_val, "dhcpSharedNetwork") == 0)
1157*83ee113eSDavid van Moolenbroek ldap_parse_shared_network (entry, cfile);
1158*83ee113eSDavid van Moolenbroek else if (strcasecmp (objectClass[i]->bv_val, "dhcpClass") == 0)
1159*83ee113eSDavid van Moolenbroek ldap_parse_class (entry, cfile);
1160*83ee113eSDavid van Moolenbroek else if (strcasecmp (objectClass[i]->bv_val, "dhcpSubnet") == 0)
1161*83ee113eSDavid van Moolenbroek ldap_parse_subnet (entry, cfile);
1162*83ee113eSDavid van Moolenbroek else if (strcasecmp (objectClass[i]->bv_val, "dhcpPool") == 0)
1163*83ee113eSDavid van Moolenbroek ldap_parse_pool (entry, cfile);
1164*83ee113eSDavid van Moolenbroek else if (strcasecmp (objectClass[i]->bv_val, "dhcpGroup") == 0)
1165*83ee113eSDavid van Moolenbroek ldap_parse_group (entry, cfile);
1166*83ee113eSDavid van Moolenbroek else if (strcasecmp (objectClass[i]->bv_val, "dhcpTSigKey") == 0)
1167*83ee113eSDavid van Moolenbroek ldap_parse_key (entry, cfile);
1168*83ee113eSDavid van Moolenbroek else if (strcasecmp (objectClass[i]->bv_val, "dhcpDnsZone") == 0)
1169*83ee113eSDavid van Moolenbroek ldap_parse_zone (entry, cfile);
1170*83ee113eSDavid van Moolenbroek else if (strcasecmp (objectClass[i]->bv_val, "dhcpHost") == 0)
1171*83ee113eSDavid van Moolenbroek {
1172*83ee113eSDavid van Moolenbroek if (ldap_method == LDAP_METHOD_STATIC)
1173*83ee113eSDavid van Moolenbroek ldap_parse_host (entry, cfile);
1174*83ee113eSDavid van Moolenbroek else
1175*83ee113eSDavid van Moolenbroek {
1176*83ee113eSDavid van Moolenbroek ignore = 1;
1177*83ee113eSDavid van Moolenbroek break;
1178*83ee113eSDavid van Moolenbroek }
1179*83ee113eSDavid van Moolenbroek }
1180*83ee113eSDavid van Moolenbroek else if (strcasecmp (objectClass[i]->bv_val, "dhcpSubClass") == 0)
1181*83ee113eSDavid van Moolenbroek {
1182*83ee113eSDavid van Moolenbroek if (ldap_method == LDAP_METHOD_STATIC)
1183*83ee113eSDavid van Moolenbroek ldap_parse_subclass (entry, cfile);
1184*83ee113eSDavid van Moolenbroek else
1185*83ee113eSDavid van Moolenbroek {
1186*83ee113eSDavid van Moolenbroek ignore = 1;
1187*83ee113eSDavid van Moolenbroek break;
1188*83ee113eSDavid van Moolenbroek }
1189*83ee113eSDavid van Moolenbroek }
1190*83ee113eSDavid van Moolenbroek else
1191*83ee113eSDavid van Moolenbroek found = 0;
1192*83ee113eSDavid van Moolenbroek
1193*83ee113eSDavid van Moolenbroek if (found && cfile->inbuf[0] == '\0')
1194*83ee113eSDavid van Moolenbroek {
1195*83ee113eSDavid van Moolenbroek ignore = 1;
1196*83ee113eSDavid van Moolenbroek break;
1197*83ee113eSDavid van Moolenbroek }
1198*83ee113eSDavid van Moolenbroek }
1199*83ee113eSDavid van Moolenbroek
1200*83ee113eSDavid van Moolenbroek ldap_value_free_len (objectClass);
1201*83ee113eSDavid van Moolenbroek
1202*83ee113eSDavid van Moolenbroek if (ignore)
1203*83ee113eSDavid van Moolenbroek {
1204*83ee113eSDavid van Moolenbroek next_ldap_entry (cfile);
1205*83ee113eSDavid van Moolenbroek return;
1206*83ee113eSDavid van Moolenbroek }
1207*83ee113eSDavid van Moolenbroek
1208*83ee113eSDavid van Moolenbroek ldap_parse_entry_options(entry->ldent, cfile->inbuf,
1209*83ee113eSDavid van Moolenbroek LDAP_BUFFER_SIZE-1, NULL);
1210*83ee113eSDavid van Moolenbroek
1211*83ee113eSDavid van Moolenbroek dn = ldap_get_dn (ld, entry->ldent);
1212*83ee113eSDavid van Moolenbroek
1213*83ee113eSDavid van Moolenbroek #if defined(DEBUG_LDAP)
1214*83ee113eSDavid van Moolenbroek if (dn != NULL)
1215*83ee113eSDavid van Moolenbroek log_info ("Found LDAP entry '%s'", dn);
1216*83ee113eSDavid van Moolenbroek #endif
1217*83ee113eSDavid van Moolenbroek
1218*83ee113eSDavid van Moolenbroek if (dn == NULL ||
1219*83ee113eSDavid van Moolenbroek (ret = ldap_search_ext_s (ld, dn, LDAP_SCOPE_ONELEVEL,
1220*83ee113eSDavid van Moolenbroek "objectClass=*", NULL, 0, NULL, NULL,
1221*83ee113eSDavid van Moolenbroek NULL, 0, &res)) != LDAP_SUCCESS)
1222*83ee113eSDavid van Moolenbroek {
1223*83ee113eSDavid van Moolenbroek if (dn)
1224*83ee113eSDavid van Moolenbroek ldap_memfree (dn);
1225*83ee113eSDavid van Moolenbroek
1226*83ee113eSDavid van Moolenbroek ldap_stop();
1227*83ee113eSDavid van Moolenbroek return;
1228*83ee113eSDavid van Moolenbroek }
1229*83ee113eSDavid van Moolenbroek
1230*83ee113eSDavid van Moolenbroek ldap_memfree (dn);
1231*83ee113eSDavid van Moolenbroek
1232*83ee113eSDavid van Moolenbroek if ((ent = ldap_first_entry (ld, res)) != NULL)
1233*83ee113eSDavid van Moolenbroek {
1234*83ee113eSDavid van Moolenbroek add_to_config_stack (res, ent);
1235*83ee113eSDavid van Moolenbroek parse_external_dns (entry->ldent);
1236*83ee113eSDavid van Moolenbroek }
1237*83ee113eSDavid van Moolenbroek else
1238*83ee113eSDavid van Moolenbroek {
1239*83ee113eSDavid van Moolenbroek ldap_msgfree (res);
1240*83ee113eSDavid van Moolenbroek parse_external_dns (entry->ldent);
1241*83ee113eSDavid van Moolenbroek next_ldap_entry (cfile);
1242*83ee113eSDavid van Moolenbroek }
1243*83ee113eSDavid van Moolenbroek }
1244*83ee113eSDavid van Moolenbroek
1245*83ee113eSDavid van Moolenbroek
1246*83ee113eSDavid van Moolenbroek static void
ldap_close_debug_fd()1247*83ee113eSDavid van Moolenbroek ldap_close_debug_fd()
1248*83ee113eSDavid van Moolenbroek {
1249*83ee113eSDavid van Moolenbroek if (ldap_debug_fd != -1)
1250*83ee113eSDavid van Moolenbroek {
1251*83ee113eSDavid van Moolenbroek close (ldap_debug_fd);
1252*83ee113eSDavid van Moolenbroek ldap_debug_fd = -1;
1253*83ee113eSDavid van Moolenbroek }
1254*83ee113eSDavid van Moolenbroek }
1255*83ee113eSDavid van Moolenbroek
1256*83ee113eSDavid van Moolenbroek
1257*83ee113eSDavid van Moolenbroek static void
ldap_write_debug(const void * buff,size_t size)1258*83ee113eSDavid van Moolenbroek ldap_write_debug (const void *buff, size_t size)
1259*83ee113eSDavid van Moolenbroek {
1260*83ee113eSDavid van Moolenbroek if (ldap_debug_fd != -1)
1261*83ee113eSDavid van Moolenbroek {
1262*83ee113eSDavid van Moolenbroek if (write (ldap_debug_fd, buff, size) < 0)
1263*83ee113eSDavid van Moolenbroek {
1264*83ee113eSDavid van Moolenbroek log_error ("Error writing to LDAP debug file %s: %s."
1265*83ee113eSDavid van Moolenbroek " Disabling log file.", ldap_debug_file,
1266*83ee113eSDavid van Moolenbroek strerror (errno));
1267*83ee113eSDavid van Moolenbroek ldap_close_debug_fd();
1268*83ee113eSDavid van Moolenbroek }
1269*83ee113eSDavid van Moolenbroek }
1270*83ee113eSDavid van Moolenbroek }
1271*83ee113eSDavid van Moolenbroek
1272*83ee113eSDavid van Moolenbroek static int
ldap_read_function(struct parse * cfile)1273*83ee113eSDavid van Moolenbroek ldap_read_function (struct parse *cfile)
1274*83ee113eSDavid van Moolenbroek {
1275*83ee113eSDavid van Moolenbroek cfile->inbuf[0] = '\0';
1276*83ee113eSDavid van Moolenbroek cfile->buflen = 0;
1277*83ee113eSDavid van Moolenbroek
1278*83ee113eSDavid van Moolenbroek while (ldap_stack != NULL && *cfile->inbuf == '\0')
1279*83ee113eSDavid van Moolenbroek ldap_generate_config_string (cfile);
1280*83ee113eSDavid van Moolenbroek
1281*83ee113eSDavid van Moolenbroek if (ldap_stack == NULL && *cfile->inbuf == '\0')
1282*83ee113eSDavid van Moolenbroek return (EOF);
1283*83ee113eSDavid van Moolenbroek
1284*83ee113eSDavid van Moolenbroek cfile->bufix = 1;
1285*83ee113eSDavid van Moolenbroek cfile->buflen = strlen (cfile->inbuf) - 1;
1286*83ee113eSDavid van Moolenbroek if (cfile->buflen > 0)
1287*83ee113eSDavid van Moolenbroek ldap_write_debug (cfile->inbuf, cfile->buflen);
1288*83ee113eSDavid van Moolenbroek
1289*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
1290*83ee113eSDavid van Moolenbroek log_info ("Sending config line '%s'", cfile->inbuf);
1291*83ee113eSDavid van Moolenbroek #endif
1292*83ee113eSDavid van Moolenbroek
1293*83ee113eSDavid van Moolenbroek return (cfile->inbuf[0]);
1294*83ee113eSDavid van Moolenbroek }
1295*83ee113eSDavid van Moolenbroek
1296*83ee113eSDavid van Moolenbroek
1297*83ee113eSDavid van Moolenbroek static char *
ldap_get_host_name(LDAPMessage * ent)1298*83ee113eSDavid van Moolenbroek ldap_get_host_name (LDAPMessage * ent)
1299*83ee113eSDavid van Moolenbroek {
1300*83ee113eSDavid van Moolenbroek struct berval **name;
1301*83ee113eSDavid van Moolenbroek char *ret;
1302*83ee113eSDavid van Moolenbroek
1303*83ee113eSDavid van Moolenbroek ret = NULL;
1304*83ee113eSDavid van Moolenbroek if ((name = ldap_get_values_len (ld, ent, "cn")) == NULL || name[0] == NULL)
1305*83ee113eSDavid van Moolenbroek {
1306*83ee113eSDavid van Moolenbroek if (name != NULL)
1307*83ee113eSDavid van Moolenbroek ldap_value_free_len (name);
1308*83ee113eSDavid van Moolenbroek
1309*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
1310*83ee113eSDavid van Moolenbroek ret = ldap_get_dn (ld, ent);
1311*83ee113eSDavid van Moolenbroek if (ret != NULL)
1312*83ee113eSDavid van Moolenbroek {
1313*83ee113eSDavid van Moolenbroek log_info ("Cannot get cn attribute for LDAP entry %s", ret);
1314*83ee113eSDavid van Moolenbroek ldap_memfree(ret);
1315*83ee113eSDavid van Moolenbroek }
1316*83ee113eSDavid van Moolenbroek #endif
1317*83ee113eSDavid van Moolenbroek return (NULL);
1318*83ee113eSDavid van Moolenbroek }
1319*83ee113eSDavid van Moolenbroek
1320*83ee113eSDavid van Moolenbroek ret = dmalloc (strlen (name[0]->bv_val) + 1, MDL);
1321*83ee113eSDavid van Moolenbroek strcpy (ret, name[0]->bv_val);
1322*83ee113eSDavid van Moolenbroek ldap_value_free_len (name);
1323*83ee113eSDavid van Moolenbroek
1324*83ee113eSDavid van Moolenbroek return (ret);
1325*83ee113eSDavid van Moolenbroek }
1326*83ee113eSDavid van Moolenbroek
1327*83ee113eSDavid van Moolenbroek
1328*83ee113eSDavid van Moolenbroek static int
getfqhostname(char * fqhost,size_t size)1329*83ee113eSDavid van Moolenbroek getfqhostname(char *fqhost, size_t size)
1330*83ee113eSDavid van Moolenbroek {
1331*83ee113eSDavid van Moolenbroek #if defined(MAXHOSTNAMELEN)
1332*83ee113eSDavid van Moolenbroek char hname[MAXHOSTNAMELEN];
1333*83ee113eSDavid van Moolenbroek #else
1334*83ee113eSDavid van Moolenbroek char hname[65];
1335*83ee113eSDavid van Moolenbroek #endif
1336*83ee113eSDavid van Moolenbroek struct hostent *hp;
1337*83ee113eSDavid van Moolenbroek
1338*83ee113eSDavid van Moolenbroek if(NULL == fqhost || 1 >= size)
1339*83ee113eSDavid van Moolenbroek return -1;
1340*83ee113eSDavid van Moolenbroek
1341*83ee113eSDavid van Moolenbroek memset(hname, 0, sizeof(hname));
1342*83ee113eSDavid van Moolenbroek if( gethostname(hname, sizeof(hname)-1))
1343*83ee113eSDavid van Moolenbroek return -1;
1344*83ee113eSDavid van Moolenbroek
1345*83ee113eSDavid van Moolenbroek if(NULL == (hp = gethostbyname(hname)))
1346*83ee113eSDavid van Moolenbroek return -1;
1347*83ee113eSDavid van Moolenbroek
1348*83ee113eSDavid van Moolenbroek strncpy(fqhost, hp->h_name, size-1);
1349*83ee113eSDavid van Moolenbroek fqhost[size-1] = '\0';
1350*83ee113eSDavid van Moolenbroek return 0;
1351*83ee113eSDavid van Moolenbroek }
1352*83ee113eSDavid van Moolenbroek
1353*83ee113eSDavid van Moolenbroek
1354*83ee113eSDavid van Moolenbroek isc_result_t
ldap_read_config(void)1355*83ee113eSDavid van Moolenbroek ldap_read_config (void)
1356*83ee113eSDavid van Moolenbroek {
1357*83ee113eSDavid van Moolenbroek LDAPMessage * ldres, * hostres, * ent, * hostent;
1358*83ee113eSDavid van Moolenbroek char hfilter[1024], sfilter[1024], fqdn[257];
1359*83ee113eSDavid van Moolenbroek char *buffer, *hostdn;
1360*83ee113eSDavid van Moolenbroek ldap_dn_node *curr = NULL;
1361*83ee113eSDavid van Moolenbroek struct parse *cfile;
1362*83ee113eSDavid van Moolenbroek struct utsname unme;
1363*83ee113eSDavid van Moolenbroek isc_result_t res;
1364*83ee113eSDavid van Moolenbroek size_t length;
1365*83ee113eSDavid van Moolenbroek int ret, cnt;
1366*83ee113eSDavid van Moolenbroek struct berval **tempbv = NULL;
1367*83ee113eSDavid van Moolenbroek
1368*83ee113eSDavid van Moolenbroek if (ld == NULL)
1369*83ee113eSDavid van Moolenbroek ldap_start ();
1370*83ee113eSDavid van Moolenbroek if (ld == NULL)
1371*83ee113eSDavid van Moolenbroek return (ldap_server == NULL ? ISC_R_SUCCESS : ISC_R_FAILURE);
1372*83ee113eSDavid van Moolenbroek
1373*83ee113eSDavid van Moolenbroek buffer = dmalloc (LDAP_BUFFER_SIZE+1, MDL);
1374*83ee113eSDavid van Moolenbroek if (buffer == NULL)
1375*83ee113eSDavid van Moolenbroek return (ISC_R_FAILURE);
1376*83ee113eSDavid van Moolenbroek
1377*83ee113eSDavid van Moolenbroek cfile = (struct parse *) NULL;
1378*83ee113eSDavid van Moolenbroek res = new_parse (&cfile, -1, buffer, LDAP_BUFFER_SIZE, "LDAP", 0);
1379*83ee113eSDavid van Moolenbroek if (res != ISC_R_SUCCESS)
1380*83ee113eSDavid van Moolenbroek return (res);
1381*83ee113eSDavid van Moolenbroek
1382*83ee113eSDavid van Moolenbroek uname (&unme);
1383*83ee113eSDavid van Moolenbroek if (ldap_dhcp_server_cn != NULL)
1384*83ee113eSDavid van Moolenbroek {
1385*83ee113eSDavid van Moolenbroek snprintf (hfilter, sizeof (hfilter),
1386*83ee113eSDavid van Moolenbroek "(&(objectClass=dhcpServer)(cn=%s))", ldap_dhcp_server_cn);
1387*83ee113eSDavid van Moolenbroek }
1388*83ee113eSDavid van Moolenbroek else
1389*83ee113eSDavid van Moolenbroek {
1390*83ee113eSDavid van Moolenbroek if(0 == getfqhostname(fqdn, sizeof(fqdn)))
1391*83ee113eSDavid van Moolenbroek {
1392*83ee113eSDavid van Moolenbroek snprintf (hfilter, sizeof (hfilter),
1393*83ee113eSDavid van Moolenbroek "(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))",
1394*83ee113eSDavid van Moolenbroek unme.nodename, fqdn);
1395*83ee113eSDavid van Moolenbroek }
1396*83ee113eSDavid van Moolenbroek else
1397*83ee113eSDavid van Moolenbroek {
1398*83ee113eSDavid van Moolenbroek snprintf (hfilter, sizeof (hfilter),
1399*83ee113eSDavid van Moolenbroek "(&(objectClass=dhcpServer)(cn=%s))", unme.nodename);
1400*83ee113eSDavid van Moolenbroek }
1401*83ee113eSDavid van Moolenbroek
1402*83ee113eSDavid van Moolenbroek }
1403*83ee113eSDavid van Moolenbroek hostres = NULL;
1404*83ee113eSDavid van Moolenbroek if ((ret = ldap_search_ext_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE,
1405*83ee113eSDavid van Moolenbroek hfilter, NULL, 0, NULL, NULL, NULL, 0,
1406*83ee113eSDavid van Moolenbroek &hostres)) != LDAP_SUCCESS)
1407*83ee113eSDavid van Moolenbroek {
1408*83ee113eSDavid van Moolenbroek log_error ("Cannot find host LDAP entry %s %s",
1409*83ee113eSDavid van Moolenbroek ((ldap_dhcp_server_cn == NULL)?(unme.nodename):(ldap_dhcp_server_cn)), hfilter);
1410*83ee113eSDavid van Moolenbroek if(NULL != hostres)
1411*83ee113eSDavid van Moolenbroek ldap_msgfree (hostres);
1412*83ee113eSDavid van Moolenbroek ldap_stop();
1413*83ee113eSDavid van Moolenbroek return (ISC_R_FAILURE);
1414*83ee113eSDavid van Moolenbroek }
1415*83ee113eSDavid van Moolenbroek
1416*83ee113eSDavid van Moolenbroek if ((hostent = ldap_first_entry (ld, hostres)) == NULL)
1417*83ee113eSDavid van Moolenbroek {
1418*83ee113eSDavid van Moolenbroek log_error ("Error: Cannot find LDAP entry matching %s", hfilter);
1419*83ee113eSDavid van Moolenbroek ldap_msgfree (hostres);
1420*83ee113eSDavid van Moolenbroek ldap_stop();
1421*83ee113eSDavid van Moolenbroek return (ISC_R_FAILURE);
1422*83ee113eSDavid van Moolenbroek }
1423*83ee113eSDavid van Moolenbroek
1424*83ee113eSDavid van Moolenbroek hostdn = ldap_get_dn (ld, hostent);
1425*83ee113eSDavid van Moolenbroek #if defined(DEBUG_LDAP)
1426*83ee113eSDavid van Moolenbroek if (hostdn != NULL)
1427*83ee113eSDavid van Moolenbroek log_info ("Found dhcpServer LDAP entry '%s'", hostdn);
1428*83ee113eSDavid van Moolenbroek #endif
1429*83ee113eSDavid van Moolenbroek
1430*83ee113eSDavid van Moolenbroek if (hostdn == NULL ||
1431*83ee113eSDavid van Moolenbroek (tempbv = ldap_get_values_len (ld, hostent, "dhcpServiceDN")) == NULL ||
1432*83ee113eSDavid van Moolenbroek tempbv[0] == NULL)
1433*83ee113eSDavid van Moolenbroek {
1434*83ee113eSDavid van Moolenbroek log_error ("Error: Cannot find LDAP entry matching %s", hfilter);
1435*83ee113eSDavid van Moolenbroek
1436*83ee113eSDavid van Moolenbroek if (tempbv != NULL)
1437*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
1438*83ee113eSDavid van Moolenbroek
1439*83ee113eSDavid van Moolenbroek if (hostdn)
1440*83ee113eSDavid van Moolenbroek ldap_memfree (hostdn);
1441*83ee113eSDavid van Moolenbroek ldap_msgfree (hostres);
1442*83ee113eSDavid van Moolenbroek ldap_stop();
1443*83ee113eSDavid van Moolenbroek return (ISC_R_FAILURE);
1444*83ee113eSDavid van Moolenbroek }
1445*83ee113eSDavid van Moolenbroek
1446*83ee113eSDavid van Moolenbroek #if defined(DEBUG_LDAP)
1447*83ee113eSDavid van Moolenbroek log_info ("LDAP: Parsing dhcpServer options '%s' ...", hostdn);
1448*83ee113eSDavid van Moolenbroek #endif
1449*83ee113eSDavid van Moolenbroek
1450*83ee113eSDavid van Moolenbroek cfile->inbuf[0] = '\0';
1451*83ee113eSDavid van Moolenbroek ldap_parse_entry_options(hostent, cfile->inbuf, LDAP_BUFFER_SIZE, NULL);
1452*83ee113eSDavid van Moolenbroek cfile->buflen = strlen (cfile->inbuf);
1453*83ee113eSDavid van Moolenbroek if(cfile->buflen > 0)
1454*83ee113eSDavid van Moolenbroek {
1455*83ee113eSDavid van Moolenbroek ldap_write_debug (cfile->inbuf, cfile->buflen);
1456*83ee113eSDavid van Moolenbroek
1457*83ee113eSDavid van Moolenbroek res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
1458*83ee113eSDavid van Moolenbroek if (res != ISC_R_SUCCESS)
1459*83ee113eSDavid van Moolenbroek {
1460*83ee113eSDavid van Moolenbroek log_error ("LDAP: cannot parse dhcpServer entry '%s'", hostdn);
1461*83ee113eSDavid van Moolenbroek ldap_memfree (hostdn);
1462*83ee113eSDavid van Moolenbroek ldap_stop();
1463*83ee113eSDavid van Moolenbroek return res;
1464*83ee113eSDavid van Moolenbroek }
1465*83ee113eSDavid van Moolenbroek cfile->inbuf[0] = '\0';
1466*83ee113eSDavid van Moolenbroek }
1467*83ee113eSDavid van Moolenbroek ldap_msgfree (hostres);
1468*83ee113eSDavid van Moolenbroek
1469*83ee113eSDavid van Moolenbroek /*
1470*83ee113eSDavid van Moolenbroek ** attach ldap (tree) read function now
1471*83ee113eSDavid van Moolenbroek */
1472*83ee113eSDavid van Moolenbroek cfile->bufix = cfile->buflen = 0;
1473*83ee113eSDavid van Moolenbroek cfile->read_function = ldap_read_function;
1474*83ee113eSDavid van Moolenbroek
1475*83ee113eSDavid van Moolenbroek res = ISC_R_SUCCESS;
1476*83ee113eSDavid van Moolenbroek for (cnt=0; tempbv[cnt] != NULL; cnt++)
1477*83ee113eSDavid van Moolenbroek {
1478*83ee113eSDavid van Moolenbroek snprintf(sfilter, sizeof(sfilter), "(&(objectClass=dhcpService)"
1479*83ee113eSDavid van Moolenbroek "(|(dhcpPrimaryDN=%s)(dhcpSecondaryDN=%s)))",
1480*83ee113eSDavid van Moolenbroek hostdn, hostdn);
1481*83ee113eSDavid van Moolenbroek ldres = NULL;
1482*83ee113eSDavid van Moolenbroek if ((ret = ldap_search_ext_s (ld, tempbv[cnt]->bv_val, LDAP_SCOPE_BASE,
1483*83ee113eSDavid van Moolenbroek sfilter, NULL, 0, NULL, NULL, NULL,
1484*83ee113eSDavid van Moolenbroek 0, &ldres)) != LDAP_SUCCESS)
1485*83ee113eSDavid van Moolenbroek {
1486*83ee113eSDavid van Moolenbroek log_error ("Error searching for dhcpServiceDN '%s': %s. Please update the LDAP entry '%s'",
1487*83ee113eSDavid van Moolenbroek tempbv[cnt]->bv_val, ldap_err2string (ret), hostdn);
1488*83ee113eSDavid van Moolenbroek if(NULL != ldres)
1489*83ee113eSDavid van Moolenbroek ldap_msgfree(ldres);
1490*83ee113eSDavid van Moolenbroek res = ISC_R_FAILURE;
1491*83ee113eSDavid van Moolenbroek break;
1492*83ee113eSDavid van Moolenbroek }
1493*83ee113eSDavid van Moolenbroek
1494*83ee113eSDavid van Moolenbroek if ((ent = ldap_first_entry (ld, ldres)) == NULL)
1495*83ee113eSDavid van Moolenbroek {
1496*83ee113eSDavid van Moolenbroek log_error ("Error: Cannot find dhcpService DN '%s' with primary or secondary server reference. Please update the LDAP server entry '%s'",
1497*83ee113eSDavid van Moolenbroek tempbv[cnt]->bv_val, hostdn);
1498*83ee113eSDavid van Moolenbroek
1499*83ee113eSDavid van Moolenbroek ldap_msgfree(ldres);
1500*83ee113eSDavid van Moolenbroek res = ISC_R_FAILURE;
1501*83ee113eSDavid van Moolenbroek break;
1502*83ee113eSDavid van Moolenbroek }
1503*83ee113eSDavid van Moolenbroek
1504*83ee113eSDavid van Moolenbroek /*
1505*83ee113eSDavid van Moolenbroek ** FIXME: how to free the remembered dn's on exit?
1506*83ee113eSDavid van Moolenbroek ** This should be OK if dmalloc registers the
1507*83ee113eSDavid van Moolenbroek ** memory it allocated and frees it on exit..
1508*83ee113eSDavid van Moolenbroek */
1509*83ee113eSDavid van Moolenbroek
1510*83ee113eSDavid van Moolenbroek curr = dmalloc (sizeof (*curr), MDL);
1511*83ee113eSDavid van Moolenbroek if (curr != NULL)
1512*83ee113eSDavid van Moolenbroek {
1513*83ee113eSDavid van Moolenbroek length = strlen (tempbv[cnt]->bv_val);
1514*83ee113eSDavid van Moolenbroek curr->dn = dmalloc (length + 1, MDL);
1515*83ee113eSDavid van Moolenbroek if (curr->dn == NULL)
1516*83ee113eSDavid van Moolenbroek {
1517*83ee113eSDavid van Moolenbroek dfree (curr, MDL);
1518*83ee113eSDavid van Moolenbroek curr = NULL;
1519*83ee113eSDavid van Moolenbroek }
1520*83ee113eSDavid van Moolenbroek else
1521*83ee113eSDavid van Moolenbroek strcpy (curr->dn, tempbv[cnt]->bv_val);
1522*83ee113eSDavid van Moolenbroek }
1523*83ee113eSDavid van Moolenbroek
1524*83ee113eSDavid van Moolenbroek if (curr != NULL)
1525*83ee113eSDavid van Moolenbroek {
1526*83ee113eSDavid van Moolenbroek curr->refs++;
1527*83ee113eSDavid van Moolenbroek
1528*83ee113eSDavid van Moolenbroek /* append to service-dn list */
1529*83ee113eSDavid van Moolenbroek if (ldap_service_dn_tail != NULL)
1530*83ee113eSDavid van Moolenbroek ldap_service_dn_tail->next = curr;
1531*83ee113eSDavid van Moolenbroek else
1532*83ee113eSDavid van Moolenbroek ldap_service_dn_head = curr;
1533*83ee113eSDavid van Moolenbroek
1534*83ee113eSDavid van Moolenbroek ldap_service_dn_tail = curr;
1535*83ee113eSDavid van Moolenbroek }
1536*83ee113eSDavid van Moolenbroek else
1537*83ee113eSDavid van Moolenbroek log_fatal ("no memory to remember ldap service dn");
1538*83ee113eSDavid van Moolenbroek
1539*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
1540*83ee113eSDavid van Moolenbroek log_info ("LDAP: Parsing dhcpService DN '%s' ...", tempbv[cnt]);
1541*83ee113eSDavid van Moolenbroek #endif
1542*83ee113eSDavid van Moolenbroek add_to_config_stack (ldres, ent);
1543*83ee113eSDavid van Moolenbroek res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
1544*83ee113eSDavid van Moolenbroek if (res != ISC_R_SUCCESS)
1545*83ee113eSDavid van Moolenbroek {
1546*83ee113eSDavid van Moolenbroek log_error ("LDAP: cannot parse dhcpService entry '%s'", tempbv[cnt]->bv_val);
1547*83ee113eSDavid van Moolenbroek break;
1548*83ee113eSDavid van Moolenbroek }
1549*83ee113eSDavid van Moolenbroek }
1550*83ee113eSDavid van Moolenbroek
1551*83ee113eSDavid van Moolenbroek end_parse (&cfile);
1552*83ee113eSDavid van Moolenbroek ldap_close_debug_fd();
1553*83ee113eSDavid van Moolenbroek
1554*83ee113eSDavid van Moolenbroek ldap_memfree (hostdn);
1555*83ee113eSDavid van Moolenbroek ldap_value_free_len (tempbv);
1556*83ee113eSDavid van Moolenbroek
1557*83ee113eSDavid van Moolenbroek if (res != ISC_R_SUCCESS)
1558*83ee113eSDavid van Moolenbroek {
1559*83ee113eSDavid van Moolenbroek struct ldap_config_stack *temp_stack;
1560*83ee113eSDavid van Moolenbroek
1561*83ee113eSDavid van Moolenbroek while ((curr = ldap_service_dn_head) != NULL)
1562*83ee113eSDavid van Moolenbroek {
1563*83ee113eSDavid van Moolenbroek ldap_service_dn_head = curr->next;
1564*83ee113eSDavid van Moolenbroek dfree (curr->dn, MDL);
1565*83ee113eSDavid van Moolenbroek dfree (curr, MDL);
1566*83ee113eSDavid van Moolenbroek }
1567*83ee113eSDavid van Moolenbroek
1568*83ee113eSDavid van Moolenbroek ldap_service_dn_tail = NULL;
1569*83ee113eSDavid van Moolenbroek
1570*83ee113eSDavid van Moolenbroek while ((temp_stack = ldap_stack) != NULL)
1571*83ee113eSDavid van Moolenbroek {
1572*83ee113eSDavid van Moolenbroek ldap_stack = temp_stack->next;
1573*83ee113eSDavid van Moolenbroek free_stack_entry (temp_stack);
1574*83ee113eSDavid van Moolenbroek }
1575*83ee113eSDavid van Moolenbroek
1576*83ee113eSDavid van Moolenbroek ldap_stop();
1577*83ee113eSDavid van Moolenbroek }
1578*83ee113eSDavid van Moolenbroek
1579*83ee113eSDavid van Moolenbroek /* Unbind from ldap immediately after reading config in static mode. */
1580*83ee113eSDavid van Moolenbroek if (ldap_method == LDAP_METHOD_STATIC)
1581*83ee113eSDavid van Moolenbroek ldap_stop();
1582*83ee113eSDavid van Moolenbroek
1583*83ee113eSDavid van Moolenbroek return (res);
1584*83ee113eSDavid van Moolenbroek }
1585*83ee113eSDavid van Moolenbroek
1586*83ee113eSDavid van Moolenbroek
1587*83ee113eSDavid van Moolenbroek /* This function will parse the dhcpOption and dhcpStatements field in the LDAP
1588*83ee113eSDavid van Moolenbroek entry if it exists. Right now, type will be either HOST_DECL or CLASS_DECL.
1589*83ee113eSDavid van Moolenbroek If we are parsing a HOST_DECL, this always returns 0. If we are parsing a
1590*83ee113eSDavid van Moolenbroek CLASS_DECL, this will return what the current lease limit is in LDAP. If
1591*83ee113eSDavid van Moolenbroek there is no lease limit specified, we return 0 */
1592*83ee113eSDavid van Moolenbroek
1593*83ee113eSDavid van Moolenbroek static int
ldap_parse_options(LDAPMessage * ent,struct group * group,int type,struct host_decl * host,struct class ** class)1594*83ee113eSDavid van Moolenbroek ldap_parse_options (LDAPMessage * ent, struct group *group,
1595*83ee113eSDavid van Moolenbroek int type, struct host_decl *host,
1596*83ee113eSDavid van Moolenbroek struct class **class)
1597*83ee113eSDavid van Moolenbroek {
1598*83ee113eSDavid van Moolenbroek int declaration, lease_limit;
1599*83ee113eSDavid van Moolenbroek char option_buffer[8192];
1600*83ee113eSDavid van Moolenbroek enum dhcp_token token;
1601*83ee113eSDavid van Moolenbroek struct parse *cfile;
1602*83ee113eSDavid van Moolenbroek isc_result_t res;
1603*83ee113eSDavid van Moolenbroek const char *val;
1604*83ee113eSDavid van Moolenbroek
1605*83ee113eSDavid van Moolenbroek lease_limit = 0;
1606*83ee113eSDavid van Moolenbroek *option_buffer = '\0';
1607*83ee113eSDavid van Moolenbroek
1608*83ee113eSDavid van Moolenbroek /* This block of code will try to find the parent of the host, and
1609*83ee113eSDavid van Moolenbroek if it is a group object, fetch the options and apply to the host. */
1610*83ee113eSDavid van Moolenbroek if (type == HOST_DECL)
1611*83ee113eSDavid van Moolenbroek {
1612*83ee113eSDavid van Moolenbroek char *hostdn, *basedn, *temp1, *temp2, filter[1024];
1613*83ee113eSDavid van Moolenbroek LDAPMessage *groupdn, *entry;
1614*83ee113eSDavid van Moolenbroek int ret;
1615*83ee113eSDavid van Moolenbroek
1616*83ee113eSDavid van Moolenbroek hostdn = ldap_get_dn (ld, ent);
1617*83ee113eSDavid van Moolenbroek if( hostdn != NULL)
1618*83ee113eSDavid van Moolenbroek {
1619*83ee113eSDavid van Moolenbroek basedn = NULL;
1620*83ee113eSDavid van Moolenbroek
1621*83ee113eSDavid van Moolenbroek temp1 = strchr (hostdn, '=');
1622*83ee113eSDavid van Moolenbroek if (temp1 != NULL)
1623*83ee113eSDavid van Moolenbroek temp1 = strchr (++temp1, '=');
1624*83ee113eSDavid van Moolenbroek if (temp1 != NULL)
1625*83ee113eSDavid van Moolenbroek temp2 = strchr (++temp1, ',');
1626*83ee113eSDavid van Moolenbroek else
1627*83ee113eSDavid van Moolenbroek temp2 = NULL;
1628*83ee113eSDavid van Moolenbroek
1629*83ee113eSDavid van Moolenbroek if (temp2 != NULL)
1630*83ee113eSDavid van Moolenbroek {
1631*83ee113eSDavid van Moolenbroek snprintf (filter, sizeof(filter),
1632*83ee113eSDavid van Moolenbroek "(&(cn=%.*s)(objectClass=dhcpGroup))",
1633*83ee113eSDavid van Moolenbroek (int)(temp2 - temp1), temp1);
1634*83ee113eSDavid van Moolenbroek
1635*83ee113eSDavid van Moolenbroek basedn = strchr (temp1, ',');
1636*83ee113eSDavid van Moolenbroek if (basedn != NULL)
1637*83ee113eSDavid van Moolenbroek ++basedn;
1638*83ee113eSDavid van Moolenbroek }
1639*83ee113eSDavid van Moolenbroek
1640*83ee113eSDavid van Moolenbroek if (basedn != NULL && *basedn != '\0')
1641*83ee113eSDavid van Moolenbroek {
1642*83ee113eSDavid van Moolenbroek ret = ldap_search_ext_s (ld, basedn, LDAP_SCOPE_SUBTREE, filter,
1643*83ee113eSDavid van Moolenbroek NULL, 0, NULL, NULL, NULL, 0, &groupdn);
1644*83ee113eSDavid van Moolenbroek if (ret == LDAP_SUCCESS)
1645*83ee113eSDavid van Moolenbroek {
1646*83ee113eSDavid van Moolenbroek if ((entry = ldap_first_entry (ld, groupdn)) != NULL)
1647*83ee113eSDavid van Moolenbroek {
1648*83ee113eSDavid van Moolenbroek res = ldap_parse_entry_options (entry, option_buffer,
1649*83ee113eSDavid van Moolenbroek sizeof(option_buffer) - 1,
1650*83ee113eSDavid van Moolenbroek &lease_limit);
1651*83ee113eSDavid van Moolenbroek if (res != ISC_R_SUCCESS)
1652*83ee113eSDavid van Moolenbroek {
1653*83ee113eSDavid van Moolenbroek /* reset option buffer discarding any results */
1654*83ee113eSDavid van Moolenbroek *option_buffer = '\0';
1655*83ee113eSDavid van Moolenbroek lease_limit = 0;
1656*83ee113eSDavid van Moolenbroek }
1657*83ee113eSDavid van Moolenbroek }
1658*83ee113eSDavid van Moolenbroek ldap_msgfree( groupdn);
1659*83ee113eSDavid van Moolenbroek }
1660*83ee113eSDavid van Moolenbroek }
1661*83ee113eSDavid van Moolenbroek ldap_memfree( hostdn);
1662*83ee113eSDavid van Moolenbroek }
1663*83ee113eSDavid van Moolenbroek }
1664*83ee113eSDavid van Moolenbroek
1665*83ee113eSDavid van Moolenbroek res = ldap_parse_entry_options (ent, option_buffer, sizeof(option_buffer) - 1,
1666*83ee113eSDavid van Moolenbroek &lease_limit);
1667*83ee113eSDavid van Moolenbroek if (res != ISC_R_SUCCESS)
1668*83ee113eSDavid van Moolenbroek return (lease_limit);
1669*83ee113eSDavid van Moolenbroek
1670*83ee113eSDavid van Moolenbroek option_buffer[sizeof(option_buffer) - 1] = '\0';
1671*83ee113eSDavid van Moolenbroek if (*option_buffer == '\0')
1672*83ee113eSDavid van Moolenbroek return (lease_limit);
1673*83ee113eSDavid van Moolenbroek
1674*83ee113eSDavid van Moolenbroek cfile = (struct parse *) NULL;
1675*83ee113eSDavid van Moolenbroek res = new_parse (&cfile, -1, option_buffer, strlen (option_buffer),
1676*83ee113eSDavid van Moolenbroek type == HOST_DECL ? "LDAP-HOST" : "LDAP-SUBCLASS", 0);
1677*83ee113eSDavid van Moolenbroek if (res != ISC_R_SUCCESS)
1678*83ee113eSDavid van Moolenbroek return (lease_limit);
1679*83ee113eSDavid van Moolenbroek
1680*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
1681*83ee113eSDavid van Moolenbroek log_info ("Sending the following options: '%s'", option_buffer);
1682*83ee113eSDavid van Moolenbroek #endif
1683*83ee113eSDavid van Moolenbroek
1684*83ee113eSDavid van Moolenbroek declaration = 0;
1685*83ee113eSDavid van Moolenbroek do
1686*83ee113eSDavid van Moolenbroek {
1687*83ee113eSDavid van Moolenbroek token = peek_token (&val, NULL, cfile);
1688*83ee113eSDavid van Moolenbroek if (token == END_OF_FILE)
1689*83ee113eSDavid van Moolenbroek break;
1690*83ee113eSDavid van Moolenbroek declaration = parse_statement (cfile, group, type, host, declaration);
1691*83ee113eSDavid van Moolenbroek } while (1);
1692*83ee113eSDavid van Moolenbroek
1693*83ee113eSDavid van Moolenbroek end_parse (&cfile);
1694*83ee113eSDavid van Moolenbroek
1695*83ee113eSDavid van Moolenbroek return (lease_limit);
1696*83ee113eSDavid van Moolenbroek }
1697*83ee113eSDavid van Moolenbroek
1698*83ee113eSDavid van Moolenbroek
1699*83ee113eSDavid van Moolenbroek
1700*83ee113eSDavid van Moolenbroek int
find_haddr_in_ldap(struct host_decl ** hp,int htype,unsigned hlen,const unsigned char * haddr,const char * file,int line)1701*83ee113eSDavid van Moolenbroek find_haddr_in_ldap (struct host_decl **hp, int htype, unsigned hlen,
1702*83ee113eSDavid van Moolenbroek const unsigned char *haddr, const char *file, int line)
1703*83ee113eSDavid van Moolenbroek {
1704*83ee113eSDavid van Moolenbroek char buf[128], *type_str;
1705*83ee113eSDavid van Moolenbroek LDAPMessage * res, *ent;
1706*83ee113eSDavid van Moolenbroek struct host_decl * host;
1707*83ee113eSDavid van Moolenbroek isc_result_t status;
1708*83ee113eSDavid van Moolenbroek ldap_dn_node *curr;
1709*83ee113eSDavid van Moolenbroek int ret;
1710*83ee113eSDavid van Moolenbroek
1711*83ee113eSDavid van Moolenbroek if (ldap_method == LDAP_METHOD_STATIC)
1712*83ee113eSDavid van Moolenbroek return (0);
1713*83ee113eSDavid van Moolenbroek
1714*83ee113eSDavid van Moolenbroek if (ld == NULL)
1715*83ee113eSDavid van Moolenbroek ldap_start ();
1716*83ee113eSDavid van Moolenbroek if (ld == NULL)
1717*83ee113eSDavid van Moolenbroek return (0);
1718*83ee113eSDavid van Moolenbroek
1719*83ee113eSDavid van Moolenbroek switch (htype)
1720*83ee113eSDavid van Moolenbroek {
1721*83ee113eSDavid van Moolenbroek case HTYPE_ETHER:
1722*83ee113eSDavid van Moolenbroek type_str = "ethernet";
1723*83ee113eSDavid van Moolenbroek break;
1724*83ee113eSDavid van Moolenbroek case HTYPE_IEEE802:
1725*83ee113eSDavid van Moolenbroek type_str = "token-ring";
1726*83ee113eSDavid van Moolenbroek break;
1727*83ee113eSDavid van Moolenbroek case HTYPE_FDDI:
1728*83ee113eSDavid van Moolenbroek type_str = "fddi";
1729*83ee113eSDavid van Moolenbroek break;
1730*83ee113eSDavid van Moolenbroek default:
1731*83ee113eSDavid van Moolenbroek log_info ("Ignoring unknown type %d", htype);
1732*83ee113eSDavid van Moolenbroek return (0);
1733*83ee113eSDavid van Moolenbroek }
1734*83ee113eSDavid van Moolenbroek
1735*83ee113eSDavid van Moolenbroek /*
1736*83ee113eSDavid van Moolenbroek ** FIXME: It is not guaranteed, that the dhcpHWAddress attribute
1737*83ee113eSDavid van Moolenbroek ** contains _exactly_ "type addr" with one space between!
1738*83ee113eSDavid van Moolenbroek */
1739*83ee113eSDavid van Moolenbroek snprintf (buf, sizeof (buf),
1740*83ee113eSDavid van Moolenbroek "(&(objectClass=dhcpHost)(dhcpHWAddress=%s %s))",
1741*83ee113eSDavid van Moolenbroek type_str, print_hw_addr (htype, hlen, haddr));
1742*83ee113eSDavid van Moolenbroek
1743*83ee113eSDavid van Moolenbroek res = ent = NULL;
1744*83ee113eSDavid van Moolenbroek for (curr = ldap_service_dn_head;
1745*83ee113eSDavid van Moolenbroek curr != NULL && *curr->dn != '\0';
1746*83ee113eSDavid van Moolenbroek curr = curr->next)
1747*83ee113eSDavid van Moolenbroek {
1748*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
1749*83ee113eSDavid van Moolenbroek log_info ("Searching for %s in LDAP tree %s", buf, curr->dn);
1750*83ee113eSDavid van Moolenbroek #endif
1751*83ee113eSDavid van Moolenbroek ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL, 0,
1752*83ee113eSDavid van Moolenbroek NULL, NULL, NULL, 0, &res);
1753*83ee113eSDavid van Moolenbroek
1754*83ee113eSDavid van Moolenbroek if(ret == LDAP_SERVER_DOWN)
1755*83ee113eSDavid van Moolenbroek {
1756*83ee113eSDavid van Moolenbroek log_info ("LDAP server was down, trying to reconnect...");
1757*83ee113eSDavid van Moolenbroek
1758*83ee113eSDavid van Moolenbroek ldap_stop();
1759*83ee113eSDavid van Moolenbroek ldap_start();
1760*83ee113eSDavid van Moolenbroek if(ld == NULL)
1761*83ee113eSDavid van Moolenbroek {
1762*83ee113eSDavid van Moolenbroek log_info ("LDAP reconnect failed - try again later...");
1763*83ee113eSDavid van Moolenbroek return (0);
1764*83ee113eSDavid van Moolenbroek }
1765*83ee113eSDavid van Moolenbroek
1766*83ee113eSDavid van Moolenbroek ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL,
1767*83ee113eSDavid van Moolenbroek 0, NULL, NULL, NULL, 0, &res);
1768*83ee113eSDavid van Moolenbroek }
1769*83ee113eSDavid van Moolenbroek
1770*83ee113eSDavid van Moolenbroek if (ret == LDAP_SUCCESS)
1771*83ee113eSDavid van Moolenbroek {
1772*83ee113eSDavid van Moolenbroek if( (ent = ldap_first_entry (ld, res)) != NULL)
1773*83ee113eSDavid van Moolenbroek break; /* search OK and have entry */
1774*83ee113eSDavid van Moolenbroek
1775*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
1776*83ee113eSDavid van Moolenbroek log_info ("No host entry for %s in LDAP tree %s",
1777*83ee113eSDavid van Moolenbroek buf, curr->dn);
1778*83ee113eSDavid van Moolenbroek #endif
1779*83ee113eSDavid van Moolenbroek if(res)
1780*83ee113eSDavid van Moolenbroek {
1781*83ee113eSDavid van Moolenbroek ldap_msgfree (res);
1782*83ee113eSDavid van Moolenbroek res = NULL;
1783*83ee113eSDavid van Moolenbroek }
1784*83ee113eSDavid van Moolenbroek }
1785*83ee113eSDavid van Moolenbroek else
1786*83ee113eSDavid van Moolenbroek {
1787*83ee113eSDavid van Moolenbroek if(res)
1788*83ee113eSDavid van Moolenbroek {
1789*83ee113eSDavid van Moolenbroek ldap_msgfree (res);
1790*83ee113eSDavid van Moolenbroek res = NULL;
1791*83ee113eSDavid van Moolenbroek }
1792*83ee113eSDavid van Moolenbroek
1793*83ee113eSDavid van Moolenbroek if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
1794*83ee113eSDavid van Moolenbroek {
1795*83ee113eSDavid van Moolenbroek log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
1796*83ee113eSDavid van Moolenbroek curr->dn, ldap_err2string (ret));
1797*83ee113eSDavid van Moolenbroek ldap_stop();
1798*83ee113eSDavid van Moolenbroek return (0);
1799*83ee113eSDavid van Moolenbroek }
1800*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
1801*83ee113eSDavid van Moolenbroek else
1802*83ee113eSDavid van Moolenbroek {
1803*83ee113eSDavid van Moolenbroek log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
1804*83ee113eSDavid van Moolenbroek ldap_err2string (ret), buf, curr->dn);
1805*83ee113eSDavid van Moolenbroek }
1806*83ee113eSDavid van Moolenbroek #endif
1807*83ee113eSDavid van Moolenbroek }
1808*83ee113eSDavid van Moolenbroek }
1809*83ee113eSDavid van Moolenbroek
1810*83ee113eSDavid van Moolenbroek if (res && ent)
1811*83ee113eSDavid van Moolenbroek {
1812*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
1813*83ee113eSDavid van Moolenbroek char *dn = ldap_get_dn (ld, ent);
1814*83ee113eSDavid van Moolenbroek if (dn != NULL)
1815*83ee113eSDavid van Moolenbroek {
1816*83ee113eSDavid van Moolenbroek log_info ("Found dhcpHWAddress LDAP entry %s", dn);
1817*83ee113eSDavid van Moolenbroek ldap_memfree(dn);
1818*83ee113eSDavid van Moolenbroek }
1819*83ee113eSDavid van Moolenbroek #endif
1820*83ee113eSDavid van Moolenbroek
1821*83ee113eSDavid van Moolenbroek host = (struct host_decl *)0;
1822*83ee113eSDavid van Moolenbroek status = host_allocate (&host, MDL);
1823*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS)
1824*83ee113eSDavid van Moolenbroek {
1825*83ee113eSDavid van Moolenbroek log_fatal ("can't allocate host decl struct: %s",
1826*83ee113eSDavid van Moolenbroek isc_result_totext (status));
1827*83ee113eSDavid van Moolenbroek ldap_msgfree (res);
1828*83ee113eSDavid van Moolenbroek return (0);
1829*83ee113eSDavid van Moolenbroek }
1830*83ee113eSDavid van Moolenbroek
1831*83ee113eSDavid van Moolenbroek host->name = ldap_get_host_name (ent);
1832*83ee113eSDavid van Moolenbroek if (host->name == NULL)
1833*83ee113eSDavid van Moolenbroek {
1834*83ee113eSDavid van Moolenbroek host_dereference (&host, MDL);
1835*83ee113eSDavid van Moolenbroek ldap_msgfree (res);
1836*83ee113eSDavid van Moolenbroek return (0);
1837*83ee113eSDavid van Moolenbroek }
1838*83ee113eSDavid van Moolenbroek
1839*83ee113eSDavid van Moolenbroek if (!clone_group (&host->group, root_group, MDL))
1840*83ee113eSDavid van Moolenbroek {
1841*83ee113eSDavid van Moolenbroek log_fatal ("can't clone group for host %s", host->name);
1842*83ee113eSDavid van Moolenbroek host_dereference (&host, MDL);
1843*83ee113eSDavid van Moolenbroek ldap_msgfree (res);
1844*83ee113eSDavid van Moolenbroek return (0);
1845*83ee113eSDavid van Moolenbroek }
1846*83ee113eSDavid van Moolenbroek
1847*83ee113eSDavid van Moolenbroek ldap_parse_options (ent, host->group, HOST_DECL, host, NULL);
1848*83ee113eSDavid van Moolenbroek
1849*83ee113eSDavid van Moolenbroek *hp = host;
1850*83ee113eSDavid van Moolenbroek ldap_msgfree (res);
1851*83ee113eSDavid van Moolenbroek return (1);
1852*83ee113eSDavid van Moolenbroek }
1853*83ee113eSDavid van Moolenbroek
1854*83ee113eSDavid van Moolenbroek
1855*83ee113eSDavid van Moolenbroek if(res) ldap_msgfree (res);
1856*83ee113eSDavid van Moolenbroek return (0);
1857*83ee113eSDavid van Moolenbroek }
1858*83ee113eSDavid van Moolenbroek
1859*83ee113eSDavid van Moolenbroek
1860*83ee113eSDavid van Moolenbroek int
find_subclass_in_ldap(struct class * class,struct class ** newclass,struct data_string * data)1861*83ee113eSDavid van Moolenbroek find_subclass_in_ldap (struct class *class, struct class **newclass,
1862*83ee113eSDavid van Moolenbroek struct data_string *data)
1863*83ee113eSDavid van Moolenbroek {
1864*83ee113eSDavid van Moolenbroek LDAPMessage * res, * ent;
1865*83ee113eSDavid van Moolenbroek int ret, lease_limit;
1866*83ee113eSDavid van Moolenbroek isc_result_t status;
1867*83ee113eSDavid van Moolenbroek ldap_dn_node *curr;
1868*83ee113eSDavid van Moolenbroek char buf[1024];
1869*83ee113eSDavid van Moolenbroek
1870*83ee113eSDavid van Moolenbroek if (ldap_method == LDAP_METHOD_STATIC)
1871*83ee113eSDavid van Moolenbroek return (0);
1872*83ee113eSDavid van Moolenbroek
1873*83ee113eSDavid van Moolenbroek if (ld == NULL)
1874*83ee113eSDavid van Moolenbroek ldap_start ();
1875*83ee113eSDavid van Moolenbroek if (ld == NULL)
1876*83ee113eSDavid van Moolenbroek return (0);
1877*83ee113eSDavid van Moolenbroek
1878*83ee113eSDavid van Moolenbroek snprintf (buf, sizeof (buf),
1879*83ee113eSDavid van Moolenbroek "(&(objectClass=dhcpSubClass)(cn=%s)(dhcpClassData=%s))",
1880*83ee113eSDavid van Moolenbroek print_hex_1 (data->len, data->data, 60),
1881*83ee113eSDavid van Moolenbroek print_hex_2 (strlen (class->name), (u_int8_t *) class->name, 60));
1882*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
1883*83ee113eSDavid van Moolenbroek log_info ("Searching LDAP for %s", buf);
1884*83ee113eSDavid van Moolenbroek #endif
1885*83ee113eSDavid van Moolenbroek
1886*83ee113eSDavid van Moolenbroek res = ent = NULL;
1887*83ee113eSDavid van Moolenbroek for (curr = ldap_service_dn_head;
1888*83ee113eSDavid van Moolenbroek curr != NULL && *curr->dn != '\0';
1889*83ee113eSDavid van Moolenbroek curr = curr->next)
1890*83ee113eSDavid van Moolenbroek {
1891*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
1892*83ee113eSDavid van Moolenbroek log_info ("Searching for %s in LDAP tree %s", buf, curr->dn);
1893*83ee113eSDavid van Moolenbroek #endif
1894*83ee113eSDavid van Moolenbroek ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf, NULL, 0,
1895*83ee113eSDavid van Moolenbroek NULL, NULL, NULL, 0, &res);
1896*83ee113eSDavid van Moolenbroek
1897*83ee113eSDavid van Moolenbroek if(ret == LDAP_SERVER_DOWN)
1898*83ee113eSDavid van Moolenbroek {
1899*83ee113eSDavid van Moolenbroek log_info ("LDAP server was down, trying to reconnect...");
1900*83ee113eSDavid van Moolenbroek
1901*83ee113eSDavid van Moolenbroek ldap_stop();
1902*83ee113eSDavid van Moolenbroek ldap_start();
1903*83ee113eSDavid van Moolenbroek
1904*83ee113eSDavid van Moolenbroek if(ld == NULL)
1905*83ee113eSDavid van Moolenbroek {
1906*83ee113eSDavid van Moolenbroek log_info ("LDAP reconnect failed - try again later...");
1907*83ee113eSDavid van Moolenbroek return (0);
1908*83ee113eSDavid van Moolenbroek }
1909*83ee113eSDavid van Moolenbroek
1910*83ee113eSDavid van Moolenbroek ret = ldap_search_ext_s (ld, curr->dn, LDAP_SCOPE_SUBTREE, buf,
1911*83ee113eSDavid van Moolenbroek NULL, 0, NULL, NULL, NULL, 0, &res);
1912*83ee113eSDavid van Moolenbroek }
1913*83ee113eSDavid van Moolenbroek
1914*83ee113eSDavid van Moolenbroek if (ret == LDAP_SUCCESS)
1915*83ee113eSDavid van Moolenbroek {
1916*83ee113eSDavid van Moolenbroek if( (ent = ldap_first_entry (ld, res)) != NULL)
1917*83ee113eSDavid van Moolenbroek break; /* search OK and have entry */
1918*83ee113eSDavid van Moolenbroek
1919*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
1920*83ee113eSDavid van Moolenbroek log_info ("No subclass entry for %s in LDAP tree %s",
1921*83ee113eSDavid van Moolenbroek buf, curr->dn);
1922*83ee113eSDavid van Moolenbroek #endif
1923*83ee113eSDavid van Moolenbroek if(res)
1924*83ee113eSDavid van Moolenbroek {
1925*83ee113eSDavid van Moolenbroek ldap_msgfree (res);
1926*83ee113eSDavid van Moolenbroek res = NULL;
1927*83ee113eSDavid van Moolenbroek }
1928*83ee113eSDavid van Moolenbroek }
1929*83ee113eSDavid van Moolenbroek else
1930*83ee113eSDavid van Moolenbroek {
1931*83ee113eSDavid van Moolenbroek if(res)
1932*83ee113eSDavid van Moolenbroek {
1933*83ee113eSDavid van Moolenbroek ldap_msgfree (res);
1934*83ee113eSDavid van Moolenbroek res = NULL;
1935*83ee113eSDavid van Moolenbroek }
1936*83ee113eSDavid van Moolenbroek
1937*83ee113eSDavid van Moolenbroek if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
1938*83ee113eSDavid van Moolenbroek {
1939*83ee113eSDavid van Moolenbroek log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
1940*83ee113eSDavid van Moolenbroek curr->dn, ldap_err2string (ret));
1941*83ee113eSDavid van Moolenbroek ldap_stop();
1942*83ee113eSDavid van Moolenbroek return (0);
1943*83ee113eSDavid van Moolenbroek }
1944*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
1945*83ee113eSDavid van Moolenbroek else
1946*83ee113eSDavid van Moolenbroek {
1947*83ee113eSDavid van Moolenbroek log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
1948*83ee113eSDavid van Moolenbroek ldap_err2string (ret), buf, curr->dn);
1949*83ee113eSDavid van Moolenbroek }
1950*83ee113eSDavid van Moolenbroek #endif
1951*83ee113eSDavid van Moolenbroek }
1952*83ee113eSDavid van Moolenbroek }
1953*83ee113eSDavid van Moolenbroek
1954*83ee113eSDavid van Moolenbroek if (res && ent)
1955*83ee113eSDavid van Moolenbroek {
1956*83ee113eSDavid van Moolenbroek #if defined (DEBUG_LDAP)
1957*83ee113eSDavid van Moolenbroek char *dn = ldap_get_dn (ld, ent);
1958*83ee113eSDavid van Moolenbroek if (dn != NULL)
1959*83ee113eSDavid van Moolenbroek {
1960*83ee113eSDavid van Moolenbroek log_info ("Found subclass LDAP entry %s", dn);
1961*83ee113eSDavid van Moolenbroek ldap_memfree(dn);
1962*83ee113eSDavid van Moolenbroek }
1963*83ee113eSDavid van Moolenbroek #endif
1964*83ee113eSDavid van Moolenbroek
1965*83ee113eSDavid van Moolenbroek status = class_allocate (newclass, MDL);
1966*83ee113eSDavid van Moolenbroek if (status != ISC_R_SUCCESS)
1967*83ee113eSDavid van Moolenbroek {
1968*83ee113eSDavid van Moolenbroek log_error ("Cannot allocate memory for a new class");
1969*83ee113eSDavid van Moolenbroek ldap_msgfree (res);
1970*83ee113eSDavid van Moolenbroek return (0);
1971*83ee113eSDavid van Moolenbroek }
1972*83ee113eSDavid van Moolenbroek
1973*83ee113eSDavid van Moolenbroek group_reference (&(*newclass)->group, class->group, MDL);
1974*83ee113eSDavid van Moolenbroek class_reference (&(*newclass)->superclass, class, MDL);
1975*83ee113eSDavid van Moolenbroek lease_limit = ldap_parse_options (ent, (*newclass)->group,
1976*83ee113eSDavid van Moolenbroek CLASS_DECL, NULL, newclass);
1977*83ee113eSDavid van Moolenbroek if (lease_limit == 0)
1978*83ee113eSDavid van Moolenbroek (*newclass)->lease_limit = class->lease_limit;
1979*83ee113eSDavid van Moolenbroek else
1980*83ee113eSDavid van Moolenbroek class->lease_limit = lease_limit;
1981*83ee113eSDavid van Moolenbroek
1982*83ee113eSDavid van Moolenbroek if ((*newclass)->lease_limit)
1983*83ee113eSDavid van Moolenbroek {
1984*83ee113eSDavid van Moolenbroek (*newclass)->billed_leases =
1985*83ee113eSDavid van Moolenbroek dmalloc ((*newclass)->lease_limit * sizeof (struct lease *), MDL);
1986*83ee113eSDavid van Moolenbroek if (!(*newclass)->billed_leases)
1987*83ee113eSDavid van Moolenbroek {
1988*83ee113eSDavid van Moolenbroek log_error ("no memory for billing");
1989*83ee113eSDavid van Moolenbroek class_dereference (newclass, MDL);
1990*83ee113eSDavid van Moolenbroek ldap_msgfree (res);
1991*83ee113eSDavid van Moolenbroek return (0);
1992*83ee113eSDavid van Moolenbroek }
1993*83ee113eSDavid van Moolenbroek memset ((*newclass)->billed_leases, 0,
1994*83ee113eSDavid van Moolenbroek ((*newclass)->lease_limit * sizeof (struct lease *)));
1995*83ee113eSDavid van Moolenbroek }
1996*83ee113eSDavid van Moolenbroek
1997*83ee113eSDavid van Moolenbroek data_string_copy (&(*newclass)->hash_string, data, MDL);
1998*83ee113eSDavid van Moolenbroek
1999*83ee113eSDavid van Moolenbroek ldap_msgfree (res);
2000*83ee113eSDavid van Moolenbroek return (1);
2001*83ee113eSDavid van Moolenbroek }
2002*83ee113eSDavid van Moolenbroek
2003*83ee113eSDavid van Moolenbroek if(res) ldap_msgfree (res);
2004*83ee113eSDavid van Moolenbroek return (0);
2005*83ee113eSDavid van Moolenbroek }
2006*83ee113eSDavid van Moolenbroek
2007*83ee113eSDavid van Moolenbroek #endif
2008