]> git.pld-linux.org Git - packages/dhcp.git/blob - dhcp-ldap.patch
- converted to UTF-8
[packages/dhcp.git] / dhcp-ldap.patch
1 diff -Naur dhcp-3.0.1rc14/Changelog-LDAP dhcp-3.0.1rc14-ldap/Changelog-LDAP
2 --- dhcp-3.0.1rc14/Changelog-LDAP       1969-12-31 19:00:00.000000000 -0500
3 +++ dhcp-3.0.1rc14-ldap/Changelog-LDAP  2004-06-22 15:18:20.000000000 -0400
4 @@ -0,0 +1,82 @@
5 +2004-5-24 Brian Masney <masneyb@ntelos.net>
6 +       * server/ldap.c - don't append a ; to the end of a dhcpStatement if it
7 +       ends in }
8 +
9 +       * server/ldap.c contrib/dhcpd-conf-to-ldap.pl - support having multiple
10 +       dhcpRange statements (from Marco D'Ettorre <marco.dettorre@sys-net.it>)
11 +
12 +2004-5-5 Brian Masney <masneyb@ntelos.net>
13 +       * server/ldap.c - added more debugging statements when
14 +       it is compiled in to help troubleshoot parsing errors. Don't free
15 +       a LDAP connection prematurely when there is a reference to another
16 +       LDAP tree. If the config entry ends in }, make sure a ; gets tacked
17 +       on
18 +
19 +       * debian/* - Updated version number. Renamed package from
20 +       dhcp3-ldap-ntelos to dhcp3-server-ldap.
21 +
22 +       * server/ldap.c - enclose the shared-network name in quotes so
23 +       that there can be shared network statements in LDAP that have spaces
24 +       in them
25 +
26 +       * configure - after the work directory is setup, add -lldap -llber
27 +       to the server Makefile
28 +
29 +Wed Apr 21 15:09:08 CEST 2004 - mt@suse.de
30 +       * contrib/dhcpd-conf-to-ldap.pl:
31 +         - added "--conf=file" option usable instead of stdin
32 +         - added "--ldif=file" option usable instead of stdout
33 +         - added "--second=host|dn" option usefull for failover
34 +         - added "--use=feature" option to enable extended features;
35 +           currently used to enable failover (default is disabled).
36 +         - extended remaining_line() to support block statements
37 +         - fixed / improved failover support, added notes about
38 +
39 +       * server/ldap.c:
40 +         - moved code checking statement ends to check_statement_end()
41 +         - moved parsing of entry options/statements to
42 +           ldap_parse_entry_options()
43 +         - moved code closing debug fd into ldap_close_debug_fd()
44 +         - moved code writing to debug fd into ldap_write_debug()
45 +         - added support for full hostname in dhcpServer search filter
46 +         - added support for multiple dhcpService entries in dhcpServer object
47 +         - added parsing of options and statements for dhcpServer object
48 +         - added verify if dhcpService contains server dn as primary or
49 +           secondary
50 +         - changed to search for dhcpHost,dhcpSubClass bellow of all
51 +           dhcpService trees instead of base-dn (avoids finding of hosts in
52 +           foreign configs)
53 +         - fixes to free all dn's fetched by ldap_get_dn (e.g. debug output)
54 +         - fixes to free ldap results, mainly in cases where no LDAP_SUCCESS
55 +           returned or other error conditions happened
56 +         - fixed/improved some log messages
57 +
58 +2004-3-30 Brian Masney <masneyb@ntelos.net>
59 +       * contrib/dhcpd-conf-to-ldap.pl - added option to control the
60 +       DHCP Config DN. Wrap the DHCP Statements in { }
61 +       This patch was contributed by Marius Tomaschewski <mt@suse.de>
62 +
63 +       * server/ldap.c - changed ldap_username and ldap_password to
64 +       be optional (anonymous bind is used then). Added {} block support
65 +       to dhcpStatements. (no ";" at end if statement ends with a "}").
66 +       Fixed writing to ldap-debug-file. Changed find_haddr_in_ldap() to
67 +       use dhcpHost objectClass in its filter
68 +       This patch was contributed by Marius Tomaschewski <mt@suse.de>
69 +
70 +2004-3-23 Brian Masney <masneyb@ntelos.net>
71 +       * contrib/dhcpd-conf-to-ldap.pl - added options for server, basedn
72 +       options and usage message (Net::Domain instead of SYS::Hostname).
73 +       Added handling of zone, authoritative and failover (config and
74 +       pool-refs) statements. Added numbering of groups and pools per
75 +       subnet. This patch was contributed by Marius Tomaschewski <mt@suse.de>
76 +
77 +2004-2-26 Brian Masney <masneyb@ntelos.net>
78 +       * fixed an instance where the LDAP server would restart, but the DHCP
79 +       server would not reconnect
80 +
81 +2004-2-18 Brian Masney <masneyb@ntelos.net>
82 +       * allow multiple dhcp*DN entries in the LDAP entry.
83 +
84 +2003-9-11 Brian Masney <masneyb@ntelos.net>
85 +       * updated patch to work with 3.0.1rc12
86 +
87 diff -Naur dhcp-3.0.1rc14/README.ldap dhcp-3.0.1rc14-ldap/README.ldap
88 --- dhcp-3.0.1rc14/README.ldap  1969-12-31 19:00:00.000000000 -0500
89 +++ dhcp-3.0.1rc14-ldap/README.ldap     2004-06-22 15:18:20.000000000 -0400
90 @@ -0,0 +1,166 @@
91 +LDAP Support in DHCP
92 +Brian Masney <masneyb@ntelos.net>
93 +Last updated 3/23/2003
94 +
95 +This document describes setting up the DHCP server to read it's configuration 
96 +from LDAP. This work is based on the IETF document 
97 +draft-ietf-dhc-ldap-schema-01.txt included in the doc directory. For the latest
98 +version of this document, please see http://home.ntelos.net/~masneyb.
99 +
100 +First question on most people's mind is "Why do I want to store my 
101 +configuration in LDAP?" If you run a small DHCP server, and the configuration
102 +on it rarely changes, then you won't need to store your configuration in LDAP.
103 +But, if you have several DHCP servers, and you want an easy way to manage your 
104 +configuration, this can be a solution. 
105 +
106 +The first step will be to setup your LDAP server. I am using OpenLDAP from
107 +www.openldap.org. Building and installing OpenLDAP is beyond the scope of this 
108 +document. There is plenty of documentation out there about this. Once you have 
109 +OpenLDAP installed, you will have to edit your slapd.conf file. I added the 
110 +following 2 lines to my configuration file:
111 +
112 +include         /etc/ldap/schema/dhcp.schema
113 +index           dhcpHWAddress  eq
114 +index           dhcpClassData  eq
115 +
116 +The first line tells it to include the dhcp schema file. You will find this 
117 +file under the contrib directory in this distribution. You will need to copy 
118 +this file to where your other schema files are (maybe
119 +/usr/local/openldap/etc/openldap/schema/). The second line sets up
120 +an index for the dhcpHWAddress parameter. The third parameter is for reading 
121 +subclasses from LDAP every time a DHCP request comes in. Make sure you run the 
122 +slapindex command and restart slapd to have these changes to into effect.
123 +
124 +Now that you have LDAP setup, you should be able to use gq (http://biot.com/gq/)
125 +to verify that the dhcp schema file is loaded into LDAP. Pull up gq, and click
126 +on the Schema tab. Go under objectClasses, and you should see at least the 
127 +following object classes listed: dhcpClass, dhcpGroup, dhcpHost, dhcpOptions, 
128 +dhcpPool, dhcpServer, dhcpService, dhcpSharedNetwork, dhcpSubClass, and 
129 +dhcpSubnet. If you do not see these, you need to check over your LDAP 
130 +configuration before you go any further.
131 +
132 +You should be ready to build DHCP. Edit the includes/site.h file and uncomment
133 +the #define LDAP_CONFIGURATION. If you would like to enable LDAP over SSL, 
134 +uncomment the USE_SSL line as well. Now run configure in the base source 
135 +directory. Edit the work.os/server/Makefile and add -lldap to the LIBS= line.
136 +(replace os with your operating system, linux-2.2 on my machine). If you 
137 +enabled SSL, you will also need to add -lcrypto -lssl. You should now be able
138 +to type make to build your DHCP server. 
139 +
140 +Once you have DHCP installed, you will need to setup your initial plaintext 
141 +config file. In my /etc/dhcpd.conf file, I have:
142 +
143 +ldap-server "localhost";
144 +ldap-port 389;
145 +ldap-username "cn=DHCP User, dc=ntelos, dc=net";
146 +ldap-password "blah";
147 +ldap-base-dn "dc=ntelos, dc=net";
148 +ldap-method dynamic;
149 +ldap-debug-file "/var/log/dhcp-ldap-startup.log";
150 +
151 +All of these parameters should be self explanatory except for the ldap-method.
152 +You can set this to static or dynamic. If you set it to static, the 
153 +configuration is read once on startup, and LDAP isn't used anymore. But, if you
154 +set this to dynamic, the configuration is read once on startup, and the 
155 +hosts that are stored in LDAP are looked up every time a DHCP request comes in.
156 +
157 +When the optional statement ldap-debug-file is specified, on startup the DHCP
158 +server will write out the configuration that it generated from LDAP. If you are
159 +getting errors about your LDAP configuration, this is a good place to start
160 +looking.
161 +
162 +The next step is to set up your LDAP tree. Here is an example config that will
163 +give a 10.100.0.x address to machines that have a host entry in LDAP. 
164 +Otherwise, it will give a 10.200.0.x address to them. (NOTE: replace 
165 +dc=ntelos, dc=net with your base dn). If you would like to convert your 
166 +existing dhcpd.conf file to LDIF format, there is a script 
167 +contrib/dhcpd-conf-to-ldap.pl that will convert it for you. Type
168 +dhcpd-conf-to-ldap.pl --help to see the usage information for this script.
169 +
170 +# You must specify the server's host name in LDAP that you are going to run
171 +# DHCP on and point it to which config tree you want to use. Whenever DHCP 
172 +# first starts up, it will do a search for this entry to find out which 
173 +# config to use
174 +dn: cn=brian.ntelos.net, dc=ntelos, dc=net
175 +objectClass: top
176 +objectClass: dhcpServer
177 +cn: brian.ntelos.net
178 +dhcpServiceDN: cn=DHCP Service Config, dc=ntelos, dc=net
179 +
180 +# Here is the config tree that brian.ntelos.net points to. 
181 +dn: cn=DHCP Service Config, dc=ntelos, dc=net
182 +cn: DHCP Service Config
183 +objectClass: top
184 +objectClass: dhcpService
185 +dhcpPrimaryDN: dc=ntelos, dc=net
186 +dhcpStatements: ddns-update-style none
187 +dhcpStatements: default-lease-time 600
188 +dhcpStatements: max-lease-time 7200
189 +
190 +# Set up a shared network segment
191 +dn: cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
192 +cn: WV
193 +objectClass: top
194 +objectClass: dhcpSharedNetwork
195 +
196 +# Set up a subnet declaration with a pool statement. Also note that we have
197 +# a dhcpOptions object with this entry
198 +dn: cn=10.100.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
199 +cn: 10.100.0.0
200 +objectClass: top
201 +objectClass: dhcpSubnet
202 +objectClass: dhcpOptions
203 +dhcpOption: domain-name-servers 10.100.0.2
204 +dhcpOption: routers 10.100.0.1
205 +dhcpOption: subnet-mask 255.255.255.0
206 +dhcpOption: broadcast-address 10.100.0.255
207 +dhcpNetMask: 24
208 +
209 +# Set up a pool for this subnet. Only known hosts will get these IPs
210 +dn: cn=Known Pool, cn=10.100.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
211 +cn: Known Pool
212 +objectClass: top
213 +objectClass: dhcpPool
214 +dhcpRange: 10.100.0.3 10.100.0.254
215 +dhcpPermitList: deny unknown-clients
216 +
217 +# Set up another subnet declaration with a pool statement
218 +dn: cn=10.200.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
219 +cn: 10.200.0.0
220 +objectClass: top
221 +objectClass: dhcpSubnet
222 +objectClass: dhcpOptions
223 +dhcpOption: domain-name-servers 10.200.0.2
224 +dhcpOption: routers 10.200.0.1
225 +dhcpOption: subnet-mask 255.255.255.0
226 +dhcpOption: broadcast-address 10.200.0.255
227 +dhcpNetMask: 24
228 +
229 +# Set up a pool for this subnet. Only unknown hosts will get these IPs
230 +dn: cn=Known Pool, cn=10.200.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
231 +cn: Known Pool
232 +objectClass: top
233 +objectClass: dhcpPool
234 +dhcpRange: 10.200.0.3 10.200.0.254
235 +dhcpPermitList: deny known clients
236 +
237 +# Set aside a group for all of our known MAC addresses
238 +dn: cn=Customers, cn=DHCP Service Config, dc=ntelos, dc=net
239 +objectClass: top
240 +objectClass: dhcpGroup
241 +cn: Customers
242 +
243 +# Host entry for my laptop
244 +dn: cn=brianlaptop, cn=Customers, cn=DHCP Service Config, dc=ntelos, dc=net
245 +objectClass: top
246 +objectClass: dhcpHost
247 +cn: brianlaptop
248 +dhcpHWAddress: ethernet 00:00:00:00:00:00
249 +
250 +You can use the command slapadd to load all of these entries into your LDAP 
251 +server. After you load this, you should be able to start up DHCP. If you run
252 +into problems reading the configuration, try running dhcpd with the -d flag. 
253 +If you still have problems, edit the site.conf file in the DHCP source and
254 +add the line: COPTS= -DDEBUG_LDAP and recompile DHCP. (make sure you run make 
255 +clean and rerun configure before you rebuild).
256 +
257 diff -Naur dhcp-3.0.1rc14/common/conflex.c dhcp-3.0.1rc14-ldap/common/conflex.c
258 --- dhcp-3.0.1rc14/common/conflex.c     2004-06-10 13:59:14.000000000 -0400
259 +++ dhcp-3.0.1rc14-ldap/common/conflex.c        2004-06-22 15:18:20.000000000 -0400
260 @@ -47,6 +47,7 @@
261  static enum dhcp_token read_number PROTO ((int, struct parse *));
262  static enum dhcp_token read_num_or_name PROTO ((int, struct parse *));
263  static enum dhcp_token intern PROTO ((char *, enum dhcp_token));
264 +static char read_function PROTO ((struct parse *));
265  
266  isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
267         struct parse **cfile;
268 @@ -74,6 +75,10 @@
269         tmp -> file = file;
270         tmp -> eol_token = eolp;
271  
272 +       if (file != -1) {
273 +               tmp -> read_function = read_function;;
274 +       }
275 +
276         tmp -> bufix = 0;
277         tmp -> buflen = buflen;
278         if (inbuf) {
279 @@ -109,22 +114,11 @@
280         int c;
281  
282         if (cfile -> bufix == cfile -> buflen) {
283 -               if (cfile -> file != -1) {
284 -                       cfile -> buflen =
285 -                               read (cfile -> file,
286 -                                     cfile -> inbuf, cfile -> bufsiz);
287 -                       if (cfile -> buflen == 0) {
288 -                               c = EOF;
289 -                               cfile -> bufix = 0;
290 -                       } else if (cfile -> buflen < 0) {
291 -                               c = EOF;
292 -                               cfile -> bufix = cfile -> buflen = 0;
293 -                       } else {
294 -                               c = cfile -> inbuf [0];
295 -                               cfile -> bufix = 1;
296 -                       }
297 -               } else
298 +               if (cfile -> read_function) {
299 +                       c = cfile -> read_function (cfile);
300 +               } else {
301                         c = EOF;
302 +               }
303         } else {
304                 c = cfile -> inbuf [cfile -> bufix];
305                 cfile -> bufix++;
306 @@ -1071,3 +1065,25 @@
307         }
308         return dfv;
309  }
310 +
311 +
312 +static char
313 +read_function (struct parse * cfile)
314 +{
315 +  char c;
316 +
317 +       cfile -> buflen = read (cfile -> file, cfile -> inbuf, cfile -> bufsiz);
318 +       if (cfile -> buflen == 0) {
319 +               c = EOF;
320 +               cfile -> bufix = 0;
321 +       } else if (cfile -> buflen < 0) {
322 +               c = EOF;
323 +               cfile -> bufix = cfile -> buflen = 0;
324 +       } else {
325 +               c = cfile -> inbuf [0];
326 +               cfile -> bufix = 1;
327 +       }
328 +
329 +       return c;
330 +}
331 +
332 diff -Naur dhcp-3.0.1rc14/common/print.c dhcp-3.0.1rc14-ldap/common/print.c
333 --- dhcp-3.0.1rc14/common/print.c       2004-06-17 16:54:39.000000000 -0400
334 +++ dhcp-3.0.1rc14-ldap/common/print.c  2004-06-22 15:18:20.000000000 -0400
335 @@ -166,9 +166,9 @@
336  }
337  
338  char *print_hw_addr (htype, hlen, data)
339 -       int htype;
340 -       int hlen;
341 -       unsigned char *data;
342 +       const int htype;
343 +       const int hlen;
344 +       const unsigned char *data;
345  {
346         static char habuf [49];
347         char *s;
348 diff -Naur dhcp-3.0.1rc14/configure dhcp-3.0.1rc14-ldap/configure
349 --- dhcp-3.0.1rc14/configure    2002-04-20 17:44:13.000000000 -0400
350 +++ dhcp-3.0.1rc14-ldap/configure       2004-06-22 15:18:20.000000000 -0400
351 @@ -256,4 +256,8 @@
352    make links
353  fi
354  
355 +mv $workname/server/Makefile $workname/server/Makefile.noldap
356 +cat $workname/server/Makefile.noldap | sed '{s/^LIBS =/LIBS=-lldap -llber/}' > $workname/server/Makefile.ldap
357 +ln $workname/server/Makefile.ldap $workname/server/Makefile
358 +
359  exit 0
360 diff -Naur dhcp-3.0.1rc14/contrib/dhcp.schema dhcp-3.0.1rc14-ldap/contrib/dhcp.schema
361 --- dhcp-3.0.1rc14/contrib/dhcp.schema  1969-12-31 19:00:00.000000000 -0500
362 +++ dhcp-3.0.1rc14-ldap/contrib/dhcp.schema     2004-06-22 15:18:20.000000000 -0400
363 @@ -0,0 +1,343 @@
364 +attributetype ( 2.16.840.1.113719.1.203.4.1 
365 +       NAME 'dhcpPrimaryDN' 
366 +       EQUALITY distinguishedNameMatch
367 +       DESC 'The DN of the dhcpServer which is the primary server for the configuration.' 
368 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
369 +
370 +attributetype ( 2.16.840.1.113719.1.203.4.2 
371 +       NAME 'dhcpSecondaryDN' 
372 +       EQUALITY distinguishedNameMatch
373 +       DESC 'The DN of dhcpServer(s) which provide backup service for the configuration.'
374 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
375 +
376 +attributetype ( 2.16.840.1.113719.1.203.4.3 
377 +       NAME 'dhcpStatements' 
378 +       EQUALITY caseIgnoreIA5Match
379 +       DESC 'Flexible storage for specific data depending on what object this exists in. Like conditional statements, server parameters, etc. This allows the standard to evolve without needing to adjust the schema.' 
380 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
381 +
382 +attributetype ( 2.16.840.1.113719.1.203.4.4 
383 +       NAME 'dhcpRange' 
384 +       EQUALITY caseIgnoreIA5Match
385 +       DESC 'The starting & ending IP Addresses in the range (inclusive), separated by a hyphen; if the range only contains one address, then just the address can be specified with no hyphen.  Each range is defined as a separate value.'
386 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
387 +
388 +attributetype ( 2.16.840.1.113719.1.203.4.5 
389 +       NAME 'dhcpPermitList' 
390 +       EQUALITY caseIgnoreIA5Match
391 +       DESC 'This attribute contains the permit lists associated with a pool. Each permit list is defined as a separate value.' 
392 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
393 +
394 +attributetype ( 2.16.840.1.113719.1.203.4.6 
395 +       NAME 'dhcpNetMask' 
396 +       EQUALITY integerMatch
397 +       DESC 'The subnet mask length for the subnet.  The mask can be easily computed from this length.' 
398 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
399 +
400 +attributetype ( 2.16.840.1.113719.1.203.4.7 
401 +       NAME 'dhcpOption' 
402 +       EQUALITY caseIgnoreIA5Match
403 +       DESC 'Encoded option values to be sent to clients.  Each value represents a single option and contains (OptionTag, Length, OptionValue) encoded in the format used by DHCP.' 
404 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
405 +
406 +attributetype ( 2.16.840.1.113719.1.203.4.8 
407 +       NAME 'dhcpClassData' 
408 +       EQUALITY caseIgnoreIA5Match
409 +       DESC 'Encoded text string or list of bytes expressed in hexadecimal, separated by colons.  Clients match subclasses based on matching the class data with the results of match or spawn with statements in the class name declarations.' 
410 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
411 +
412 +attributetype ( 2.16.840.1.113719.1.203.4.9 
413 +       NAME 'dhcpOptionsDN' 
414 +       EQUALITY distinguishedNameMatch
415 +       DESC 'The distinguished name(s) of the dhcpOption objects containing the configuration options provided by the server.' 
416 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
417 +
418 +attributetype ( 2.16.840.1.113719.1.203.4.10 
419 +       NAME 'dhcpHostDN' 
420 +       EQUALITY distinguishedNameMatch
421 +       DESC 'the distinguished name(s) of the dhcpHost objects.' 
422 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) 
423 +
424 +attributetype ( 2.16.840.1.113719.1.203.4.11 
425 +       NAME 'dhcpPoolDN' 
426 +       EQUALITY distinguishedNameMatch
427 +       DESC 'The distinguished name(s) of pools.' 
428 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
429 +
430 +attributetype ( 2.16.840.1.113719.1.203.4.12 
431 +       NAME 'dhcpGroupDN' 
432 +       EQUALITY distinguishedNameMatch
433 +       DESC 'The distinguished name(s)   of the groups.' 
434 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
435 +
436 +attributetype ( 2.16.840.1.113719.1.203.4.13 
437 +       NAME 'dhcpSubnetDN' 
438 +       EQUALITY distinguishedNameMatch
439 +       DESC 'The distinguished name(s) of the subnets.' 
440 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
441 +
442 +attributetype ( 2.16.840.1.113719.1.203.4.14 
443 +       NAME 'dhcpLeaseDN' 
444 +       EQUALITY distinguishedNameMatch
445 +       DESC 'The distinguished name of a client address.' 
446 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE)
447 +
448 +attributetype ( 2.16.840.1.113719.1.203.4.15 NAME 'dhcpLeasesDN' 
449 +       DESC 'The distinguished name(s) client addresses.' 
450 +       EQUALITY distinguishedNameMatch
451 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
452 +
453 +attributetype ( 2.16.840.1.113719.1.203.4.16 
454 +       NAME 'dhcpClassesDN' 
455 +       EQUALITY distinguishedNameMatch
456 +       DESC 'The distinguished name(s) of a class(es) in a subclass.' 
457 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
458 +
459 +attributetype ( 2.16.840.1.113719.1.203.4.17 
460 +       NAME 'dhcpSubclassesDN' 
461 +       EQUALITY distinguishedNameMatch
462 +       DESC 'The distinguished name(s) of subclass(es).' 
463 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
464 +
465 +attributetype ( 2.16.840.1.113719.1.203.4.18 
466 +       NAME 'dhcpSharedNetworkDN' 
467 +       EQUALITY distinguishedNameMatch
468 +       DESC 'The distinguished name(s) of sharedNetworks.' 
469 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
470 +
471 +attributetype ( 2.16.840.1.113719.1.203.4.19 
472 +       NAME 'dhcpServiceDN' 
473 +       EQUALITY distinguishedNameMatch
474 +       DESC 'The DN of dhcpService object(s)which contain the configuration information. Each dhcpServer object has this attribute identifying the DHCP configuration(s) that the server is associated with.' 
475 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
476 +
477 +attributetype ( 2.16.840.1.113719.1.203.4.20 
478 +       NAME 'dhcpVersion' DESC 'The version attribute of this object.' 
479 +       EQUALITY caseIgnoreIA5Match
480 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
481 +
482 +attributetype ( 2.16.840.1.113719.1.203.4.21 
483 +       NAME 'dhcpImplementation' 
484 +       EQUALITY caseIgnoreIA5Match
485 +       DESC 'Description of the DHCP Server implementation e.g. DHCP Servers vendor.' 
486 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
487 +
488 +attributetype ( 2.16.840.1.113719.1.203.4.22 
489 +       NAME 'dhcpAddressState' 
490 +       EQUALITY caseIgnoreIA5Match
491 +       DESC 'This stores information about the current binding-status of an address.  For dynamic addresses managed by DHCP, the values should be restricted to the following: "FREE", "ACTIVE", "EXPIRED", "RELEASED", "RESET", "ABANDONED", "BACKUP".  For other addresses, it SHOULD be one of the following: "UNKNOWN", "RESERVED" (an address that is managed by DHCP that is reserved for a specific client), "RESERVED-ACTIVE" (same as reserved, but address is currently in use), "ASSIGNED" (assigned manually or by some other mechanism), "UNASSIGNED", "NOTASSIGNABLE".'
492 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
493 +
494 +attributetype ( 2.16.840.1.113719.1.203.4.23 
495 +       NAME 'dhcpExpirationTime' 
496 +       EQUALITY generalizedTimeMatch 
497 +       DESC 'This is the time the current lease for an address expires.' 
498 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
499 +
500 +attributetype ( 2.16.840.1.113719.1.203.4.24 
501 +       NAME 'dhcpStartTimeOfState' 
502 +       EQUALITY generalizedTimeMatch 
503 +       DESC 'This is the time of the last state change for a leased address.' 
504 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
505 +
506 +attributetype ( 2.16.840.1.113719.1.203.4.25 
507 +       NAME 'dhcpLastTransactionTime' 
508 +       EQUALITY generalizedTimeMatch 
509 +       DESC 'This is the last time a valid DHCP packet was received from the client.'
510 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
511 +
512 +attributetype ( 2.16.840.1.113719.1.203.4.26 
513 +       NAME 'dhcpBootpFlag' 
514 +       EQUALITY booleanMatch 
515 +       DESC 'This indicates whether the address was assigned via BOOTP.' 
516 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
517 +
518 +attributetype ( 2.16.840.1.113719.1.203.4.27 
519 +       NAME 'dhcpDomainName' 
520 +       EQUALITY caseIgnoreIA5Match
521 +       DESC 'This is the name of the domain sent to the client by the server.  It is essentially the same as the value for DHCP option 15 sent to the client, and represents only the domain - not the full FQDN.  To obtain the full FQDN assigned to the client you must prepend the "dhcpAssignedHostName" to this value with a ".".' 
522 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
523 +
524 +attributetype ( 2.16.840.1.113719.1.203.4.28 
525 +       NAME 'dhcpDnsStatus' 
526 +       EQUALITY integerMatch
527 +       DESC 'This indicates the status of updating DNS resource records on behalf of the client by the DHCP server for this address.  The value is a 16-bit bitmask.'
528 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
529 +
530 +attributetype ( 2.16.840.1.113719.1.203.4.29 
531 +       NAME 'dhcpRequestedHostName' 
532 +       EQUALITY caseIgnoreIA5Match
533 +       DESC 'This is the hostname that was requested by the client.' 
534 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
535 +
536 +attributetype ( 2.16.840.1.113719.1.203.4.30 
537 +       NAME 'dhcpAssignedHostName' 
538 +       EQUALITY caseIgnoreIA5Match
539 +       DESC 'This is the actual hostname that was assigned to a client. It may not be the name that was requested by the client.  The fully qualified domain name can be determined by appending the value of "dhcpDomainName" (with a dot separator) to this name.' 
540 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
541 +
542 +attributetype ( 2.16.840.1.113719.1.203.4.31 
543 +       NAME 'dhcpReservedForClient' 
544 +       EQUALITY distinguishedNameMatch
545 +       DESC 'The distinguished name of a "dhcpClient" that an address is reserved for.  This may not be the same as the "dhcpAssignedToClient" attribute if the address is being reassigned but the current lease has not yet expired.'
546 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
547 +
548 +attributetype ( 2.16.840.1.113719.1.203.4.32 
549 +       NAME 'dhcpAssignedToClient' 
550 +       EQUALITY distinguishedNameMatch
551 +       DESC 'This is the distinguished name of a "dhcpClient" that an address is currently assigned to.  This attribute is only present in the class when the address is leased.' 
552 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
553 +
554 +attributetype ( 2.16.840.1.113719.1.203.4.33 
555 +       NAME 'dhcpRelayAgentInfo' 
556 +       EQUALITY octetStringMatch
557 +       DESC 'If the client request was received via a relay agent, this contains information about the relay agent that was available from the DHCP request.  This is a hex-encoded option value.' 
558 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
559 +
560 +attributetype ( 2.16.840.1.113719.1.203.4.34 
561 +       NAME 'dhcpHWAddress' 
562 +       EQUALITY octetStringMatch
563 +       DESC 'The clients hardware address that requested this IP address.' 
564 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
565 +
566 +attributetype ( 2.16.840.1.113719.1.203.4.35 
567 +       NAME 'dhcpHashBucketAssignment' 
568 +       EQUALITY octetStringMatch
569 +       DESC 'HashBucketAssignment bit map for the DHCP Server, as defined in DHC Load Balancing Algorithm [RFC 3074].' 
570 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
571 +
572 +attributetype ( 2.16.840.1.113719.1.203.4.36 
573 +       NAME 'dhcpDelayedServiceParameter' 
574 +       EQUALITY integerMatch
575 +       DESC 'Delay in seconds corresponding to Delayed Service Parameter configuration, as defined in  DHC Load Balancing Algorithm [RFC 3074]. '
576 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
577 +
578 +attributetype ( 2.16.840.1.113719.1.203.4.37 
579 +       NAME 'dhcpMaxClientLeadTime' 
580 +       EQUALITY integerMatch
581 +       DESC 'Maximum Client Lead Time configuration in seconds, as defined in DHCP Failover Protocol [FAILOVR]' 
582 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
583 +
584 +attributetype ( 2.16.840.1.113719.1.203.4.38 
585 +       NAME 'dhcpFailOverEndpointState' 
586 +       EQUALITY caseIgnoreIA5Match
587 +       DESC 'Server (Failover Endpoint) state, as defined in DHCP Failover Protocol [FAILOVR]' 
588 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
589 +
590 +attributetype ( 2.16.840.1.113719.1.203.4.39 
591 +       NAME 'dhcpErrorLog' 
592 +       EQUALITY caseIgnoreIA5Match
593 +       DESC 'Generic error log attribute that allows logging error conditions within a dhcpService or a dhcpSubnet, like no IP addresses available for lease.'
594 +       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
595 +
596 +# Classes
597 +
598 +objectclass ( 2.16.840.1.113719.1.203.6.1 
599 +       NAME 'dhcpService' 
600 +       DESC 'Service object that represents the actual DHCP Service configuration. This is a container object.' 
601 +       SUP top 
602 +       MUST (cn $ dhcpPrimaryDN) 
603 +       MAY ( dhcpSecondaryDN $ dhcpSharedNetworkDN $ dhcpSubnetDN $ 
604 +               dhcpGroupDN $ dhcpHostDN $  dhcpClassesDN $ dhcpOptionsDN $ 
605 +               dhcpStatements ) )
606 +
607 +objectclass ( 2.16.840.1.113719.1.203.6.2 
608 +       NAME 'dhcpSharedNetwork' 
609 +       DESC 'This stores configuration information for a shared network.' 
610 +       SUP top 
611 +       MUST cn 
612 +       MAY ( dhcpSubnetDN $ dhcpPoolDN $ dhcpOptionsDN $ dhcpStatements) 
613 +       X-NDS_CONTAINMENT ('dhcpService' ) )
614 +
615 +objectclass ( 2.16.840.1.113719.1.203.6.3 
616 +       NAME 'dhcpSubnet' 
617 +       DESC 'This class defines a subnet. This is a container object.' 
618 +       SUP top 
619 +       MUST ( cn $ dhcpNetMask ) 
620 +       MAY ( dhcpRange $ dhcpPoolDN $ dhcpGroupDN $ dhcpHostDN $ 
621 +               dhcpClassesDN $ dhcpLeasesDN $ dhcpOptionsDN $ dhcpStatements) 
622 +       X-NDS_CONTAINMENT ('dhcpService' 'dhcpSharedNetwork') )
623 +
624 +objectclass ( 2.16.840.1.113719.1.203.6.4 
625 +       NAME 'dhcpPool' 
626 +       DESC 'This stores configuration information about a pool.' 
627 +       SUP top 
628 +       MUST ( cn $ dhcpRange ) 
629 +       MAY (dhcpClassesDN $ dhcpPermitList $ dhcpLeasesDN $ dhcpOptionsDN $ 
630 +               dhcpStatements) 
631 +       X-NDS_CONTAINMENT ('dhcpSubnet' 'dhcpSharedNetwork') )
632 +
633 +objectclass ( 2.16.840.1.113719.1.203.6.5 
634 +       NAME 'dhcpGroup' 
635 +       DESC 'Group object that lists host DNs and parameters. This is a container object.' 
636 +       SUP top 
637 +       MUST cn 
638 +       MAY ( dhcpHostDN $ dhcpOptionsDN $ dhcpStatements ) 
639 +       X-NDS_CONTAINMENT ('dhcpSubnet' 'dhcpService' ) )
640 +
641 +objectclass ( 2.16.840.1.113719.1.203.6.6 
642 +       NAME 'dhcpHost' 
643 +       DESC 'This represents information about a particular client' 
644 +       SUP top 
645 +       MUST cn 
646 +       MAY  (dhcpLeaseDN $ dhcpHWAddress $ dhcpOptionsDN $ dhcpStatements) 
647 +       X-NDS_CONTAINMENT ('dhcpService' 'dhcpSubnet' 'dhcpGroup') )
648 +
649 +objectclass ( 2.16.840.1.113719.1.203.6.7 
650 +       NAME 'dhcpClass' 
651 +       DESC 'Represents information about a collection of related clients.' 
652 +       SUP top 
653 +       MUST cn 
654 +       MAY (dhcpSubClassesDN $ dhcpOptionsDN $ dhcpStatements) 
655 +       X-NDS_CONTAINMENT ('dhcpService' 'dhcpSubnet' ) )
656 +
657 +objectclass ( 2.16.840.1.113719.1.203.6.8 
658 +       NAME 'dhcpSubClass' 
659 +       DESC 'Represents information about a collection of related classes.' 
660 +       SUP top 
661 +       MUST cn 
662 +       MAY (dhcpClassData $ dhcpOptionsDN $ dhcpStatements) 
663 +       X-NDS_CONTAINMENT 'dhcpClass' ) 
664 +
665 +objectclass ( 2.16.840.1.113719.1.203.6.9 
666 +       NAME 'dhcpOptions' 
667 +       DESC 'Represents information about a collection of options defined.' 
668 +       SUP top AUXILIARY
669 +       MUST cn 
670 +       MAY ( dhcpOption ) 
671 +       X-NDS_CONTAINMENT  ('dhcpService' 'dhcpSharedNetwork' 'dhcpSubnet' 
672 +                       'dhcpPool' 'dhcpGroup' 'dhcpHost' 'dhcpClass' ) )
673 +
674 +objectclass ( 2.16.840.1.113719.1.203.6.10 
675 +       NAME 'dhcpLeases' 
676 +       DESC 'This class represents an IP Address, which may or may not have been leased.' 
677 +       SUP top 
678 +       MUST ( cn $ dhcpAddressState ) 
679 +       MAY ( dhcpExpirationTime $ dhcpStartTimeOfState $ 
680 +               dhcpLastTransactionTime $ dhcpBootpFlag $ dhcpDomainName $ 
681 +               dhcpDnsStatus $ dhcpRequestedHostName $ dhcpAssignedHostName $ 
682 +               dhcpReservedForClient $ dhcpAssignedToClient $ 
683 +               dhcpRelayAgentInfo $ dhcpHWAddress ) 
684 +       X-NDS_CONTAINMENT ( 'dhcpService' 'dhcpSubnet' 'dhcpPool') )
685 +
686 +objectclass ( 2.16.840.1.113719.1.203.6.11 
687 +       NAME 'dhcpLog' 
688 +       DESC 'This is the object that holds past information about the IP address. The cn is the time/date stamp when the address was assigned or released, the address state at the time, if the address was assigned or released.' 
689 +       SUP top 
690 +       MUST ( cn ) 
691 +       MAY ( dhcpAddressState $ dhcpExpirationTime $ dhcpStartTimeOfState $ 
692 +               dhcpLastTransactionTime $ dhcpBootpFlag $ dhcpDomainName $ 
693 +               dhcpDnsStatus $ dhcpRequestedHostName $ dhcpAssignedHostName $ 
694 +               dhcpReservedForClient $ dhcpAssignedToClient $ 
695 +               dhcpRelayAgentInfo $ dhcpHWAddress $ dhcpErrorLog) 
696 +       X-NDS_CONTAINMENT ('dhcpLeases' 'dhcpPool' 'dhcpSubnet' 
697 +                                       'dhcpSharedNetwork' 'dhcpService' ) )
698 +
699 +objectclass ( 2.16.840.1.113719.1.203.6.12 
700 +       NAME 'dhcpServer' 
701 +       DESC 'DHCP Server Object' 
702 +       SUP top 
703 +       MUST (cn $ dhcpServiceDN) 
704 +       MAY (dhcpVersion $ dhcpImplementation $ dhcpHashBucketAssignment $ dhcpDelayedServiceParameter $ dhcpMaxClientLeadTime $ dhcpFailOverEndpointState $ dhcpStatements)
705 +       X-NDS_CONTAINMENT ('o' 'ou' 'dc') )
706 +
707 diff -Naur dhcp-3.0.1rc14/contrib/dhcpd-conf-to-ldap.pl dhcp-3.0.1rc14-ldap/contrib/dhcpd-conf-to-ldap.pl
708 --- dhcp-3.0.1rc14/contrib/dhcpd-conf-to-ldap.pl        1969-12-31 19:00:00.000000000 -0500
709 +++ dhcp-3.0.1rc14-ldap/contrib/dhcpd-conf-to-ldap.pl   2004-06-22 15:18:20.000000000 -0400
710 @@ -0,0 +1,751 @@
711 +#!/usr/bin/perl -w
712 +
713 +# Brian Masney <masneyb@ntelos.net>
714 +# To use this script, set your base DN below. Then run 
715 +# ./dhcpd-conf-to-ldap.pl < /path-to-dhcpd-conf/dhcpd.conf > output-file
716 +# The output of this script will generate entries in LDIF format. You can use
717 +# the slapadd command to add these entries into your LDAP server. You will
718 +# definately want to double check that your LDAP entries are correct before
719 +# you load them into LDAP.
720 +
721 +# This script does not do much error checking. Make sure before you run this
722 +# that the DHCP server doesn't give any errors about your config file
723 +
724 +# FailOver notes:
725 +#   Failover is disabled by default, since it may need manually intervention.
726 +#   You can try the '--use=failover' option to see what happens :-)
727 +#
728 +#   If enabled, the failover pool references will be written to LDIF output.
729 +#   The failover configs itself will be added to the dhcpServer statements
730 +#   and not to the dhcpService object (since this script uses only one and
731 +#   it may be usefull to have multiple service containers in failover mode).
732 +#   Further, this script does not check if primary or secondary makes sense,
733 +#   it simply converts what it gets...
734 +
735 +use Net::Domain qw(hostname hostfqdn hostdomain);
736 +use Getopt::Long;
737 +
738 +my $domain = hostdomain();           # your.domain
739 +my $basedn = "dc=".$domain;
740 +   $basedn =~ s/\./,dc=/g;           # dc=your,dc=domain
741 +my $server = hostname();             # hostname (nodename)
742 +my $dhcpcn = 'DHCP Config';          # CN of DHCP config tree
743 +my $dhcpdn = "cn=$dhcpcn, $basedn";  # DHCP config tree DN
744 +my $second = '';                     # secondary server DN / hostname
745 +my $i_conf = '';                     # dhcp.conf file to read or stdin
746 +my $o_ldif = '';                     # output ldif file name or stdout
747 +my @use    = ();                     # extended flags (failover)
748 +
749 +sub usage($;$)
750 +{
751 +  my $rc = shift;
752 +  my $err= shift;
753 +
754 +  print STDERR "Error: $err\n\n" if(defined $err);
755 +  print STDERR <<__EOF_USAGE__;
756 +usage: 
757 +  $0 [options] < dhcpd.conf > dhcpd.ldif
758 +
759 +options:
760 +
761 +  --basedn  "dc=your,dc=domain"        ("$basedn")
762 +
763 +  --dhcpdn  "dhcp config DN"           ("$dhcpdn")
764 +
765 +  --server  "dhcp server name"         ("$server")
766 +
767 +  --second  "secondary server or DN"   ("$second")
768 +
769 +  --conf    "/path/to/dhcpd.conf"      (default is stdin)
770 +  --ldif    "/path/to/output.ldif"     (default is stdout)
771 +
772 +  --use     "extended features"        (see source comments)
773 +__EOF_USAGE__
774 +  exit($rc);
775 +}
776 +
777 +
778 +sub next_token
779 +{
780 +  local ($lowercase) = @_;
781 +  local ($token, $newline);
782 +
783 +  do 
784 +    {
785 +      if (!defined ($line) || length ($line) == 0)
786 +        {
787 +          $line = <>;
788 +          return undef if !defined ($line);
789 +          chop $line;
790 +          $line_number++;
791 +          $token_number = 0;
792 +        }
793 +
794 +      $line =~ s/#.*//;
795 +      $line =~ s/^\s+//;
796 +      $line =~ s/\s+$//;
797 +    }
798 +  while (length ($line) == 0);
799 +
800 +  if (($token, $newline) = $line =~ /^(.*?)\s+(.*)/)
801 +    {
802 +      $line = $newline;
803 +    }
804 +  else
805 +    {
806 +      $token = $line;
807 +      $line = '';
808 +    }
809 +  $token_number++;
810 +
811 +  $token =~ y/[A-Z]/[a-z]/ if $lowercase;
812 +
813 +  return ($token);
814 +}
815 +
816 +
817 +sub remaining_line
818 +{
819 +  local ($block) = shift || 0;
820 +  local ($tmp, $str);
821 +
822 +  $str = "";
823 +  while (defined($tmp = next_token (0)))
824 +    {
825 +      $str .= ' ' if !($str eq "");
826 +      $str .= $tmp;
827 +      last if $tmp =~ /;\s*$/;
828 +      last if($block and $tmp =~ /\s*[}{]\s*$/);
829 +    }
830 +
831 +  $str =~ s/;$//;
832 +  return ($str);
833 +}
834 +
835 +
836 +sub
837 +add_dn_to_stack
838 +{
839 +  local ($dn) = @_;
840 +
841 +  $current_dn = "$dn, $current_dn";
842 +}
843 +
844 +
845 +sub
846 +remove_dn_from_stack
847 +{
848 +  $current_dn =~ s/^.*?,\s*//;
849 +}
850 +
851 +
852 +sub
853 +parse_error
854 +{
855 +  print "Parse error on line number $line_number at token number $token_number\n";
856 +  exit (1);
857 +}
858 +
859 +
860 +sub
861 +print_entry
862 +{
863 +  return if (scalar keys %curentry == 0);
864 +
865 +  if (!defined ($curentry{'type'}))
866 +    {
867 +      $hostdn = "cn=$server, $basedn";
868 +      print "dn: $hostdn\n";
869 +      print "cn: $server\n";
870 +      print "objectClass: top\n";
871 +      print "objectClass: dhcpServer\n";
872 +      print "dhcpServiceDN: $current_dn\n";
873 +      if(grep(/FaIlOvEr/i, @use))
874 +        {
875 +          foreach my $fo_peer (keys %failover)
876 +            {
877 +              next if(scalar(@{$failover{$fo_peer}}) <= 1);
878 +              print "dhcpStatements: failover peer $fo_peer { ",
879 +                    join('; ', @{$failover{$fo_peer}}), "; }\n";
880 +            }
881 +        }
882 +      print "\n";
883 +
884 +      print "dn: $current_dn\n";
885 +      print "cn: $dhcpcn\n";
886 +      print "objectClass: top\n";
887 +      print "objectClass: dhcpService\n";
888 +      if (defined ($curentry{'options'}))
889 +        {
890 +          print "objectClass: dhcpOptions\n";
891 +        }
892 +      print "dhcpPrimaryDN: $hostdn\n";
893 +      if(grep(/FaIlOvEr/i, @use) and ($second ne ''))
894 +        {
895 +          print "dhcpSecondaryDN: $second\n";
896 +        }
897 +    }
898 +  elsif ($curentry{'type'} eq 'subnet')
899 +    {
900 +      print "dn: $current_dn\n";
901 +      print "cn: " . $curentry{'ip'} . "\n";
902 +      print "objectClass: top\n";
903 +      print "objectClass: dhcpSubnet\n";
904 +      if (defined ($curentry{'options'}))
905 +        {
906 +          print "objectClass: dhcpOptions\n";
907 +        }
908 +      
909 +      print "dhcpNetMask: " . $curentry{'netmask'} . "\n";
910 +      if (defined ($curentry{'ranges'}))
911 +        {
912 +          foreach $statement (@{$curentry{'ranges'}})
913 +            {
914 +              print "dhcpRange: $statement\n";
915 +            }
916 +        }
917 +    }
918 +  elsif ($curentry{'type'} eq 'shared-network')
919 +    {
920 +      print "dn: $current_dn\n";
921 +      print "cn: " . $curentry{'descr'} . "\n";
922 +      print "objectClass: top\n";
923 +      print "objectClass: dhcpSharedNetwork\n";
924 +      if (defined ($curentry{'options'}))
925 +        {
926 +          print "objectClass: dhcpOptions\n";
927 +        }
928 +    }
929 +  elsif ($curentry{'type'} eq 'group')
930 +    {
931 +      print "dn: $current_dn\n";
932 +      print "cn: group", $curentry{'idx'}, "\n";
933 +      print "objectClass: top\n";
934 +      print "objectClass: dhcpGroup\n";
935 +      if (defined ($curentry{'options'}))
936 +        {
937 +          print "objectClass: dhcpOptions\n";
938 +        }
939 +    }
940 +  elsif ($curentry{'type'} eq 'host')
941 +    {
942 +      print "dn: $current_dn\n";
943 +      print "cn: " . $curentry{'host'} . "\n";
944 +      print "objectClass: top\n";
945 +      print "objectClass: dhcpHost\n";
946 +      if (defined ($curentry{'options'}))
947 +        {
948 +          print "objectClass: dhcpOptions\n";
949 +        }
950 +
951 +      if (defined ($curentry{'hwaddress'}))
952 +        {
953 +          print "dhcpHWAddress: " . $curentry{'hwaddress'} . "\n";
954 +        }
955 +    }
956 +  elsif ($curentry{'type'} eq 'pool')
957 +    {
958 +      print "dn: $current_dn\n";
959 +      print "cn: pool", $curentry{'idx'}, "\n";
960 +      print "objectClass: top\n";
961 +      print "objectClass: dhcpPool\n";
962 +      if (defined ($curentry{'options'}))
963 +        {
964 +          print "objectClass: dhcpOptions\n";
965 +        }
966 +
967 +      if (defined ($curentry{'ranges'}))
968 +        {
969 +          foreach $statement (@{$curentry{'ranges'}})
970 +            {
971 +              print "dhcpRange: $statement\n";
972 +            }
973 +        }
974 +    }
975 +  elsif ($curentry{'type'} eq 'class')
976 +    {
977 +      print "dn: $current_dn\n";
978 +      print "cn: " . $curentry{'class'} . "\n";
979 +      print "objectClass: top\n";
980 +      print "objectClass: dhcpClass\n";
981 +      if (defined ($curentry{'options'}))
982 +        {
983 +          print "objectClass: dhcpOptions\n";
984 +        }
985 +    }
986 +  elsif ($curentry{'type'} eq 'subclass')
987 +    {
988 +      print "dn: $current_dn\n";
989 +      print "cn: " . $curentry{'subclass'} . "\n";
990 +      print "objectClass: top\n";
991 +      print "objectClass: dhcpSubClass\n";
992 +      if (defined ($curentry{'options'}))
993 +        {
994 +          print "objectClass: dhcpOptions\n";
995 +        }
996 +      print "dhcpClassData: " . $curentry{'class'} . "\n";
997 +    }
998 +
999 +  if (defined ($curentry{'statements'}))
1000 +    {
1001 +      foreach $statement (@{$curentry{'statements'}})
1002 +        {
1003 +          print "dhcpStatements: $statement\n";
1004 +        }
1005 +    }
1006 +
1007 +  if (defined ($curentry{'options'}))
1008 +    {
1009 +      foreach $statement (@{$curentry{'options'}})
1010 +        {
1011 +          print "dhcpOption: $statement\n";
1012 +        }
1013 +    }
1014 +
1015 +  print "\n";
1016 +  undef (%curentry);
1017 +}
1018 +
1019 +
1020 +sub parse_netmask
1021 +{
1022 +  local ($netmask) = @_;
1023 +  local ($i);
1024 +
1025 +  if ((($a, $b, $c, $d) = $netmask =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) != 4)
1026 +    {
1027 +      parse_error ();
1028 +    }
1029 +
1030 +  $num = (($a & 0xff) << 24) |
1031 +         (($b & 0xff) << 16) |
1032 +         (($c & 0xff) << 8) |
1033 +          ($d & 0xff);
1034 +
1035 +  for ($i=1; $i<=32 && $num & (1 << (32 - $i)); $i++)
1036 +    {
1037 +    }
1038 +  $i--;
1039 +
1040 +  return ($i);
1041 +}
1042 +
1043 +
1044 +sub parse_subnet
1045 +{
1046 +  local ($ip, $tmp, $netmask);
1047 +
1048 +  print_entry () if %curentry;
1049 +    
1050 +  $ip = next_token (0);
1051 +  parse_error () if !defined ($ip);
1052 +
1053 +  $tmp = next_token (1);
1054 +  parse_error () if !defined ($tmp);
1055 +  parse_error () if !($tmp eq 'netmask');
1056 +
1057 +  $tmp = next_token (0);
1058 +  parse_error () if !defined ($tmp);
1059 +  $netmask = parse_netmask ($tmp);
1060 +
1061 +  $tmp = next_token (0);
1062 +  parse_error () if !defined ($tmp);
1063 +  parse_error () if !($tmp eq '{');
1064 +
1065 +  add_dn_to_stack ("cn=$ip");
1066 +  $curentry{'type'} = 'subnet';
1067 +  $curentry{'ip'} = $ip;
1068 +  $curentry{'netmask'} = $netmask;
1069 +  $cursubnet = $ip;
1070 +  $curcounter{$ip} = { pool  => 0, group => 0 };
1071 +}
1072 +
1073 +
1074 +sub parse_shared_network
1075 +{
1076 +  local ($descr, $tmp);
1077 +
1078 +  print_entry () if %curentry;
1079 +
1080 +  $descr = next_token (0);
1081 +  parse_error () if !defined ($descr);
1082 +
1083 +  $tmp = next_token (0);
1084 +  parse_error () if !defined ($tmp);
1085 +  parse_error () if !($tmp eq '{');
1086 +
1087 +  add_dn_to_stack ("cn=$descr");
1088 +  $curentry{'type'} = 'shared-network';
1089 +  $curentry{'descr'} = $descr;
1090 +}
1091 +
1092 +
1093 +sub parse_host
1094 +{
1095 +  local ($descr, $tmp);
1096 +
1097 +  print_entry () if %curentry;
1098 +
1099 +  $host = next_token (0);
1100 +  parse_error () if !defined ($host);
1101 +
1102 +  $tmp = next_token (0);
1103 +  parse_error () if !defined ($tmp);
1104 +  parse_error () if !($tmp eq '{');
1105 +
1106 +  add_dn_to_stack ("cn=$host");
1107 +  $curentry{'type'} = 'host';
1108 +  $curentry{'host'} = $host;
1109 +}
1110 +
1111 +
1112 +sub parse_group
1113 +{
1114 +  local ($descr, $tmp);
1115 +
1116 +  print_entry () if %curentry;
1117 +
1118 +  $tmp = next_token (0);
1119 +  parse_error () if !defined ($tmp);
1120 +  parse_error () if !($tmp eq '{');
1121 +
1122 +  my $idx;
1123 +  if(exists($curcounter{$cursubnet})) {
1124 +    $idx = ++$curcounter{$cursubnet}->{'group'};
1125 +  } else {
1126 +    $idx = ++$curcounter{''}->{'group'};
1127 +  }
1128 +
1129 +  add_dn_to_stack ("cn=group".$idx);
1130 +  $curentry{'type'} = 'group';
1131 +  $curentry{'idx'} = $idx;
1132 +}
1133 +
1134 +
1135 +sub parse_pool
1136 +{
1137 +  local ($descr, $tmp);
1138 +
1139 +  print_entry () if %curentry;
1140 +
1141 +  $tmp = next_token (0);
1142 +  parse_error () if !defined ($tmp);
1143 +  parse_error () if !($tmp eq '{');
1144 +
1145 +  my $idx;
1146 +  if(exists($curcounter{$cursubnet})) {
1147 +    $idx = ++$curcounter{$cursubnet}->{'pool'};
1148 +  } else {
1149 +    $idx = ++$curcounter{''}->{'pool'};
1150 +  }
1151 +
1152 +  add_dn_to_stack ("cn=pool".$idx);
1153 +  $curentry{'type'} = 'pool';
1154 +  $curentry{'idx'} = $idx;
1155 +}
1156 +
1157 +
1158 +sub parse_class
1159 +{
1160 +  local ($descr, $tmp);
1161 +
1162 +  print_entry () if %curentry;
1163 +
1164 +  $class = next_token (0);
1165 +  parse_error () if !defined ($class);
1166 +
1167 +  $tmp = next_token (0);
1168 +  parse_error () if !defined ($tmp);
1169 +  parse_error () if !($tmp eq '{');
1170 +
1171 +  $class =~ s/\"//g;
1172 +  add_dn_to_stack ("cn=$class");
1173 +  $curentry{'type'} = 'class';
1174 +  $curentry{'class'} = $class;
1175 +}
1176 +
1177 +
1178 +sub parse_subclass
1179 +{
1180 +  local ($descr, $tmp);
1181 +
1182 +  print_entry () if %curentry;
1183 +
1184 +  $class = next_token (0);
1185 +  parse_error () if !defined ($class);
1186 +
1187 +  $subclass = next_token (0);
1188 +  parse_error () if !defined ($subclass);
1189 +
1190 +  $tmp = next_token (0);
1191 +  parse_error () if !defined ($tmp);
1192 +  parse_error () if !($tmp eq '{');
1193 +
1194 +  add_dn_to_stack ("cn=$subclass");
1195 +  $curentry{'type'} = 'subclass';
1196 +  $curentry{'class'} = $class;
1197 +  $curentry{'subclass'} = $subclass;
1198 +}
1199 +
1200 +
1201 +sub parse_hwaddress
1202 +{
1203 +  local ($type, $hw, $tmp);
1204 +
1205 +  $type = next_token (1);
1206 +  parse_error () if !defined ($type);
1207 +
1208 +  $hw = next_token (1);
1209 +  parse_error () if !defined ($hw);
1210 +  $hw =~ s/;$//;
1211 +
1212 +  $curentry{'hwaddress'} = "$type $hw";
1213 +}
1214 +
1215 +    
1216 +sub parse_range
1217 +{
1218 +  local ($tmp, $str);
1219 +
1220 +  $str = remaining_line ();
1221 +
1222 +  if (!($str eq ''))
1223 +    {
1224 +      $str =~ s/;$//;
1225 +      push (@{$curentry{'ranges'}}, $str);
1226 +    }
1227 +}
1228 +
1229 +
1230 +sub parse_statement
1231 +{
1232 +  local ($token) = shift;
1233 +  local ($str);
1234 +
1235 +  if ($token eq 'option')
1236 +    {
1237 +      $str = remaining_line ();
1238 +      push (@{$curentry{'options'}}, $str);
1239 +    }
1240 +  elsif($token eq 'failover')
1241 +    {
1242 +      $str = remaining_line (1); # take care on block
1243 +      if($str =~ /[{]/)
1244 +        {
1245 +          my ($peername, @statements);
1246 +
1247 +          parse_error() if($str !~ /^\s*peer\s+(.+?)\s+[{]\s*$/);
1248 +          parse_error() if(($peername = $1) !~ /^\"?[^\"]+\"?$/);
1249 +
1250 +          #
1251 +          # failover config block found:
1252 +          # e.g. 'failover peer "some-name" {'
1253 +          #
1254 +          if(not grep(/FaIlOvEr/i, @use))
1255 +            {
1256 +              print STDERR "Warning: Failover config 'peer $peername' found!\n";
1257 +              print STDERR "         Skipping it, since failover disabled!\n";
1258 +              print STDERR "         You may try out --use=failover option.\n";
1259 +            }
1260 +
1261 +          until($str =~ /[}]/ or $str eq "")
1262 +            {
1263 +                $str = remaining_line (1);
1264 +                # collect all statements, except ending '}'
1265 +                push(@statements, $str) if($str !~ /[}]/);
1266 +            }
1267 +          $failover{$peername} = [@statements];
1268 +        }
1269 +      else
1270 +        {
1271 +          #
1272 +          # pool reference to failover config is fine
1273 +          # e.g. 'failover peer "some-name";'
1274 +          #
1275 +          if(not grep(/FaIlOvEr/i, @use))
1276 +            {
1277 +              print STDERR "Warning: Failover reference '$str' found!\n";
1278 +              print STDERR "         Skipping it, since failover disabled!\n";
1279 +              print STDERR "         You may try out --use=failover option.\n";
1280 +            }
1281 +          else
1282 +            {
1283 +              push (@{$curentry{'statements'}}, $token. " " . $str);
1284 +            }
1285 +        }
1286 +    }
1287 +  elsif($token eq 'zone')
1288 +    {
1289 +      $str = $token;
1290 +      while($str !~ /}$/) {
1291 +        $str .= ' ' . next_token (0);
1292 +      }
1293 +      push (@{$curentry{'statements'}}, $str);
1294 +    }
1295 +  elsif($token =~ /^(authoritative)[;]*$/)
1296 +    {
1297 +      push (@{$curentry{'statements'}}, $1);
1298 +    }
1299 +  else
1300 +    {
1301 +      $str = $token . " " . remaining_line ();
1302 +      push (@{$curentry{'statements'}}, $str);
1303 +    }
1304 +}
1305 +
1306 +
1307 +my $ok = GetOptions(
1308 +    'basedn=s'      => \$basedn,
1309 +    'dhcpdn=s'      => \$dhcpdn,
1310 +    'server=s'      => \$server,
1311 +    'second=s'      => \$second,
1312 +    'conf=s'        => \$i_conf,
1313 +    'ldif=s'        => \$o_ldif,
1314 +    'use=s'         => \@use,
1315 +    'h|help|usage'  => sub { usage(0); },
1316 +);
1317 +
1318 +unless($server =~ /^\w+/)
1319 +  {
1320 +    usage(1, "invalid server name '$server'");
1321 +  }
1322 +unless($basedn =~ /^\w+=[^,]+/)
1323 +  {
1324 +    usage(1, "invalid base dn '$basedn'");
1325 +  }
1326 +
1327 +if($dhcpdn =~ /^cn=([^,]+)/i)
1328 +  {
1329 +    $dhcpcn = "$1";
1330 +  }
1331 +$second = '' if not defined $second;
1332 +unless($second eq '' or $second =~ /^cn=[^,]+\s*,\s*\w+=[^,]+/i)
1333 +  {
1334 +    if($second =~ /^cn=[^,]+$/i)
1335 +      {
1336 +        # relative DN 'cn=name'
1337 +        $second = "$second, $basedn";
1338 +      }
1339 +    elsif($second =~ /^\w+/)
1340 +      {
1341 +        # assume hostname only
1342 +        $second = "cn=$second, $basedn";
1343 +      }
1344 +    else
1345 +      {
1346 +        usage(1, "invalid secondary '$second'")
1347 +      }
1348 +  }
1349 +
1350 +usage(1) unless($ok);
1351 +
1352 +if($i_conf ne "" and -f $i_conf)
1353 +  {
1354 +    if(not open(STDIN, '<', $i_conf))
1355 +      {
1356 +        print STDERR "Error: can't open conf file '$i_conf': $!\n";
1357 +        exit(1);
1358 +      }
1359 +  }
1360 +if($o_ldif ne "")
1361 +  {
1362 +    if(-e $o_ldif)
1363 +      {
1364 +        print STDERR "Error: output ldif name '$o_ldif' already exists!\n";
1365 +        exit(1);
1366 +      }
1367 +    if(not open(STDOUT, '>', $o_ldif))
1368 +      {
1369 +        print STDERR "Error: can't open ldif file '$o_ldif': $!\n";
1370 +        exit(1);
1371 +      }
1372 +  }
1373 +
1374 +
1375 +print STDERR "Creating LDAP Configuration with the following options:\n";
1376 +print STDERR "\tBase DN: $basedn\n";
1377 +print STDERR "\tDHCP DN: $dhcpdn\n";
1378 +print STDERR "\tServer DN: cn=$server, $basedn\n";
1379 +print STDERR "\tSecondary DN: $second\n"
1380 +             if(grep(/FaIlOvEr/i, @use) and $second ne '');
1381 +print STDERR "\n";
1382 +
1383 +my $token;
1384 +my $token_number = 0;
1385 +my $line_number = 0;
1386 +my %curentry;
1387 +my $cursubnet = '';
1388 +my %curcounter = ( '' => { pool => 0, group => 0 } );
1389 +
1390 +$current_dn = "$dhcpdn";
1391 +$curentry{'descr'} = $dhcpcn;
1392 +$line = '';
1393 +%failover = ();
1394 +
1395 +while (($token = next_token (1)))
1396 +  {
1397 +    if ($token eq '}')
1398 +      {
1399 +        print_entry () if %curentry;
1400 +        if($current_dn =~ /.+?,\s*${dhcpdn}$/) {
1401 +          # don't go below dhcpdn ...
1402 +          remove_dn_from_stack ();
1403 +        }
1404 +      }
1405 +    elsif ($token eq 'subnet')
1406 +      {
1407 +        parse_subnet ();
1408 +        next;
1409 +      }
1410 +    elsif ($token eq 'shared-network')
1411 +      {
1412 +        parse_shared_network ();
1413 +        next;
1414 +      }
1415 +    elsif ($token eq 'class')
1416 +      {
1417 +        parse_class ();
1418 +        next;
1419 +      }
1420 +    elsif ($token eq 'subclass')
1421 +      {
1422 +        parse_subclass ();
1423 +        next;
1424 +      }
1425 +    elsif ($token eq 'pool')
1426 +      {
1427 +        parse_pool ();
1428 +        next;
1429 +      }
1430 +    elsif ($token eq 'group')
1431 +      {
1432 +        parse_group ();
1433 +        next;
1434 +      }
1435 +    elsif ($token eq 'host')
1436 +      {
1437 +        parse_host ();
1438 +        next;
1439 +      }
1440 +    elsif ($token eq 'hardware')
1441 +      {
1442 +        parse_hwaddress ();
1443 +        next;
1444 +      }
1445 +    elsif ($token eq 'range')
1446 +      {
1447 +        parse_range ();
1448 +        next;
1449 +      }
1450 +    else
1451 +      {
1452 +        parse_statement ($token);
1453 +        next;
1454 +      }
1455 +  }
1456 +
1457 +close(STDIN)  if($i_conf);
1458 +close(STDOUT) if($o_ldif);
1459 +
1460 +print STDERR "Done.\n";
1461 +
1462 diff -Naur dhcp-3.0.1rc14/debian/changelog dhcp-3.0.1rc14-ldap/debian/changelog
1463 --- dhcp-3.0.1rc14/debian/changelog     1969-12-31 19:00:00.000000000 -0500
1464 +++ dhcp-3.0.1rc14-ldap/debian/changelog        2004-06-22 15:26:38.000000000 -0400
1465 @@ -0,0 +1,25 @@
1466 +dhcp3-server-ldap (3.0.1rc14-1) unstable; urgency=low
1467 +
1468 +  * See ChangeLog-LDAP for changes in this release
1469 +
1470 + -- Brian Masney <masneyb@gftp.org>  Tue, 22 Jun 2004 15:29:07 -0400
1471 +
1472 +dhcp3-server-ldap (3.0.1rc13-1) unstable; urgency=low
1473 +
1474 +  * See ChangeLog-LDAP for changes in this release
1475 +
1476 + -- Brian Masney <masneyb@gftp.org>  Wed, 05 May 2004 07:20:13 -0400
1477 +
1478 +dhcp3-server-ldap (3.0.1rc12-1) unstable; urgency=low
1479 +
1480 +  * Updated patch to work against ISC DHCPD 3.0.1rc12
1481 +
1482 + -- Brian Masney <masneyb@gftp.org>  Mon, 08 Sep 2003 16:34:00 -0400
1483 +
1484 +dhcp3-server-ldap (3.0.1rc11-2) unstable; urgency=low
1485 +
1486 +  * Added these Debian files. They are mostly from the existing dhcp3-server
1487 +    package in Debian.
1488 +
1489 + -- Brian Masney <masneyb@gftp.org>  Mon, 04 Aug 2003 13:34:00 -0400
1490 +
1491 diff -Naur dhcp-3.0.1rc14/debian/control dhcp-3.0.1rc14-ldap/debian/control
1492 --- dhcp-3.0.1rc14/debian/control       1969-12-31 19:00:00.000000000 -0500
1493 +++ dhcp-3.0.1rc14-ldap/debian/control  2004-06-22 15:18:20.000000000 -0400
1494 @@ -0,0 +1,12 @@
1495 +Source: dhcp3-server-ldap
1496 +Section: net
1497 +Priority: optional
1498 +Maintainer: Brian Masney <masneyb@gftp.org>
1499 +Build-Depends: debhelper (>= 2.1.18), dpkg-dev (>= 1.7.0), groff
1500 +Standards-Version: 2.4.0.0
1501 +
1502 +Package: dhcp3-server-ldap
1503 +Architecture: any
1504 +Depends: debconf, debianutils (>= 1.7), dhcp3-server (>= 3.0+3.0.1rc11)
1505 +Conflicts: dhcp, dhcp3-ldap-ntelos
1506 +Description: This is the DHCP server with LDAP patches applied to it
1507 diff -Naur dhcp-3.0.1rc14/debian/copyright dhcp-3.0.1rc14-ldap/debian/copyright
1508 --- dhcp-3.0.1rc14/debian/copyright     1969-12-31 19:00:00.000000000 -0500
1509 +++ dhcp-3.0.1rc14-ldap/debian/copyright        2004-06-22 15:18:20.000000000 -0400
1510 @@ -0,0 +1,30 @@
1511 +/*
1512 + * Copyright (c) 1996, 1997 The Internet Software Consortium.
1513 + * All rights reserved.
1514 + *
1515 + * Redistribution and use in source and binary forms, with or without
1516 + * modification, are permitted provided that the following conditions
1517 + * are met:
1518 + *
1519 + * 1. Redistributions of source code must retain the above copyright
1520 + *    notice, this list of conditions and the following disclaimer.
1521 + * 2. Redistributions in binary form must reproduce the above copyright
1522 + *    notice, this list of conditions and the following disclaimer in the
1523 + *    documentation and/or other materials provided with the distribution.
1524 + * 3. Neither the name of The Internet Software Consortium nor the names of its
1525 + *    contributors may be used to endorse or promote products derived
1526 + *    from this software without specific prior written permission.
1527 + *
1528 + * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
1529 + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
1530 + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
1531 + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
1532 + * THE INTERNET SOFTWARE CONSORTIUM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
1533 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1534 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1535 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1536 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1537 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1538 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1539 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1540 + */
1541 diff -Naur dhcp-3.0.1rc14/debian/dhcp3-server-ldap.files dhcp-3.0.1rc14-ldap/debian/dhcp3-server-ldap.files
1542 --- dhcp-3.0.1rc14/debian/dhcp3-server-ldap.files       1969-12-31 19:00:00.000000000 -0500
1543 +++ dhcp-3.0.1rc14-ldap/debian/dhcp3-server-ldap.files  2004-06-22 15:18:20.000000000 -0400
1544 @@ -0,0 +1 @@
1545 +usr/sbin/dhcpd3
1546 diff -Naur dhcp-3.0.1rc14/debian/dhcp3-server-ldap.postinst dhcp-3.0.1rc14-ldap/debian/dhcp3-server-ldap.postinst
1547 --- dhcp-3.0.1rc14/debian/dhcp3-server-ldap.postinst    1969-12-31 19:00:00.000000000 -0500
1548 +++ dhcp-3.0.1rc14-ldap/debian/dhcp3-server-ldap.postinst       2004-06-22 15:18:20.000000000 -0400
1549 @@ -0,0 +1,13 @@
1550 +#!/bin/sh
1551 +
1552 +set -e 
1553 +
1554 +# Removes the left over diversions of the old package
1555 +
1556 +if [ "$1" = remove -o "$1" = upgrade ]; then
1557 +       for v in `list_versions`; do
1558 +               dpkg-divert --package dhcp3-server-ldap --remove \
1559 +                       --rename --divert /usr/sbin/dhcpd3-noldap \
1560 +                       /usr/sbin/dhcpd3
1561 +       done
1562 +fi
1563 diff -Naur dhcp-3.0.1rc14/debian/dhcp3-server-ldap.postrm dhcp-3.0.1rc14-ldap/debian/dhcp3-server-ldap.postrm
1564 --- dhcp-3.0.1rc14/debian/dhcp3-server-ldap.postrm      1969-12-31 19:00:00.000000000 -0500
1565 +++ dhcp-3.0.1rc14-ldap/debian/dhcp3-server-ldap.postrm 2004-06-22 15:18:20.000000000 -0400
1566 @@ -0,0 +1,8 @@
1567 +#!/bin/sh
1568 +
1569 +set -e 
1570 +
1571 +if [ "$1" = remove ]; then
1572 +       dpkg-divert --package dhcp3-server-ldap --remove --rename \
1573 +               --divert /usr/sbin/dhcpd3-noldap /usr/sbin/dhcpd3
1574 +fi
1575 diff -Naur dhcp-3.0.1rc14/debian/dhcp3-server-ldap.preinst dhcp-3.0.1rc14-ldap/debian/dhcp3-server-ldap.preinst
1576 --- dhcp-3.0.1rc14/debian/dhcp3-server-ldap.preinst     1969-12-31 19:00:00.000000000 -0500
1577 +++ dhcp-3.0.1rc14-ldap/debian/dhcp3-server-ldap.preinst        2004-06-22 15:18:20.000000000 -0400
1578 @@ -0,0 +1,14 @@
1579 +#!/bin/sh
1580 +
1581 +set -e 
1582 +
1583 +if [ "$1" = install -o "$1" = upgrade ]; then
1584 +       if dpkg-divert --list /usr/sbin/dhcpd3 \
1585 +               | grep -q "by dhcp3-server-ldap";
1586 +       then
1587 +               exit 0
1588 +       fi
1589 +               
1590 +       dpkg-divert --package dhcp3-server-ldap --add --rename \
1591 +               --divert /usr/sbin/dhcpd3-noldap /usr/sbin/dhcpd3
1592 +fi
1593 diff -Naur dhcp-3.0.1rc14/debian/dhcp3-server-ldap.substvars dhcp-3.0.1rc14-ldap/debian/dhcp3-server-ldap.substvars
1594 --- dhcp-3.0.1rc14/debian/dhcp3-server-ldap.substvars   1969-12-31 19:00:00.000000000 -0500
1595 +++ dhcp-3.0.1rc14-ldap/debian/dhcp3-server-ldap.substvars      2004-06-22 15:18:20.000000000 -0400
1596 @@ -0,0 +1 @@
1597 +shlibs:Depends=libc6 (>= 2.3.2.ds1-4), libldap2 (>= 2.1.17-1)
1598 diff -Naur dhcp-3.0.1rc14/debian/dirs dhcp-3.0.1rc14-ldap/debian/dirs
1599 --- dhcp-3.0.1rc14/debian/dirs  1969-12-31 19:00:00.000000000 -0500
1600 +++ dhcp-3.0.1rc14-ldap/debian/dirs     2004-06-22 15:18:20.000000000 -0400
1601 @@ -0,0 +1 @@
1602 +usr/sbin
1603 diff -Naur dhcp-3.0.1rc14/debian/files dhcp-3.0.1rc14-ldap/debian/files
1604 --- dhcp-3.0.1rc14/debian/files 1969-12-31 19:00:00.000000000 -0500
1605 +++ dhcp-3.0.1rc14-ldap/debian/files    2004-06-22 15:18:20.000000000 -0400
1606 @@ -0,0 +1 @@
1607 +dhcp3-server-ldap_3.0.1rc13-1_i386.deb net optional
1608 diff -Naur dhcp-3.0.1rc14/debian/rules dhcp-3.0.1rc14-ldap/debian/rules
1609 --- dhcp-3.0.1rc14/debian/rules 1969-12-31 19:00:00.000000000 -0500
1610 +++ dhcp-3.0.1rc14-ldap/debian/rules    2004-06-22 15:18:20.000000000 -0400
1611 @@ -0,0 +1,87 @@
1612 +#!/usr/bin/make -f
1613 +# Made with the iad of dh_make, by Craig Small
1614 +# Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess.
1615 +# Also some stuff taken from debmake scripts, by Cristopt Lameter.
1616 +
1617 +# Uncomment this to turn on verbose mode.
1618 +#export DH_VERBOSE=1
1619 +
1620 +export DH_COMPAT=3
1621 +
1622 +DESTDIR = `pwd`/debian/tmp
1623 +
1624 +IVARS = DESTDIR=$(DESTDIR)
1625 +
1626 +BVARS = PREDEFINES='-D_PATH_DHCPD_DB=\"/var/lib/dhcp3/dhcpd.leases\" \
1627 +       -D_PATH_DHCLIENT_DB=\"/var/lib/dhcp3/dhclient.leases\" \
1628 +       -D_PATH_DHCLIENT_SCRIPT=\"/etc/dhcp3/dhclient-script\" \
1629 +       -D_PATH_DHCPD_CONF=\"/etc/dhcp3/dhcpd.conf\" \
1630 +        -D_PATH_DHCLIENT_CONF=\"/etc/dhcp3/dhclient.conf\"'
1631 +
1632 +build: build-stamp
1633 +build-stamp:
1634 +       dh_testdir
1635 +
1636 +       ./configure
1637 +       $(MAKE) $(BVARS)
1638 +
1639 +       touch build-stamp
1640 +
1641 +clean: 
1642 +       dh_testdir
1643 +       rm -f build-stamp install-stamp
1644 +
1645 +       # Add here commands to clean up after the build process.
1646 +       -$(MAKE) distclean
1647 +
1648 +       # Remove leftover junk...
1649 +       rm -Rf work.linux-2.2/
1650 +
1651 +       dh_clean
1652 +
1653 +install: install-stamp
1654 +install-stamp: build-stamp
1655 +       dh_testdir
1656 +       dh_testroot
1657 +       dh_clean -k
1658 +       dh_installdirs
1659 +
1660 +       # Add here commands to install the package into debian/tmp.
1661 +       $(MAKE) install $(IVARS)
1662 +
1663 +       mv $(DESTDIR)/usr/sbin/dhcpd $(DESTDIR)/usr/sbin/dhcpd3
1664 +
1665 +       dh_movefiles
1666 +
1667 +       # Remove unwanted directories that dh_movefiles leaves around
1668 +       rmdir $(DESTDIR)/etc
1669 +       rm -Rf $(DESTDIR)/sbin/
1670 +       rm -Rf $(DESTDIR)/usr/bin/
1671 +       rm -Rf $(DESTDIR)/usr/include/
1672 +       rm -Rf $(DESTDIR)/usr/lib/
1673 +       rm -Rf $(DESTDIR)/usr/local/
1674 +       rm -Rf $(DESTDIR)/usr/man/
1675 +       rm -Rf $(DESTDIR)/var/
1676 +       rm -f $(DESTDIR)/usr/sbin/dhcrelay
1677 +
1678 +       touch install-stamp
1679 +
1680 +# Build architecture-dependent files here (this package does not contain
1681 +#      architecture-independent files).
1682 +binary-arch: build install
1683 +       dh_testdir -a
1684 +       dh_testroot -a
1685 +       dh_strip -a
1686 +       dh_compress -a
1687 +       dh_fixperms -a
1688 +       dh_installdeb -a
1689 +       dh_shlibdeps -a
1690 +       dh_gencontrol -a
1691 +       dh_md5sums -a
1692 +       dh_builddeb -a
1693 +
1694 +source diff:                                                                  
1695 +       @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false
1696 +
1697 +binary: binary-arch
1698 +.PHONY: build clean binary-indep binary-arch binary
1699 diff -Naur dhcp-3.0.1rc14/doc/draft-ietf-dhc-ldap-schema-01.txt dhcp-3.0.1rc14-ldap/doc/draft-ietf-dhc-ldap-schema-01.txt
1700 --- dhcp-3.0.1rc14/doc/draft-ietf-dhc-ldap-schema-01.txt        1969-12-31 19:00:00.000000000 -0500
1701 +++ dhcp-3.0.1rc14-ldap/doc/draft-ietf-dhc-ldap-schema-01.txt   2004-06-22 15:18:20.000000000 -0400
1702 @@ -0,0 +1,1089 @@
1703 +
1704 +
1705 +
1706 +
1707 +
1708 +Network Working Group                                  M. Meredith,
1709 +Internet Draft                                         V. Nanjundaswamy,
1710 +Document: <draft-ietf-dhc-ldap-schema-00.txt>          M. Hinckley
1711 +Category: Proposed Standard                            Novell Inc.
1712 +Expires: 15th December 2001                            16th June 2001
1713 +
1714 +
1715 +                          LDAP Schema for DHCP
1716 +
1717 +Status of this Memo
1718 +
1719 +This document is an Internet-Draft and is in full conformance with all
1720 +provisions of Section 10 of RFC2026 [ ].
1721 +
1722 +Internet-Drafts are working documents of the Internet Engineering Task
1723 +Force (IETF), its areas, and its working groups.  Note that other groups
1724 +may also distribute working documents as Internet-Drafts. Internet-
1725 +Drafts are draft documents valid for a maximum of six months and may be
1726 +updated, replaced, or obsolete by other documents at any time.  It is
1727 +inappropriate to use Internet-Drafts as reference material or to cite
1728 +them other than as "work in progress."  The list of current Internet-
1729 +Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt The
1730 +list of Internet-Draft Shadow Directories can be accessed at
1731 +http://www.ietf.org/shadow.html.
1732 +
1733 +1. Abstract
1734 +
1735 +This document defines a schema for representing DHCP configuration in an
1736 +LDAP directory. It can be used to represent the DHCP Service
1737 +configuration(s) for an entire enterprise network, a subset of the
1738 +network, or even a single server. Representing DHCP configuration in an
1739 +LDAP directory enables centralized management of DHCP services offered
1740 +by one or more DHCP Servers within the enterprise.
1741 +
1742 +2. Conventions used in this document
1743 +
1744 +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
1745 +"SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and "OPTIONAL" in this
1746 +document are to be interpreted as described in RFC-2119 [ ].
1747 +
1748 +In places where different sets of terminology are commonly used to
1749 +represent similar DHCP concepts, this schema uses the terminology of the
1750 +Internet Software Consortium's DHCP server reference implementation.
1751 +For more information see www.isc.org.
1752 +
1753 +3. Design Considerations
1754 +
1755 +The DHCP LDAP schema is designed to be a simple multi-server schema. The
1756 +
1757 +
1758 +
1759 +M. Meredith et al.        Expires December 2001                 [Page 1]
1760 +
1761 +
1762 +
1763 +
1764 +
1765 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
1766 +
1767 +
1768 +intent of this schema is to provide a basic framework for representing
1769 +the most common elements used in the configuration of DHCP Server.  This
1770 +should allow other network services to obtain and use basic DHCP
1771 +configuration information in a server-independent but knowledgeable way.
1772 +
1773 +It is expected that some implementations may need to extend the schema
1774 +objects, in order to implement all of their features or needs. It is
1775 +recommended that you use the schema defined in this draft to represent
1776 +DHCP configuration information in an LDAP directory.  Conforming to a
1777 +standard schema improves interoperability between DHCP implementations
1778 +from different vendors.
1779 +
1780 +Some implementations may choose not to support all of the objects
1781 +defined here.
1782 +
1783 +Two decisions are explicitly left up to each implementation:
1784 +
1785 +First, implementations may choose not to store the lease information in
1786 +the directory, so those objects would not be used.
1787 +
1788 +Second, implementations may choose not to implement the auditing
1789 +information.
1790 +
1791 +It is up to the implementation to determine if the data in the directory
1792 +is considered "authoritative", or if it is simply a copy of data from an
1793 +authoritative source. Validity of the information if used as a copy is
1794 +to be ensured by the implementation.
1795 +
1796 +Primarily two types of applications will use the information in this
1797 +schema: 1. DHCP servers (for loading their configuration) 2. Management
1798 +Interfaces (for defining/editing configurations).
1799 +
1800 +The schema should be efficient for the needs of both types of
1801 +applications.  The schema is designed to allow objects managed by DHCP
1802 +(such as computers, subnets, etc) to be present anywhere in a directory
1803 +hierarchy (to allow those objects to be placed in the directory for
1804 +managing administrative control and access to the objects).
1805 +
1806 +The schema uses a few naming conventions - all object classes and
1807 +attributes are prefixed with "dhcp" to decrease the chance that object
1808 +classes and attributes will have the same name.  The schema also uses
1809 +standard naming attributes ("cn", "ou", etc) for all objects.
1810 +
1811 +4. Common DHCP Configuration Attributes
1812 +
1813 +Although DHCP manages several different types of objects, the
1814 +configuration of those objects is often similar.  Consequently, most of
1815 +these objects have a common set of attributes, which are defined below.
1816 +
1817 +
1818 +
1819 +M. Meredith et al.        Expires December 2001                 [Page 2]
1820 +
1821 +
1822 +
1823 +
1824 +
1825 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
1826 +
1827 +
1828 +4.1. Attributes Definitions
1829 +
1830 +The schema definitions listed below are for readability.  The LDIF
1831 +layout for this schema will follow in section 8.
1832 +
1833 +Name: dhcpPrimaryDN Description: The Distinguished Name of the
1834 +dhcpServer object, which is the primary server for the configuration.
1835 +Syntax: DN Flags: SINGLE-VALUE
1836 +
1837 +Named: dhcpSecondaryDN Description: The Distinguished Name(s) of the
1838 +dhcpServer object(s), which are secondary servers for the configuration.
1839 +Syntax: DN
1840 +
1841 +Name: dhcpStatements Description: Flexible storage for representing any
1842 +specific data depending on the object to which it is attached. Examples
1843 +include conditional statements, Server parameters, etc.  This also
1844 +serves as a 'catch-all' attribute that allows the standard to evolve
1845 +without needing to update the schema.  Syntax: IA5String
1846 +
1847 +Name: dhcpRange Description: The starting and ending IP Addresses in the
1848 +range (inclusive), separated by a hyphen; if the range only contains one
1849 +address, then just the address can be specified with no hyphen.  Each
1850 +range is defined as a separate value.  Syntax: IA5String
1851 +
1852 +Name: dhcpPermitList Description: This attribute contains the permit
1853 +lists associated with a pool. Each permit list is defined as a separate
1854 +value.  Syntax: IA5String
1855 +
1856 +Name: dhcpNetMask Description: The subnet mask length for the subnet.
1857 +The mask can be easily computed from this length.  Syntax: Integer
1858 +Flags: SINGLE-VALUE
1859 +
1860 +Name: dhcpOption Description: Encoded option values to be sent to
1861 +clients.  Each value represents a single option and contains (OptionTag,
1862 +Length, OptionData) encoded in the format used by DHCP.  For more
1863 +information see [DHCPOPT].  Syntax: OctetString
1864 +
1865 +Name: dhcpClassData Description: Encoded text string or list of bytes
1866 +expressed in hexadecimal, separated by colons. Clients match subclasses
1867 +based on matching the class data with the results of a 'match' or 'spawn
1868 +with' statement in the class name declarations.  Syntax: IA5String
1869 +Flags: SINGLE-VALUE
1870 +
1871 +Name: dhcpSubclassesDN Description: List of subclasses, these are the
1872 +actual DN of each subclass object.  Syntax: DN
1873 +
1874 +Name: dhcpClassesDN Description: List of classes, these are the actual
1875 +DN of each class object.  Syntax: DN
1876 +
1877 +
1878 +
1879 +M. Meredith et al.        Expires December 2001                 [Page 3]
1880 +
1881 +
1882 +
1883 +
1884 +
1885 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
1886 +
1887 +
1888 +Name: dhcpSubnetDN Description: List of subnets, these are the actual DN
1889 +of each subnet object.  Syntax: DN
1890 +
1891 +Name: dhcpPoolDN Description: List of pools, these are the actual DN of
1892 +each Pool object.  Syntax: DN
1893 +
1894 +Name: dhcpOptionsDN Description: List of options, these are the actual
1895 +DN of each Options object.  Syntax: DN
1896 +
1897 +Name: dhcpHostDN Description: List of hosts, these are the actual DN of
1898 +each host object.  Syntax: DN
1899 +
1900 +Name: dhcpSharedNetworkDN Description: List of shared networks, these
1901 +are the actual DN of each shared network object.  Syntax: DN
1902 +
1903 +Name: dhcpGroupDN Description: List of groups, these are the actual DN
1904 +of each Group object.  Syntax: DN
1905 +
1906 +Name: dhcpLeaseDN Description: Single Lease DN. A dhcpHost configuration
1907 +uses this attribute to identify a static IP address assignment.  Syntax:
1908 +DN Flags: SINGLE-VALUE
1909 +
1910 +Name: dhcpLeasesDN Description: List of leases, these are the actual DN
1911 +of each lease object.  Syntax: DN
1912 +
1913 +Name: dhcpServiceDN Description: The DN of dhcpService object(s)which
1914 +contain the configuration information. Each dhcpServer object has this
1915 +attribute identifying the DHCP configuration(s) that the server is
1916 +associated with.  Syntax: DN
1917 +
1918 +Name: dhcpHWAddress Description: The hardware address of the client
1919 +associated with a lease Syntax: OctetString Flags: SINGLE-VALUE
1920 +
1921 +Name: dhcpVersion Description: This is the version identified for the
1922 +object that this attribute is part of. In case of the dhcpServer object,
1923 +this represents the DHCP software version.  Syntax: IA5String Flags:
1924 +SINGLE-VALUE
1925 +
1926 +Name: dhcpImplementation Description: DHCP Server implementation
1927 +description e.g. DHCP Vendor information.  Syntax: IA5String Flags:
1928 +SINGLE-VALUE
1929 +
1930 +Name: dhcpHashBucketAssignment Description: HashBucketAssignment bit map
1931 +for the DHCP Server, as defined in DHC Load Balancing Algorithm [RFC
1932 +3074].  Syntax: Octet String Flags: SINGLE-VALUE
1933 +
1934 +Name: dhcpDelayedServiceParameter Description: Delay in seconds
1935 +corresponding to Delayed Service Parameter configuration, as defined in
1936 +
1937 +
1938 +
1939 +M. Meredith et al.        Expires December 2001                 [Page 4]
1940 +
1941 +
1942 +
1943 +
1944 +
1945 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
1946 +
1947 +
1948 +DHC Load Balancing Algorithm [RFC 3074].  Syntax: Integer Flags: SINGLE-
1949 +VALUE
1950 +
1951 +Name: dhcpMaxClientLeadTime Description: Maximum Client Lead Time
1952 +configuration in seconds, as defined in DHCP Failover Protocol [FAILOVR]
1953 +Syntax: Integer Flags: SINGLE-VALUE
1954 +
1955 +Name: dhcpFailOverEndpointState Description: Server (Failover Endpoint)
1956 +state, as defined in DHCP Failover Protocol [FAILOVR] Syntax: IA5String
1957 +Flags: SINGLE-VALUE
1958 +
1959 +5. Configurations and Services
1960 +
1961 +The schema definitions below are for readability the LDIF layout for
1962 +this schema will follow in section 8.
1963 +
1964 +The DHC working group is currently considering several proposals for
1965 +fail-over and redundancy of DHCP servers.  These may require sharing of
1966 +configuration information between servers.  This schema provides a
1967 +generalized mechanism for supporting any of these proposals, by
1968 +separating the definition of a server from the definition of
1969 +configuration service provided by the server.
1970 +
1971 +Separating the DHCP Server (dhcpServer) and the DHCP Configuration
1972 +(dhcpService) representations allows a configuration service to be
1973 +provided by one or more servers. Similarly, a server may provide one or
1974 +more configurations. The schema allows a server to be configured as
1975 +either a primary or secondary provider of a DHCP configuration.
1976 +
1977 +Configurations are also defined so that one configuration can include
1978 +some of the objects that are defined in another configuration.  This
1979 +allows for sharing and/or a hierarchy of related configuration items.
1980 +
1981 +Name: dhcpService Description:  Service object that represents the
1982 +actual DHCP Service configuration. This will be a container with the
1983 +following attributes.  Must: cn, dhcpPrimaryDN May: dhcpSecondaryDN,
1984 +dhcpSharedNetworkDN, dhcpSubnetDN, dhcpGroupDN, dhcpHostDN,
1985 +dhcpClassesDN, dhcpOptionsDN, dhcpStatements
1986 +
1987 +The following objects could exist inside the dhcpService container:
1988 +dhcpSharedNetwork, dhcpSubnet, dhcpGroup, dhcpHost, dhcpClass,
1989 +dhcpOptions, dhcpLog
1990 +
1991 +Name: dhcpServer Description:  Server object that the DHCP server will
1992 +login as.  The configuration information is in the dhcpService container
1993 +that the dhcpServiceDN points to.  Must: cn, dhcpServiceDN May:
1994 +dhcpVersion, dhcpImplementation, dhcpHashBucketAssignment,
1995 +dhcpDelayedServiceParameter, dhcpMaxClientLeadTime, 
1996 +
1997 +
1998 +
1999 +M. Meredith et al.        Expires December 2001                 [Page 5]
2000 +
2001 +
2002 +
2003 +
2004 +
2005 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
2006 +dhcpFailOverEndpointState, dhcpStatements
2007 +
2008 +5.1. DHCP Declaration related classes:
2009 +
2010 +Name: dhcpSharedNetwork Description: Shared Network class will list what
2011 +pools and subnets are in this network.
2012 +
2013 +This will be a container with the following attributes.  Must: cn May:
2014 +dhcpSubnetDN, dhcpPoolDN, dhcpOptionsDN, dhcpStatements
2015 +
2016 +The following objects can exist within a dhcpSharedNetwork container:
2017 +dhcpSubnet, dhcpPool, dhcpOptions, dhcpLog
2018 +
2019 +Name: dhcpSubnet Description: Subnet object will include configuration
2020 +information associated with a subnet, including a range and a net mask.
2021 +
2022 +This will be a container with the following attributes.  Must: cn
2023 +(Subnet address), dhcpNetMask May: dhcpRange, dhcpPoolDN, dhcpGroupDN,
2024 +dhcpHostDN, dhcpClassesDN, dhcpLeasesDN, dhcpOptionsDN, dhcpStatements
2025 +
2026 +The following objects can exist within a dhcpSubnet container: dhcpPool,
2027 +dhcpGroup, dhcpHost, dhcpClass, dhcpOptions, dhcpLease, dhcpLog
2028 +
2029 +Name: dhcpGroup Description: Group object will have configuration
2030 +information associated with a group.
2031 +
2032 +This will be a container with the following attributes.  Must: cn May:
2033 +dhcpHostDN, dhcpOptionsDN, dhcpStatements
2034 +
2035 +The following objects can exist within a dhcpGroup container: dhcpHost,
2036 +dhcpOptions
2037 +
2038 +Name: dhcpHost Description: The host object includes DHCP host
2039 +declarations to assign a static IP address or declare the client as
2040 +known or specify statements for a specific client.  Must: cn May:
2041 +dhcpLeaseDN, dhcpHWAddress, dhcpOptionsDN, dhcpStatements
2042 +
2043 +The following objects can exist within a dhcpHost container: dhcpLease,
2044 +dhcpOptions
2045 +
2046 +Name: dhcpOptions Description: The options class is for option space
2047 +declarations, it contains a list of options.  Must: cn, dhcpOption
2048 +
2049 +Name: dhcpClass Description: This is a class to group clients together
2050 +based on matching rules.
2051 +
2052 +This will be a container with the following attributes.  Must: cn May:
2053 +dhcpSubClassesDN, dhcpOptionsDN, dhcpStatements
2054 +
2055 +The following object can exist within a dhcpClass container:
2056 +dhcpSubclass, dhcpOptions
2057 +
2058 +
2059 +
2060 +M. Meredith et al.        Expires December 2001                 [Page 6]
2061 +
2062 +
2063 +
2064 +
2065 +
2066 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
2067 +
2068 +
2069 +Name: dhcpSubClass Description: This includes configuration information
2070 +for a subclass associated with a class. The dhcpSubClass object will
2071 +always be contained within the corresponding class container object.
2072 +Must: cn May:  dhcpClassData, dhcpOptionsDN, dhcpStatements
2073 +
2074 +Name: dhcpPool Description: This contains configuration for a pool that
2075 +will have the range of addresses, permit lists and point to classes and
2076 +leases that are members of this pool.
2077 +
2078 +This will be a container that could be contained by dhcpSubnet or a
2079 +dhcpSharedNetwork.  Must: cn, dhcpRange May: dhcpClassesDN,
2080 +dhcpPermitList, dhcpLeasesDN, dhcpOptionsDN, dhcpStatements
2081 +
2082 +The following objects can exist within a dhcpPool container: dhcpClass,
2083 +dhcpOptions, dhcpLease, dhcpLog
2084 +
2085 +6. Tracking Address Assignments
2086 +
2087 +The behavior of a DHCP server is influenced by two factors - it's
2088 +configuration and the current state of the addresses that have been
2089 +assigned to clients. This schema defines a set of objects for
2090 +representing the DHCP configuration associated with a server. The
2091 +following object classes provide the ability to record how addresses are
2092 +used including maintaining history (audit log) on individual leases.
2093 +Recording lease information in a directory could result in a significant
2094 +performance impact and is therefore optional. Implementations supporting
2095 +logging of leases need to consider the performance impact.
2096 +
2097 +6.1. dhcpLeases Attribute Definitions
2098 +
2099 +The schema definitions below are for readability the LDIF layout for
2100 +this schema will follow in section 8.
2101 +
2102 +Name: dhcpAddressState Description: This stores information about the
2103 +current binding-status of an address.  For dynamic addresses managed by
2104 +DHCP, the values should be restricted to the states defined in the DHCP
2105 +Failover Protocol draft [FAILOVR]: 'FREE', 'ACTIVE', 'EXPIRED',
2106 +'RELEASED', 'RESET', 'ABANDONED', 'BACKUP'.  For more information on
2107 +these states see [FAILOVR].  For other addresses, it SHOULD be one of
2108 +the following: 'UNKNOWN', 'RESERVED' (an address that is managed by DHCP
2109 +that is reserved for a specific client), 'RESERVED-ACTIVE' (same as
2110 +reserved, but address is currently in use),  'ASSIGNED' (assigned
2111 +manually or by some other mechanism), 'UNASSIGNED', 'NOTASSIGNABLE'.
2112 +Syntax: IA5String Flags: SINGLE-VALUE
2113 +
2114 +Name: dhcpExpirationTime Description: This is the time the current lease
2115 +for an address expires.  Syntax: DateTime Flags: SINGLE-VALUE
2116 +
2117 +
2118 +
2119 +
2120 +M. Meredith et al.        Expires December 2001                 [Page 7]
2121 +
2122 +
2123 +
2124 +
2125 +
2126 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
2127 +
2128 +
2129 +Name: dhcpStartTimeOfState Description: This is the time of the last
2130 +state change for a leased address.  Syntax: DateTime Flags: SINGLE-VALUE
2131 +
2132 +Name: dhcpLastTransactionTime Description: This is the last time a valid
2133 +DHCP packet was received from the client.  Syntax: DateTime Flags:
2134 +SINGLE-VALUE
2135 +
2136 +Name: dhcpBootpFlag Description: This indicates whether the address was
2137 +assigned via BOOTP Syntax: Boolean Flags: SINGLE-VALUE
2138 +
2139 +Name: dhcpDomainName Description: This is the name of the domain sent to
2140 +the client by the server.  It is essentially the same as the value for
2141 +DHCP option 15 sent to the client, and represents only the domain - not
2142 +the full FQDN.  To obtain the full FQDN assigned to the client you must
2143 +prepend the "dhcpAssignedHostName" to this value with a ".".  Syntax:
2144 +IA5String Flags: SINGLE-VALUE
2145 +
2146 +Name: dhcpDnsStatus Description: This indicates the status of updating
2147 +DNS resource records on behalf of the client by the DHCP server for this
2148 +address.  The value is a 16-bit bitmask that has the same values as
2149 +specified by the Failover-DDNS option (see [FAILOVR]).  Syntax: Integer
2150 +Flags: SINGLE-VALUE
2151 +
2152 +Name: dhcpRequestedHostName Description: This is the hostname that was
2153 +requested by the client.  Syntax: IA5String Flags: SINGLE-VALUE
2154 +
2155 +Name: dhcpAssignedHostName Description: This is the actual hostname that
2156 +was assigned to a client. It may not be the name that was requested by
2157 +the client.  The fully qualified domain name can be determined by
2158 +appending the value of "dhcpDomainName" (with a dot separator) to this
2159 +name.  Syntax: IA5String Flags: SINGLE-VALUE
2160 +
2161 +Name: dhcpReservedForClient Description: This is the distinguished name
2162 +of the "dhcpHost" that an address is reserved for.  This may not be the
2163 +same as the "dhcpAssignedToClient" attribute if the address is being
2164 +reassigned but the current lease has not yet expired.  Syntax: DN Flags:
2165 +SINGLE-VALUE
2166 +
2167 +Name: dhcpAssignedToClient Description: This is the distinguished name
2168 +of a "dhcpHost" that an address is currently assigned to.  This
2169 +attribute is only present in the class when the address is leased.
2170 +Syntax: DN Flags: SINGLE-VALUE
2171 +
2172 +Name: dhcpRelayAgentInfo Description: If the client request was received
2173 +via a relay agent, this contains information about the relay agent that
2174 +was available from the DHCP request.  This is a hex-encoded option
2175 +value.  Syntax: OctetString Flags: SINGLE-VALUE
2176 +
2177 +Name: dhcpErrorLog Description: Generic error log attribute that allows
2178 +logging error conditions within a dhcpService or a dhcpSubnet, like no IP 
2179 +addresses available for lease. Syntax: IA5String 
2180 +
2181 +M. Meredith et al.        Expires December 2001                 [Page 8]
2182 +
2183 +
2184 +
2185 +
2186 +
2187 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
2188 +
2189 +
2190 +6.2.  dhcpLeases Object Class
2191 +
2192 +This class represents an IP address.  It may or may not be leaseable,
2193 +and the object may exist even though a lease is not currently active for
2194 +the associated IP address.
2195 +
2196 +It is recommended that all Lease objects for a single DHCP Service be
2197 +centrally located within a single container. This ensures that the lease
2198 +objects and the corresponding logs do not have to be relocated, when
2199 +address ranges allocated to individual DHCP subnets and/or pools change.
2200 +
2201 +The schema definitions below are for readability the LDIF layout for
2202 +this schema will follow in section 8.
2203 +
2204 +Name: dhcpLeases Description: This is the object that holds state
2205 +information about an IP address. The cn (which is the IP address), and
2206 +the current address-state are mandatory attributes. If the address is
2207 +assigned then, some of the optional attributes will have valid data.
2208 +Must: cn, dhcpAddressState May: dhcpExpirationTime,
2209 +dhcpStartTimeOfState, dhcpLastTransactionTime, dhcpBootpFlag,
2210 +dhcpDomainName, dhcpDnsStatus, dhcpRequestedHostName,
2211 +dhcpAssignedHostName, dhcpReservedForClient, dhcpAssignedToClient,
2212 +dhcpRelayAgentInfo, dhcpHWAddress
2213 +
2214 +6.3 Audit Log Information
2215 +
2216 +A dhcpLog object is created whenever a lease is assigned or released.
2217 +This object is intended to be created under the corresponding dhcpLeases
2218 +container, or dhcpPool, dhcpSubnet, dhcpSharedNetwork or dhcpService
2219 +containers.
2220 +
2221 +The log information under the dhcpLeases container would be for
2222 +addresses matching that lease information. The log information in the
2223 +other containers could be used for errors, i.e. when a pool or subnet is
2224 +out our addresses or if a server is not able to assign any more
2225 +addresses for a particular dhcpService.
2226 +
2227 +Name: dhcpLog Description: This is the object that holds past
2228 +information about an IP address. The cn is the time/date stamp when the
2229 +address was assigned or released, the address state at the time, if the
2230 +address was assigned or released.  Must: cn May: dhcpAddressState,
2231 +dhcpExpirationTime, dhcpStartTimeOfState, dhcpLastTransactionTime,
2232 +dhcpBootpFlag, dhcpDomainName, dhcpDnsStatus, dhcpRequestedHostName,
2233 +dhcpAssignedHostName, dhcpReservedForClient, dhcpAssignedToClient,
2234 +dhcpRelayAgentInfo, dhcpHWAddress, dhcpErrorLog
2235 +
2236 +
2237 +
2238 +
2239 +
2240 +
2241 +M. Meredith et al.        Expires December 2001                 [Page 9]
2242 +
2243 +
2244 +
2245 +
2246 +
2247 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
2248 +
2249 +
2250 +7. Determining settings
2251 +
2252 +The dhcpStatements attribute is the key to DHC enhancements that may
2253 +come along, and the different key words that a particular server
2254 +implementation may use. This attribute can be used to hold conditional
2255 +DHCP Statements and DHCP server parameters. Having a generic settings
2256 +attribute that is just a string, allows this schema to be extensible and
2257 +easy to configure.
2258 +
2259 +All of the attributes that end with DN are references to the class that
2260 +precedes the DN e.g. the dhcpPrimaryDN and dhcpSecondaryDN attributes
2261 +hold the Distinguished Names of the dhcpServer objects that are
2262 +associated with the dhcpService object.
2263 +
2264 +8. LDIF format for attributes and classes.
2265 +
2266 +# Attributes
2267 +
2268 +( 2.16.840.1.113719.1.203.4.1 NAME 'dhcpPrimaryDN' DESC
2269 +'The DN of the dhcpServer which is the primary server for the
2270 +configuration.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
2271 +
2272 +( 2.16.840.1.113719.1.203.4.2 NAME 'dhcpSecondaryDN' DESC 'The DN of
2273 +dhcpServer(s) which provide backup service for the configuration.'
2274 +SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
2275 +
2276 +( 2.16.840.1.113719.1.203.4.3 NAME 'dhcpStatements' DESC 'Flexible
2277 +storage for specific data depending on what object this exists in. Like
2278 +conditional statements, server parameters, etc. This allows the standard
2279 +to evolve without needing to adjust the schema.' SYNTAX
2280 +1.3.6.1.4.1.1466.115.121.1.26 )
2281 +
2282 +( 2.16.840.1.113719.1.203.4.4 NAME 'dhcpRange' DESC 'The starting &
2283 +ending IP Addresses in the range (inclusive), separated by a hyphen; if
2284 +the range only contains one address, then just the address can be
2285 +specified with no hyphen.  Each range is defined as a separate value.'
2286 +SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
2287 +
2288 +( 2.16.840.1.113719.1.203.4.5 NAME 'dhcpPermitList' DESC 'This attribute
2289 +contains the permit lists associated with a pool. Each permit list is
2290 +defined as a separate value.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
2291 +
2292 +( 2.16.840.1.113719.1.203.4.6 NAME 'dhcpNetMask' DESC 'The subnet mask
2293 +length for the subnet.  The mask can be easily computed from this
2294 +length.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
2295 +
2296 +( 2.16.840.1.113719.1.203.4.7 NAME 'dhcpOption' DESC 'Encoded option
2297 +values to be sent to clients.  Each value represents a single option and
2298 +contains (OptionTag, Length, OptionValue) encoded in the format used by
2299 +DHCP.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
2300 +
2301 +M. Meredith et al.        Expires December 2001                [Page 10]
2302 +
2303 +
2304 +
2305 +
2306 +
2307 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
2308 +
2309 +
2310 +( 2.16.840.1.113719.1.203.4.8 NAME 'dhcpClassData' DESC 'Encoded text
2311 +string or list of bytes expressed in hexadecimal, separated by colons.
2312 +Clients match subclasses based on matching the class data with the
2313 +results of match or spawn with statements in the class name
2314 +declarations.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
2315 +
2316 +( 2.16.840.1.113719.1.203.4.9 NAME 'dhcpOptionsDN' DESC 'The
2317 +distinguished name(s) of the dhcpOption objects containing the
2318 +configuration options provided by the server.' SYNTAX
2319 +1.3.6.1.4.1.1466.115.121.1.12 )
2320 +
2321 +( 2.16.840.1.113719.1.203.4.10 NAME 'dhcpHostDN' DESC 'the distinguished
2322 +name(s) of the dhcpHost objects.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
2323 +
2324 +( 2.16.840.1.113719.1.203.4.11 NAME 'dhcpPoolDN' DESC 'The distinguished
2325 +name(s) of pools.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
2326 +
2327 +( 2.16.840.1.113719.1.203.4.12 NAME 'dhcpGroupDN' DESC 'The
2328 +distinguished name(s)   of the groups.' SYNTAX
2329 +1.3.6.1.4.1.1466.115.121.1.12 )
2330 +
2331 +( 2.16.840.1.113719.1.203.4.13 NAME 'dhcpSubnetDN' DESC 'The
2332 +distinguished name(s) of the subnets.' SYNTAX
2333 +1.3.6.1.4.1.1466.115.121.1.12 )
2334 +
2335 +( 2.16.840.1.113719.1.203.4.14 NAME 'dhcpLeaseDN' DESC 'The
2336 +distinguished name of a client address.' SYNTAX
2337 +1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE)
2338 +
2339 +( 2.16.840.1.113719.1.203.4.15 NAME 'dhcpLeasesDN' DESC 'The
2340 +distinguished name(s) client addresses.' SYNTAX
2341 +1.3.6.1.4.1.1466.115.121.1.12 )
2342 +
2343 +( 2.16.840.1.113719.1.203.4.16 NAME 'dhcpClassesDN' DESC 'The
2344 +distinguished name(s) of a class(es) in a subclass.' SYNTAX
2345 +1.3.6.1.4.1.1466.115.121.1.12 )
2346 +
2347 +( 2.16.840.1.113719.1.203.4.17 NAME 'dhcpSubclassesDN' DESC 'The
2348 +distinguished name(s) of subclass(es).' SYNTAX
2349 +1.3.6.1.4.1.1466.115.121.1.12 )
2350 +
2351 +( 2.16.840.1.113719.1.203.4.18 NAME 'dhcpSharedNetworkDN' DESC 'The
2352 +distinguished name(s) of sharedNetworks.' SYNTAX
2353 +1.3.6.1.4.1.1466.115.121.1.12 )
2354 +
2355 +( 2.16.840.1.113719.1.203.4.19 NAME 'dhcpServiceDN' DESC 'The DN of
2356 +dhcpService object(s)which contain the configuration information. Each
2357 +dhcpServer object has this attribute identifying the DHCP
2358 +
2359 +
2360 +
2361 +M. Meredith et al.        Expires December 2001                [Page 11]
2362 +
2363 +
2364 +
2365 +
2366 +
2367 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
2368 +
2369 +
2370 +configuration(s) that the server is associated with.' SYNTAX
2371 +1.3.6.1.4.1.1466.115.121.1.12 )
2372 +
2373 +( 2.16.840.1.113719.1.203.4.20 NAME 'dhcpVersion' DESC 'The version
2374 +attribute of this object.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-
2375 +VALUE )
2376 +
2377 +( 2.16.840.1.113719.1.203.4.21 NAME 'dhcpImplementation' DESC
2378 +'Description of the DHCP Server implementation e.g. DHCP Server's
2379 +vendor.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
2380 +
2381 +( 2.16.840.1.113719.1.203.4.22 NAME 'dhcpAddressState' DESC 'This stores
2382 +information about the current binding-status of an address.  For dynamic
2383 +addresses managed by DHCP, the values should be restricted to the
2384 +following: "FREE", "ACTIVE", "EXPIRED", "RELEASED", "RESET",
2385 +"ABANDONED", "BACKUP".  For other addresses, it SHOULD be one of the
2386 +following: "UNKNOWN", "RESERVED" (an address that is managed by DHCP
2387 +that is reserved for a specific client), "RESERVED-ACTIVE" (same as
2388 +reserved, but address is currently in use), "ASSIGNED" (assigned
2389 +manually or by some other mechanism), "UNASSIGNED", "NOTASSIGNABLE".'
2390 +SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
2391 +
2392 +( 2.16.840.1.113719.1.203.4.23 NAME 'dhcpExpirationTime' DESC 'This is
2393 +the time the current lease for an address expires.' SYNTAX
2394 +1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
2395 +
2396 +( 2.16.840.1.113719.1.203.4.24 NAME 'dhcpStartTimeOfState' DESC 'This is
2397 +the time of the last state change for a leased address.' SYNTAX
2398 +1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
2399 +
2400 +( 2.16.840.1.113719.1.203.4.25 NAME 'dhcpLastTransactionTime' DESC 'This
2401 +is the last time a valid DHCP packet was received from the client.'
2402 +SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
2403 +
2404 +( 2.16.840.1.113719.1.203.4.26 NAME 'dhcpBootpFlag' DESC 'This indicates
2405 +whether the address was assigned via BOOTP.' SYNTAX
2406 +1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
2407 +
2408 +( 2.16.840.1.113719.1.203.4.27 NAME 'dhcpDomainName' DESC 'This is the
2409 +name of the domain sent to the client by the server.  It is essentially
2410 +the same as the value for DHCP option 15 sent to the client, and
2411 +represents only the domain - not the full FQDN.  To obtain the full FQDN
2412 +assigned to the client you must prepend the "dhcpAssignedHostName" to
2413 +this value with a ".".' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-
2414 +VALUE )
2415 +
2416 +( 2.16.840.1.113719.1.203.4.28 NAME 'dhcpDnsStatus' DESC 'This indicates
2417 +the status of updating DNS resource records on behalf of the client by
2418 +
2419 +
2420 +
2421 +M. Meredith et al.        Expires December 2001                [Page 12]
2422 +
2423 +
2424 +
2425 +
2426 +
2427 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
2428 +
2429 +
2430 +the DHCP server for this address.  The value is a 16-bit bitmask.'
2431 +SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
2432 +
2433 +( 2.16.840.1.113719.1.203.4.29 NAME 'dhcpRequestedHostName' DESC 'This
2434 +is the hostname that was requested by the client.' SYNTAX
2435 +1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
2436 +
2437 +( 2.16.840.1.113719.1.203.4.30 NAME 'dhcpAssignedHostName' DESC 'This is
2438 +the actual hostname that was assigned to a client. It may not be the
2439 +name that was requested by the client.  The fully qualified domain name
2440 +can be determined by appending the value of "dhcpDomainName" (with a dot
2441 +separator) to this name.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-
2442 +VALUE )
2443 +
2444 +( 2.16.840.1.113719.1.203.4.31 NAME 'dhcpReservedForClient' DESC 'The
2445 +distinguished name of a "dhcpClient" that an address is reserved for.
2446 +This may not be the same as the "dhcpAssignedToClient" attribute if the
2447 +address is being reassigned but the current lease has not yet expired.'
2448 +SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
2449 +
2450 +( 2.16.840.1.113719.1.203.4.32 NAME 'dhcpAssignedToClient' DESC 'This is
2451 +the distinguished name of a "dhcpClient" that an address is currently
2452 +assigned to.  This attribute is only present in the class when the
2453 +address is leased.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
2454 +
2455 +( 2.16.840.1.113719.1.203.4.33 NAME 'dhcpRelayAgentInfo' DESC 'If the
2456 +client request was received via a relay agent, this contains information
2457 +about the relay agent that was available from the DHCP request.  This is
2458 +a hex-encoded option value.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
2459 +SINGLE-VALUE )
2460 +
2461 +( 2.16.840.1.113719.1.203.4.34 NAME 'dhcpHWAddress' DESC 'The clients
2462 +hardware address that requested this IP address.' SYNTAX
2463 +1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
2464 +
2465 +( 2.16.840.1.113719.1.203.4.35 NAME 'dhcpHashBucketAssignment' DESC
2466 +'HashBucketAssignment bit map for the DHCP Server, as defined in DHC
2467 +Load Balancing Algorithm [RFC 3074].' SYNTAX
2468 +1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
2469 +
2470 +( 2.16.840.1.113719.1.203.4.36 NAME 'dhcpDelayedServiceParameter' DESC
2471 +'Delay in seconds corresponding to Delayed Service Parameter
2472 +configuration, as defined in  DHC Load Balancing Algorithm [RFC 3074]. '
2473 +SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
2474 +
2475 +( 2.16.840.1.113719.1.203.4.37 NAME 'dhcpMaxClientLeadTime' DESC
2476 +'Maximum Client Lead Time configuration in seconds, as defined in DHCP
2477 +Failover Protocol [FAILOVR]' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
2478 +
2479 +
2480 +
2481 +M. Meredith et al.        Expires December 2001                [Page 13]
2482 +
2483 +
2484 +
2485 +
2486 +
2487 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
2488 +
2489 +
2490 +SINGLE-VALUE )
2491 +
2492 +( 2.16.840.1.113719.1.203.4.38 NAME 'dhcpFailOverEndpointState' DESC
2493 +'Server (Failover Endpoint) state, as defined in DHCP Failover Protocol
2494 +[FAILOVR]' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
2495 +
2496 +( 2.16.840.1.113719.1.203.4.39 NAME 'dhcpErrorLog' DESC
2497 +Generic error log attribute that allows logging error conditions within a 
2498 +dhcpService or a dhcpSubnet, like no IP addresses available for lease. 
2499 +SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
2500 +
2501 +#Classes
2502 +
2503 +( 2.16.840.1.113719.1.203.6.1 NAME 'dhcpService' DESC ' Service object
2504 +that represents the actual DHCP Service configuration. This is a
2505 +container object.' SUP top MUST (cn $ dhcpPrimaryDN) MAY
2506 +(dhcpSecondaryDN $ dhcpSharedNetworkDN $ dhcpSubnetDN $ dhcpGroupDN $
2507 +dhcpHostDN $  dhcpClassesDN $ dhcpOptionsDN $ dhcpStatements ) )
2508 +
2509 +( 2.16.840.1.113719.1.203.6.2 NAME 'dhcpSharedNetwork' DESC 'This stores
2510 +configuration information for a shared network.' SUP top MUST  cn MAY
2511 +(dhcpSubnetDN $ dhcpPoolDN $ dhcpOptionsDN $ dhcpStatements) X-
2512 +NDS_CONTAINMENT ('dhcpService' ) )
2513 +
2514 +( 2.16.840.1.113719.1.203.6.3 NAME 'dhcpSubnet' DESC 'This class defines
2515 +a subnet. This is a container object.' SUP top MUST ( cn $ dhcpNetMask )
2516 +MAY (dhcpRange $ dhcpPoolDN $ dhcpGroupDN $ dhcpHostDN $ dhcpClassesDN $
2517 +dhcpLeasesDN $ dhcpOptionsDN $ dhcpStatements) X-NDS_CONTAINMENT
2518 +('dhcpService' 'dhcpSharedNetwork') )
2519 +
2520 +( 2.16.840.1.113719.1.203.6.4 NAME 'dhcpPool' DESC 'This stores
2521 +configuration information about a pool.' SUP top MUST ( cn $ dhcpRange )
2522 +MAY (dhcpClassesDN $ dhcpPermitList $ dhcpLeasesDN $ dhcpOptionsDN $
2523 +dhcpStatements) X-NDS_CONTAINMENT ('dhcpSubnet' 'dhcpSharedNetwork') )
2524 +
2525 +( 2.16.840.1.113719.1.203.6.5 NAME 'dhcpGroup' DESC 'Group object that
2526 +lists host DNs and parameters. This is a container object.' SUP top MUST
2527 +cn MAY ( dhcpHostDN $ dhcpOptionsDN $ dhcpStatements ) X-NDS_CONTAINMENT
2528 +('dhcpSubnet' 'dhcpService' ) )
2529 +
2530 +( 2.16.840.1.113719.1.203.6.6 NAME 'dhcpHost' DESC 'This represents
2531 +information about a particular client' SUP top MUST cn MAY  (dhcpLeaseDN
2532 +$ dhcpHWAddress $ dhcpOptionsDN $ dhcpStatements) X-NDS_CONTAINMENT
2533 +('dhcpService' 'dhcpSubnet' 'dhcpGroup') )
2534 +
2535 +( 2.16.840.1.113719.1.203.6.7 NAME 'dhcpClass' DESC 'Represents
2536 +information about a collection of related clients.' SUP top MUST cn MAY
2537 +(dhcpSubClassesDN $ dhcpOptionsDN $ dhcpStatements) X-NDS_CONTAINMENT
2538 +('dhcpService' 'dhcpSubnet' ) )
2539 +
2540 +( 2.16.840.1.113719.1.203.6.8 NAME 'dhcpSubClass' DESC 'Represents
2541 +information about a collection of related classes.' SUP top MUST cn MAY
2542 +(dhcpClassData $ dhcpOptionsDN $ dhcpStatements) X-NDS_CONTAINMENT
2543 +
2544 +
2545 +
2546 +M. Meredith et al.        Expires December 2001                [Page 14]
2547 +
2548 +
2549 +
2550 +
2551 +
2552 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
2553 +
2554 +
2555 +'dhcpClass' )
2556 +
2557 +( 2.16.840.1.113719.1.203.6.9 NAME 'dhcpOptions' DESC 'Represents
2558 +information about a collection of options defined.' SUP top MUST cn MAY
2559 +( dhcpOption ) X-NDS_CONTAINMENT  ('dhcpService' 'dhcpSharedNetwork'
2560 +'dhcpSubnet' 'dhcpPool' 'dhcpGroup' 'dhcpHost' 'dhcpClass' )
2561 +
2562 +( 2.16.840.1.113719.1.203.6.10 NAME 'dhcpLeases' DESC 'This class
2563 +represents an IP Address, which may or may not have been leased.' SUP
2564 +top MUST ( cn $ dhcpAddressState ) MAY ( dhcpExpirationTime $
2565 +dhcpStartTimeOfState $ dhcpLastTransactionTime $ dhcpBootpFlag $
2566 +dhcpDomainName $ dhcpDnsStatus $ dhcpRequestedHostName $
2567 +dhcpAssignedHostName $ dhcpReservedForClient $ dhcpAssignedToClient $
2568 +dhcpRelayAgentInfo $ dhcpHWAddress ) X-NDS_CONTAINMENT ( 'dhcpService'
2569 +'dhcpSubnet' 'dhcpPool') )
2570 +
2571 +( 2.16.840.1.113719.1.203.6.11 NAME 'dhcpLog' DESC 'This is the object
2572 +that holds past information about the IP address. The cn is the
2573 +time/date stamp when the address was assigned or released, the address
2574 +state at the time, if the address was assigned or released.' SUP top
2575 +MUST ( cn ) MAY ( dhcpAddressState $ dhcpExpirationTime $
2576 +dhcpStartTimeOfState $ dhcpLastTransactionTime $ dhcpBootpFlag $
2577 +dhcpDomainName $ dhcpDnsStatus $ dhcpRequestedHostName $
2578 +dhcpAssignedHostName $ dhcpReservedForClient $ dhcpAssignedToClient $
2579 +dhcpRelayAgentInfo $ dhcpHWAddress $ dhcpErrorLog) X-NDS_CONTAINMENT 
2580 +('dhcpLeases' 'dhcpPool' 'dhcpSubnet' 'dhcpSharedNetwork' 'dhcpService' ) )
2581 +
2582 +( 2.16.840.1.113719.1.203.6.12 NAME 'dhcpServer' DESC 'DHCP Server
2583 +Object' SUP top MUST (cn, dhcpServiceDN) MAY (dhcpVersion $
2584 +dhcpImplementation $ dhcpHashBucketAssignment $
2585 +dhcpDelayedServiceParameter $ dhcpMaxClientLeadTime $
2586 +dhcpFailOverEndpointState $ dhcpStatements) X-NDS_CONTAINMENT ('O' 'OU' 
2587 +'dc') )
2588 +
2589 +9. Security Considerations
2590 +
2591 +Since the DHCP Configuration information is stored in a directory, the
2592 +security of the information is limited to the security offered by the
2593 +directory including the security of the objects within that directory.
2594 +
2595 +10.  Intellectual Property Rights Notices
2596 +
2597 +The IETF takes no position regarding the validity or scope of any
2598 +intellectual property or other rights that might be claimed to pertain
2599 +to the implementation or use of the technology described in this
2600 +document or the extent to which any license under such rights might or
2601 +might not be available; neither does it represent that it has made any
2602 +effort to identify any such rights.  Information on the IETF's
2603 +procedures with respect to rights in standards-track and standards-
2604 +
2605 +
2606 +
2607 +M. Meredith et al.        Expires December 2001                [Page 15]
2608 +
2609 +
2610 +
2611 +
2612 +
2613 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
2614 +
2615 +
2616 +related documentation can be found in BCP-11.  Copies of claims of
2617 +rights made available for publication and any assurances of licenses to
2618 +be made available, or the result of an attempt made to obtain a general
2619 +license or permission for the use of such proprietary rights by
2620 +implementors or users of this specification can be obtained from the
2621 +IETF Secretariat.
2622 +
2623 +The IETF invites any interested party to bring to its attention any
2624 +copyrights, patents or patent applications, or other proprietary rights
2625 +which may cover technology that may be required to practice this
2626 +standard.  Please address the information to the IETF Executive
2627 +Director.
2628 +
2629 +11.  Full Copyright Statement
2630 +
2631 +Copyright (C) The Internet Society (2001).  All Rights Reserved.
2632 +
2633 +This document and translations of it may be copied and furnished to
2634 +others, and derivative works that comment on or otherwise explain it or
2635 +assist in its implementation may be prepared, copied, published and
2636 +distributed, in whole or in part, without restriction of any kind,
2637 +provided that the above copyright notice and this paragraph are included
2638 +on all such copies and derivative works.  However, this document itself
2639 +may not be modified in any way, such as by removing the copyright notice
2640 +or references to the Internet Society or other Internet organizations,
2641 +except as needed for the purpose of developing Internet standards in
2642 +which case the procedures for copyrights defined in the Internet
2643 +Standards process must be followed, or as required to translate it into
2644 +languages other than English.
2645 +
2646 +The limited permissions granted above are perpetual and will not be
2647 +revoked by the Internet Society or its successors or assigns.
2648 +
2649 +This document and the information contained herein is provided on an "AS
2650 +IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK
2651 +FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
2652 +LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT
2653 +INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR
2654 +FITNESS FOR A PARTICULAR PURPOSE.
2655 +
2656 +12. References
2657 +
2658 +[RFC2131] Droms, R., "Dynamic Host Configuration Protocol", RFC 2131,
2659 +March 1997.
2660 +
2661 +[RFC2132] Alexander, S., Droms, R., "DHCP Options and BOOTP Vendor
2662 +Extensions", RFC 2132, March 1997.
2663 +
2664 +
2665 +
2666 +
2667 +M. Meredith et al.        Expires December 2001                [Page 16]
2668 +
2669 +
2670 +
2671 +
2672 +
2673 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
2674 +
2675 +
2676 +[MSDHCP]  Gu, Y., Vyaghrapuri, R., "An LDAP Schema for Dynamic Host
2677 +Configuration Protocol Service", Internet Draft <draft-gu-dhcp-ldap-
2678 +schema-00.txt>, August 1998.
2679 +
2680 +[NOVDHCP] Miller, T., Patel, A., Rao, P., "Lightweight Directory Access
2681 +Protocol (v3): Schema for Dynamic Host Configuration Protocol (DHCP)",
2682 +Internet Draft <draft-miller-dhcp-ldap-schema-00.txt>, June 1998.
2683 +
2684 +[FAILOVR] Droms, R., Rabil, G., Dooley, M., Kapur, A., Gonczi, S., Volz,
2685 +B., "DHCP Failover Protocol", Internet Draft <draft-ietf-dhc-
2686 +failover-08.txt>, July 2000.
2687 +
2688 +[RFC 3074] Volz B., Gonczi S., Lemon T., Stevens R., "DHC Load Balancing
2689 +Algorithm", February 2001
2690 +
2691 +[AGENT]   Patrick, M., "DHCP Relay Agent Information Option", Internet
2692 +Draft <draft-ietf-dhc-agent-options-09.txt>, March 2000.
2693 +
2694 +[DHCPOPT] Carney, M., "New Option Review Guidelines and Additional
2695 +Option Namespace", Internet Draft <draft-ietf-dhc-
2696 +option_review_and_namespace-01.txt>, October 1999.
2697 +
2698 +[POLICY]  Strassner, J., Elleson, E., Moore, B., "Policy Framework LDAP
2699 +Core Schema", Internet Draft <draft-ietf-policy-core-schema-06.txt>,
2700 +November 1999.
2701 +
2702 +[RFC2251] Wahl, M., Howes, T., Kille, S., "Lightweight Directory Access
2703 +Protocol (v3)", RFC 2251, December 1997.
2704 +
2705 +[RFC2252] Wahl, M., Coulbeck, A., Howes, T., Kille, S., "Lightweight
2706 +Directory Access Protocol (v3) Attribute Syntax Definitions", RFC 2252,
2707 +December 1997.
2708 +
2709 +[RFC2255] Howes, T., Smith, M., "The LDAP URL Format", RFC 2255,
2710 +December 1997.
2711 +
2712 +[RFC951]  Croft, B., Gilmore, J., "Bootstrap Protocol (BOOTP)", RFC 951,
2713 +September 1985.
2714 +
2715 +[RFC2119] Bradner, S. "Key words for use in RFCs to Indicate Requirement
2716 +Levels", RFC 2119, March 1997.
2717 +
2718 +13. Acknowledgments
2719 +
2720 +This work is partially based on a previous draft draft-ietf-dhc-
2721 +schema-02.doc.
2722 +
2723 +
2724 +
2725 +
2726 +
2727 +M. Meredith et al.        Expires December 2001                [Page 17]
2728 +
2729 +
2730 +
2731 +
2732 +
2733 +INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
2734 +
2735 +
2736 +14. Author's Addresses
2737 +
2738 +Comments regarding this draft may be sent to the authors at the
2739 +following address:
2740 +
2741 +Mark Meredith
2742 +Mark Hinckley
2743 +Novell Inc.
2744 +1800 S. Novell Place
2745 +Provo, Utah 84606
2746 +
2747 +Vijay K. Nanjundaswamy
2748 +Novell Software Development (I) Ltd
2749 +49/1 & 49/3, Garvebhavi Palya,
2750 +7th Mile, Hosur Road
2751 +Bangalore 560068
2752 +
2753 +email: mark_meredith@novell.com
2754 +email: knvijay@novell.com
2755 +email: mhinckley@novell.com
2756 +
2757 +This Internet Draft expires December 16, 2001.
2758 +
2759 +
2760 +
2761 +
2762 +
2763 +
2764 +
2765 +
2766 +
2767 +
2768 +
2769 +
2770 +
2771 +
2772 +
2773 +
2774 +
2775 +
2776 +
2777 +
2778 +
2779 +
2780 +
2781 +
2782 +
2783 +
2784 +
2785 +
2786 +
2787 +M. Meredith et al.        Expires December 2001                [Page 18]
2788 +
2789 +
2790 +
2791 +
2792 diff -Naur dhcp-3.0.1rc14/includes/dhcpd.h dhcp-3.0.1rc14-ldap/includes/dhcpd.h
2793 --- dhcp-3.0.1rc14/includes/dhcpd.h     2004-06-10 13:59:29.000000000 -0400
2794 +++ dhcp-3.0.1rc14-ldap/includes/dhcpd.h        2004-06-22 15:18:20.000000000 -0400
2795 @@ -79,6 +79,11 @@
2796  #include <isc-dhcp/result.h>
2797  #include <omapip/omapip_p.h>
2798  
2799 +#if defined(LDAP_CONFIGURATION)
2800 +# include <ldap.h>
2801 +# include <sys/utsname.h> /* for uname() */
2802 +#endif
2803 +
2804  #if !defined (OPTION_HASH_SIZE)
2805  # define OPTION_HASH_SIZE 17
2806  # define OPTION_HASH_PTWO 32   /* Next power of two above option hash. */
2807 @@ -139,6 +144,8 @@
2808         char *inbuf;
2809         unsigned bufix, buflen;
2810         unsigned bufsiz;
2811 +
2812 +       char (*read_function) (struct parse *);
2813  };
2814  
2815  /* Variable-length array of data. */
2816 @@ -241,6 +248,26 @@
2817         u_int8_t hbuf [17];
2818  };
2819  
2820 +#if defined(LDAP_CONFIGURATION)
2821 +# define LDAP_BUFFER_SIZE              8192
2822 +# define LDAP_METHOD_STATIC            0
2823 +# define LDAP_METHOD_DYNAMIC           1
2824 +
2825 +/* This is a tree of the current configuration we are building from LDAP */
2826 +
2827 +struct ldap_config_stack {
2828 +       LDAPMessage * res;      /* Pointer returned from ldap_search */
2829 +       LDAPMessage * ldent;    /* Current item in LDAP that we're processing 
2830 +                                  in res */
2831 +       int close_brace;        /* Put a closing } after we're through with
2832 +                                  this item */
2833 +       int processed;          /* We set this flag if this base item has been
2834 +                                  processed. After this base item is processed,
2835 +                                  we can start processing the children */
2836 +       struct ldap_config_stack *next;
2837 +};
2838 +#endif
2839 +
2840  typedef enum {
2841         server_startup = 0,
2842         server_running = 1,
2843 @@ -417,6 +444,16 @@
2844  # define DEFAULT_PING_TIMEOUT 1
2845  #endif
2846  
2847 +#if defined(LDAP_CONFIGURATION)
2848 +# define SV_LDAP_SERVER                47
2849 +# define SV_LDAP_PORT                          48
2850 +# define SV_LDAP_USERNAME              49
2851 +# define SV_LDAP_PASSWORD              50
2852 +# define SV_LDAP_BASE_DN               51
2853 +# define SV_LDAP_METHOD                        52
2854 +# define SV_LDAP_DEBUG_FILE            53
2855 +#endif
2856 +
2857  #if !defined (DEFAULT_DEFAULT_LEASE_TIME)
2858  # define DEFAULT_DEFAULT_LEASE_TIME 43200
2859  #endif
2860 @@ -1520,7 +1557,7 @@
2861  char *quotify_string (const char *, const char *, int);
2862  char *quotify_buf (const unsigned char *, unsigned, const char *, int);
2863  char *print_base64 (const unsigned char *, unsigned, const char *, int);
2864 -char *print_hw_addr PROTO ((int, int, unsigned char *));
2865 +char *print_hw_addr PROTO ((const int, const int, const unsigned char *));
2866  void print_lease PROTO ((struct lease *));
2867  void dump_raw PROTO ((const unsigned char *, unsigned));
2868  void dump_packet_option (struct option_cache *, struct packet *,
2869 @@ -2622,3 +2659,14 @@
2870  #endif /* FAILOVER_PROTOCOL */
2871  
2872  const char *binding_state_print (enum failover_state);
2873 +
2874 +/* ldap.c */
2875 +#if defined(LDAP_CONFIGURATION)
2876 +extern struct enumeration ldap_methods;
2877 +isc_result_t ldap_read_config (void);
2878 +int find_haddr_in_ldap (struct host_decl **, int, unsigned,
2879 +                        const unsigned char *, const char *, int);
2880 +int find_subclass_in_ldap (struct class *, struct class **, 
2881 +                          struct data_string *);
2882 +#endif
2883 +
2884 diff -Naur dhcp-3.0.1rc14/includes/site.h dhcp-3.0.1rc14-ldap/includes/site.h
2885 --- dhcp-3.0.1rc14/includes/site.h      2002-03-12 13:33:39.000000000 -0500
2886 +++ dhcp-3.0.1rc14-ldap/includes/site.h 2004-06-22 15:18:20.000000000 -0400
2887 @@ -177,3 +177,13 @@
2888     traces. */
2889  
2890  #define TRACING
2891 +
2892 +/* Define this if you want to read your config from LDAP. Read README.ldap
2893 +   about how to set this up */
2894 +
2895 +#define LDAP_CONFIGURATION
2896 +
2897 +/* Define this if you want to enable LDAP over a SSL connection. You will need
2898 +   to add -lcrypto -lssl to the LIBS= line of server/Makefile */
2899 +
2900 +/* #define USE_SSL */
2901 diff -Naur dhcp-3.0.1rc14/server/Makefile.dist dhcp-3.0.1rc14-ldap/server/Makefile.dist
2902 --- dhcp-3.0.1rc14/server/Makefile.dist 2004-06-10 13:59:50.000000000 -0400
2903 +++ dhcp-3.0.1rc14-ldap/server/Makefile.dist    2004-06-22 15:18:20.000000000 -0400
2904 @@ -25,9 +25,9 @@
2905  CATMANPAGES = dhcpd.cat8 dhcpd.conf.cat5 dhcpd.leases.cat5
2906  SEDMANPAGES = dhcpd.man8 dhcpd.conf.man5 dhcpd.leases.man5
2907  SRCS   = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \
2908 -        omapi.c mdb.c stables.c salloc.c ddns.c
2909 +        ldap.c omapi.c mdb.c stables.c salloc.c ddns.c
2910  OBJS   = dhcpd.o dhcp.o bootp.o confpars.o db.o class.o failover.o \
2911 -        omapi.o mdb.o stables.o salloc.o ddns.o
2912 +        ldap.o omapi.o mdb.o stables.o salloc.o ddns.o
2913  PROG   = dhcpd
2914  MAN    = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5
2915  
2916 diff -Naur dhcp-3.0.1rc14/server/class.c dhcp-3.0.1rc14-ldap/server/class.c
2917 --- dhcp-3.0.1rc14/server/class.c       2004-06-10 13:59:51.000000000 -0400
2918 +++ dhcp-3.0.1rc14-ldap/server/class.c  2004-06-22 15:18:20.000000000 -0400
2919 @@ -90,6 +90,7 @@
2920         int matched = 0;
2921         int status;
2922         int ignorep;
2923 +       int classfound;
2924  
2925         for (class = collection -> classes; class; class = class -> nic) {
2926  #if defined (DEBUG_CLASS_MATCHING)
2927 @@ -135,9 +136,19 @@
2928                                    class -> submatch, MDL));
2929                         if (status && data.len) {
2930                                 nc = (struct class *)0;
2931 -                               if (class_hash_lookup (&nc, class -> hash,
2932 -                                                      (const char *)data.data,
2933 -                                                      data.len, MDL)) {
2934 +                                classfound = class_hash_lookup (&nc, 
2935 +                                               class -> hash, 
2936 +                                               (const char *)data.data,
2937 +                                               data.len, MDL);
2938 +
2939 +#ifdef LDAP_CONFIGURATION
2940 +                                if (!classfound && 
2941 +                                               find_subclass_in_ldap (class, 
2942 +                                                               &nc, &data)) 
2943 +                                       classfound = 1;
2944 +#endif
2945 +
2946 +                               if (classfound) {
2947  #if defined (DEBUG_CLASS_MATCHING)
2948                                         log_info ("matches subclass %s.",
2949                                               print_hex_1 (data.len,
2950 diff -Naur dhcp-3.0.1rc14/server/confpars.c dhcp-3.0.1rc14-ldap/server/confpars.c
2951 --- dhcp-3.0.1rc14/server/confpars.c    2004-06-10 13:59:51.000000000 -0400
2952 +++ dhcp-3.0.1rc14-ldap/server/confpars.c       2004-06-22 15:18:20.000000000 -0400
2953 @@ -62,7 +62,17 @@
2954  
2955  isc_result_t readconf ()
2956  {
2957 -       return read_conf_file (path_dhcpd_conf, root_group, ROOT_GROUP, 0);
2958 +       isc_result_t res;
2959 +
2960 +       res = read_conf_file (path_dhcpd_conf, root_group, ROOT_GROUP, 0);
2961 +#if defined(LDAP_CONFIGURATION)
2962 +       if (res != ISC_R_SUCCESS)
2963 +               return (res);
2964 +
2965 +       return ldap_read_config ();
2966 +#else
2967 +       return (res);
2968 +#endif
2969  }
2970  
2971  isc_result_t read_conf_file (const char *filename, struct group *group,
2972 diff -Naur dhcp-3.0.1rc14/server/dhcpd.c dhcp-3.0.1rc14-ldap/server/dhcpd.c
2973 --- dhcp-3.0.1rc14/server/dhcpd.c       2004-06-10 13:59:52.000000000 -0400
2974 +++ dhcp-3.0.1rc14-ldap/server/dhcpd.c  2004-06-22 15:18:20.000000000 -0400
2975 @@ -434,6 +434,9 @@
2976         /* Add the ddns update style enumeration prior to parsing. */
2977         add_enumeration (&ddns_styles);
2978         add_enumeration (&syslog_enum);
2979 +#if defined (LDAP_CONFIGURATION)
2980 +       add_enumeration (&ldap_methods);
2981 +#endif
2982  
2983         if (!group_allocate (&root_group, MDL))
2984                 log_fatal ("Can't allocate root group!");
2985 diff -Naur dhcp-3.0.1rc14/server/ldap.c dhcp-3.0.1rc14-ldap/server/ldap.c
2986 --- dhcp-3.0.1rc14/server/ldap.c        1969-12-31 19:00:00.000000000 -0500
2987 +++ dhcp-3.0.1rc14-ldap/server/ldap.c   2004-06-22 15:18:20.000000000 -0400
2988 @@ -0,0 +1,1479 @@
2989 +/* ldap.c
2990 +
2991 +   Routines for reading the configuration from LDAP */
2992 +
2993 +/*
2994 + * Copyright (c) 2003-2004 Ntelos, Inc.
2995 + * All rights reserved.
2996 + *
2997 + * Redistribution and use in source and binary forms, with or without
2998 + * modification, are permitted provided that the following conditions
2999 + * are met:
3000 + *
3001 + * 1. Redistributions of source code must retain the above copyright
3002 + *    notice, this list of conditions and the following disclaimer.
3003 + * 2. Redistributions in binary form must reproduce the above copyright
3004 + *    notice, this list of conditions and the following disclaimer in the
3005 + *    documentation and/or other materials provided with the distribution.
3006 + * 3. Neither the name of The Internet Software Consortium nor the names
3007 + *    of its contributors may be used to endorse or promote products derived
3008 + *    from this software without specific prior written permission.
3009 + *
3010 + * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
3011 + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
3012 + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
3013 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3014 + * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
3015 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3016 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3017 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
3018 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3019 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3020 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
3021 + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3022 + * SUCH DAMAGE.
3023 + *
3024 + * This LDAP module was written by Brian Masney <masneyb@ntelos.net>. It's
3025 + * development was sponsored by Ntelos, Inc. (www.ntelos.com).
3026 + */
3027 +
3028 +#include "dhcpd.h"
3029 +
3030 +#if defined(LDAP_CONFIGURATION)
3031 +
3032 +static LDAP * ld = NULL;
3033 +static char *ldap_server = NULL, 
3034 +            *ldap_username = NULL, 
3035 +            *ldap_password = NULL,
3036 +            *ldap_base_dn = NULL,
3037 +            *ldap_debug_file = NULL;
3038 +static int ldap_port = LDAP_PORT,
3039 +           ldap_method = LDAP_METHOD_DYNAMIC,
3040 +           ldap_debug_fd = -1;
3041 +static struct ldap_config_stack *ldap_stack = NULL;
3042 +
3043 +typedef struct ldap_dn_node {
3044 +    struct ldap_dn_node *next;
3045 +    size_t refs;
3046 +    char *dn;
3047 +} ldap_dn_node;
3048 +
3049 +static ldap_dn_node *ldap_service_dn_head = NULL;
3050 +static ldap_dn_node *ldap_service_dn_tail = NULL;
3051 +
3052 +
3053 +static void
3054 +ldap_parse_class (struct ldap_config_stack *item, struct parse *cfile)
3055 +{
3056 +  char **tempstr;
3057 +
3058 +  if ((tempstr = ldap_get_values (ld, item->ldent, "cn")) == NULL ||
3059 +      tempstr[0] == NULL)
3060 +    {
3061 +      if (tempstr != NULL)
3062 +        ldap_value_free (tempstr);
3063 +
3064 +      return;
3065 +    }
3066 +
3067 +  strncat (cfile->inbuf, "class \"", LDAP_BUFFER_SIZE);
3068 +  strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
3069 +  strncat (cfile->inbuf, "\" {\n", LDAP_BUFFER_SIZE);
3070 +
3071 +  item->close_brace = 1;
3072 +  ldap_value_free (tempstr);
3073 +}
3074 +
3075 +
3076 +static void
3077 +ldap_parse_subclass (struct ldap_config_stack *item, struct parse *cfile)
3078 +{
3079 +  char **tempstr, **classdata;
3080 +
3081 +  if ((tempstr = ldap_get_values (ld, item->ldent, "cn")) == NULL ||
3082 +      tempstr[0] == NULL)
3083 +    {
3084 +      if (tempstr != NULL)
3085 +        ldap_value_free (tempstr);
3086 +
3087 +      return;
3088 +    }
3089 +
3090 +  if ((classdata = ldap_get_values (ld, item->ldent, 
3091 +                                  "dhcpClassData")) == NULL || 
3092 +      classdata[0] == NULL)
3093 +    {
3094 +      if (classdata != NULL)
3095 +        ldap_value_free (classdata);
3096 +      ldap_value_free (tempstr);
3097 +
3098 +      return;
3099 +    }
3100 +
3101 +  strncat (cfile->inbuf, "subclass ", LDAP_BUFFER_SIZE);
3102 +  strncat (cfile->inbuf, classdata[0], LDAP_BUFFER_SIZE);
3103 +  strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
3104 +  strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
3105 +  strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
3106 +
3107 +  item->close_brace = 1;
3108 +  ldap_value_free (tempstr);
3109 +  ldap_value_free (classdata);
3110 +}
3111 +
3112 +
3113 +static void
3114 +ldap_parse_host (struct ldap_config_stack *item, struct parse *cfile)
3115 +{
3116 +  char **tempstr, **hwaddr;
3117 +
3118 +  if ((tempstr = ldap_get_values (ld, item->ldent, "cn")) == NULL ||
3119 +      tempstr[0] == NULL)
3120 +    {
3121 +      if (tempstr != NULL)
3122 +        ldap_value_free (tempstr);
3123 +
3124 +      return;
3125 +    }
3126 +
3127 +  if ((hwaddr = ldap_get_values (ld, item->ldent, 
3128 +                                 "dhcpHWAddress")) == NULL || 
3129 +      hwaddr[0] == NULL)
3130 +    {
3131 +      if (hwaddr != NULL)
3132 +        ldap_value_free (hwaddr);
3133 +
3134 +      ldap_value_free (tempstr);
3135 +      return;
3136 +    }
3137 +
3138 +  strncat (cfile->inbuf, "host ", LDAP_BUFFER_SIZE);
3139 +  strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
3140 +  strncat (cfile->inbuf, " {\nhardware ", LDAP_BUFFER_SIZE);
3141 +  strncat (cfile->inbuf, hwaddr[0], LDAP_BUFFER_SIZE);
3142 +  strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
3143 +
3144 +  item->close_brace = 1;
3145 +  ldap_value_free (tempstr);
3146 +  ldap_value_free (hwaddr);
3147 +}
3148 +
3149 +
3150 +static void
3151 +ldap_parse_shared_network (struct ldap_config_stack *item, struct parse *cfile)
3152 +{
3153 +  char **tempstr;
3154 +
3155 +
3156 +  if ((tempstr = ldap_get_values (ld, item->ldent, "cn")) == NULL ||
3157 +      tempstr[0] == NULL)
3158 +    {
3159 +      if (tempstr != NULL)
3160 +        ldap_value_free (tempstr);
3161 +
3162 +      return;
3163 +    }
3164 +
3165 +  strncat (cfile->inbuf, "shared-network \"", LDAP_BUFFER_SIZE);
3166 +  strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
3167 +  strncat (cfile->inbuf, "\" {\n", LDAP_BUFFER_SIZE);
3168 +
3169 +  item->close_brace = 1;
3170 +  ldap_value_free (tempstr);
3171 +}
3172 +
3173 +
3174 +static void
3175 +parse_netmask (int netmask, char *netmaskbuf)
3176 +{
3177 +  unsigned long nm;
3178 +  int i;
3179 +
3180 +  nm = 0;
3181 +  for (i=1; i <= netmask; i++)
3182 +    {
3183 +      nm |= 1 << (32 - i);
3184 +    }
3185 +
3186 +  sprintf (netmaskbuf, "%d.%d.%d.%d", (int) (nm >> 24) & 0xff, 
3187 +                                      (int) (nm >> 16) & 0xff, 
3188 +                                      (int) (nm >> 8) & 0xff, 
3189 +                                      (int) nm & 0xff);
3190 +}
3191 +
3192 +static void
3193 +ldap_parse_subnet (struct ldap_config_stack *item, struct parse *cfile)
3194 +{
3195 +  char **tempstr, **netmaskstr, netmaskbuf[16];
3196 +  int i;
3197 +
3198 +  if ((tempstr = ldap_get_values (ld, item->ldent, "cn")) == NULL ||
3199 +      tempstr[0] == NULL)
3200 +    {
3201 +      if (tempstr != NULL)
3202 +        ldap_value_free (tempstr);
3203 +
3204 +      return;
3205 +    }
3206 +
3207 +  if ((netmaskstr = ldap_get_values (ld, item->ldent, 
3208 +                                     "dhcpNetmask")) == NULL || 
3209 +      netmaskstr[0] == NULL)
3210 +    {
3211 +      if (netmaskstr != NULL)
3212 +        ldap_value_free (netmaskstr);
3213 +      ldap_value_free (tempstr);
3214 +
3215 +      return;
3216 +    }
3217 +
3218 +  strncat (cfile->inbuf, "subnet ", LDAP_BUFFER_SIZE);
3219 +  strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
3220 +
3221 +  strncat (cfile->inbuf, " netmask ", LDAP_BUFFER_SIZE);
3222 +  parse_netmask (strtol (netmaskstr[0], NULL, 10), netmaskbuf);
3223 +  strncat (cfile->inbuf, netmaskbuf, LDAP_BUFFER_SIZE);
3224 +
3225 +  strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
3226 +
3227 +  ldap_value_free (tempstr);
3228 +  ldap_value_free (netmaskstr);
3229 +
3230 +  if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpRange")) != NULL)
3231 +    {
3232 +      for (i=0; tempstr[i] != NULL; i++)
3233 +        {
3234 +          strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE);
3235 +          strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
3236 +          strncat (cfile->inbuf, tempstr[i], LDAP_BUFFER_SIZE);
3237 +          strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
3238 +        }
3239 +      ldap_value_free (tempstr);
3240 +    }
3241 +
3242 +  item->close_brace = 1;
3243 +}
3244 +
3245 +
3246 +static void
3247 +ldap_parse_pool (struct ldap_config_stack *item, struct parse *cfile)
3248 +{
3249 +  char **tempstr;
3250 +  int i;
3251 +
3252 +  strncat (cfile->inbuf, "pool {\n", LDAP_BUFFER_SIZE);
3253 +
3254 +  if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpRange")) != NULL)
3255 +    {
3256 +      strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE);
3257 +      for (i=0; tempstr[i] != NULL; i++)
3258 +        {
3259 +          strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
3260 +          strncat (cfile->inbuf, tempstr[i], LDAP_BUFFER_SIZE);
3261 +        }
3262 +      strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
3263 +      ldap_value_free (tempstr);
3264 +    }
3265 +
3266 +  if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpPermitList")) != NULL)
3267 +    {
3268 +      for (i=0; tempstr[i] != NULL; i++)
3269 +        {
3270 +          strncat (cfile->inbuf, tempstr[i], LDAP_BUFFER_SIZE);
3271 +          strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
3272 +        }
3273 +      ldap_value_free (tempstr);
3274 +    }
3275 +
3276 +  item->close_brace = 1;
3277 +}
3278 +
3279 +
3280 +static void
3281 +ldap_parse_group (struct ldap_config_stack *item, struct parse *cfile)
3282 +{
3283 +  strncat (cfile->inbuf, "group {\n", LDAP_BUFFER_SIZE);
3284 +  item->close_brace = 1;
3285 +}
3286 +
3287 +
3288 +static void
3289 +add_to_config_stack (LDAPMessage * res, LDAPMessage * ent)
3290 +{
3291 +  struct ldap_config_stack *ns;
3292 +
3293 +  ns = dmalloc (sizeof (*ns), MDL);
3294 +  ns->res = res;
3295 +  ns->ldent = ent;
3296 +  ns->close_brace = 0;
3297 +  ns->processed = 0;
3298 +  ns->next = ldap_stack;
3299 +  ldap_stack = ns;
3300 +}
3301 +
3302 +
3303 +static void
3304 +ldap_start (void)
3305 +{
3306 +  struct option_state *options;
3307 +  struct option_cache *oc;
3308 +  struct data_string db;
3309 +  int ret, version;
3310 +
3311 +  if (ld != NULL)
3312 +    return;
3313 +
3314 +  if (ldap_server == NULL)
3315 +    {
3316 +      options = NULL;
3317 +      option_state_allocate (&options, MDL);
3318 +
3319 +      execute_statements_in_scope ((struct binding_value **) NULL,
3320 +                 (struct packet *) NULL, (struct lease *) NULL,
3321 +                 (struct client_state *) NULL, (struct option_state *) NULL,
3322 +                 options, &global_scope, root_group, (struct group *) NULL);
3323 +
3324 +      memset (&db, 0, sizeof (db));
3325 +      oc = lookup_option (&server_universe, options, SV_LDAP_SERVER);
3326 +      if (oc &&
3327 +          evaluate_option_cache (&db,  (struct packet*) NULL,
3328 +                (struct lease *) NULL, (struct client_state *) NULL,
3329 +                options, (struct option_state *) NULL, &global_scope, oc, MDL))
3330 +        {
3331 +          ldap_server = dmalloc (db.len + 1, MDL);
3332 +          if (!ldap_server)
3333 +            log_fatal ("no memory for ldap server");
3334 +          memcpy (ldap_server, db.data, db.len);
3335 +          ldap_server[db.len] = 0;
3336 +          data_string_forget (&db, MDL);
3337 +        }
3338 +
3339 +      oc = lookup_option (&server_universe, options, SV_LDAP_USERNAME);
3340 +      if (oc &&
3341 +          evaluate_option_cache (&db,  (struct packet*) NULL,
3342 +                (struct lease *) NULL, (struct client_state *) NULL,
3343 +                options, (struct option_state *) NULL, &global_scope, oc, MDL))
3344 +        {
3345 +          ldap_username = dmalloc (db.len + 1, MDL);
3346 +          if (!ldap_username)
3347 +            log_fatal ("no memory for ldap username");
3348 +          memcpy (ldap_username, db.data, db.len);
3349 +          ldap_username[db.len] = 0;
3350 +          data_string_forget (&db, MDL);
3351 +        }
3352 +
3353 +      oc = lookup_option (&server_universe, options, SV_LDAP_PASSWORD);
3354 +      if (oc &&
3355 +          evaluate_option_cache (&db,  (struct packet*) NULL,
3356 +                (struct lease *) NULL, (struct client_state *) NULL,
3357 +                options, (struct option_state *) NULL, &global_scope, oc, MDL))
3358 +        {
3359 +          ldap_password = dmalloc (db.len + 1, MDL);
3360 +          if (!ldap_password)
3361 +            log_fatal ("no memory for ldap password");
3362 +          memcpy (ldap_password, db.data, db.len);
3363 +          ldap_password[db.len] = 0;
3364 +          data_string_forget (&db, MDL);
3365 +        }
3366 +
3367 +      oc = lookup_option (&server_universe, options, SV_LDAP_BASE_DN);
3368 +      if (oc &&
3369 +          evaluate_option_cache (&db,  (struct packet*) NULL,
3370 +                (struct lease *) NULL, (struct client_state *) NULL,
3371 +                options, (struct option_state *) NULL, &global_scope, oc, MDL))
3372 +        {
3373 +          ldap_base_dn = dmalloc (db.len + 1, MDL);
3374 +          if (!ldap_base_dn)
3375 +            log_fatal ("no memory for ldap base dn");
3376 +          memcpy (ldap_base_dn, db.data, db.len);
3377 +          ldap_base_dn[db.len] = 0;
3378 +          data_string_forget (&db, MDL);
3379 +        }
3380 +
3381 +      oc = lookup_option (&server_universe, options, SV_LDAP_METHOD);
3382 +      if (oc &&
3383 +          evaluate_option_cache (&db,  (struct packet*) NULL,
3384 +                (struct lease *) NULL, (struct client_state *) NULL,
3385 +                options, (struct option_state *) NULL, &global_scope, oc, MDL))
3386 +        {
3387 +
3388 +          if (db.len == 1) 
3389 +            ldap_method = db.data [0];
3390 +          else
3391 +            log_fatal ("invalid ldap method type");
3392 +          data_string_forget (&db, MDL);
3393 +        }
3394 +
3395 +      oc = lookup_option (&server_universe, options, SV_LDAP_DEBUG_FILE);
3396 +      if (oc &&
3397 +          evaluate_option_cache (&db,  (struct packet*) NULL,
3398 +                (struct lease *) NULL, (struct client_state *) NULL,
3399 +                options, (struct option_state *) NULL, &global_scope, oc, MDL))
3400 +        {
3401 +          ldap_debug_file = dmalloc (db.len + 1, MDL);
3402 +          if (!ldap_debug_file)
3403 +            log_fatal ("no memory for ldap debug file");
3404 +          memcpy (ldap_debug_file, db.data, db.len);
3405 +          ldap_debug_file[db.len] = 0;
3406 +          data_string_forget (&db, MDL);
3407 +        }
3408 +
3409 +      option_state_dereference (&options, MDL);
3410 +    }
3411 +
3412 +  if (ldap_server == NULL || ldap_base_dn == NULL)
3413 +    {
3414 +      log_info ("Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not specified in the config file");
3415 +      ldap_method = LDAP_METHOD_STATIC;
3416 +      return;
3417 +    }
3418 +
3419 +  if (ldap_debug_file != NULL && ldap_debug_fd == -1)
3420 +    {
3421 +      if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY,
3422 +                                 S_IRUSR | S_IWUSR)) < 0)
3423 +        log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file,
3424 +                   strerror (errno));
3425 +    }
3426 +
3427 +#if defined (DEBUG_LDAP)
3428 +  log_info ("Connecting to LDAP server %s:%d", ldap_server, ldap_port);
3429 +#endif
3430 +
3431 +  if ((ld = ldap_init (ldap_server, ldap_port)) == NULL)
3432 +    {
3433 +      log_error ("Cannot init ldap session to %s", ldap_server);
3434 +      return;
3435 +    }
3436 +
3437 +  version = LDAP_VERSION3;
3438 +  if ((ret = ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version)) != LDAP_OPT_SUCCESS)
3439 +    {
3440 +      log_error ("Cannot set LDAP version to %d: %s", version,
3441 +                 ldap_err2string (ret));
3442 +    }
3443 +
3444 +#if defined (USE_SSL)
3445 +  if ((ret = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS)
3446 +    log_error ("Warning: Cannot start TLS session to %s: %s",
3447 +               ldap_server, ldap_err2string (ret));
3448 +  else
3449 +    log_info ("TLS session successfully started to %s", ldap_server);
3450 +#endif
3451 +
3452 +  if ((ret = ldap_simple_bind_s (ld, ldap_username, ldap_password)) != LDAP_SUCCESS)
3453 +    {
3454 +      log_error ("Error: Cannot login into ldap server %s: %s", ldap_server,
3455 +                 ldap_err2string (ret));
3456 +      ldap_unbind (ld);
3457 +      ld = NULL;
3458 +      return;
3459 +    }
3460 +
3461 +#if defined (DEBUG_LDAP)
3462 +  log_info ("Successfully logged into LDAP server %s", ldap_server);
3463 +#endif
3464 +}
3465 +
3466 +
3467 +static void
3468 +parse_external_dns (LDAPMessage * ent)
3469 +{
3470 +  char *search[] = {"dhcpOptionsDN", "dhcpSharedNetworkDN", "dhcpSubnetDN",
3471 +                    "dhcpGroupDN", "dhcpHostDN", "dhcpClassesDN", 
3472 +                    "dhcpPoolDN", NULL};
3473 +  LDAPMessage * newres, * newent;
3474 +  struct ldap_config_stack *ns;
3475 +  char **tempstr;
3476 +  int i, j, ret;
3477 +#if defined (DEBUG_LDAP)
3478 +  char *dn;
3479 +#endif
3480 +
3481 +  if (ld == NULL)
3482 +    ldap_start ();
3483 +  if (ld == NULL)
3484 +    return;
3485 +
3486 +  for (i=0; search[i] != NULL; i++)
3487 +    {
3488 +      if ((tempstr = ldap_get_values (ld, ent, search[i])) == NULL)
3489 +        continue;
3490 +
3491 +      for (j=0; tempstr[j] != NULL; j++)
3492 +        {
3493 +          if (*tempstr[j] == '\0')
3494 +            continue;
3495 +
3496 +          if ((ret = ldap_search_s (ld, tempstr[j], LDAP_SCOPE_BASE, 
3497 +                                    "objectClass=*", NULL, 0, 
3498 +                                    &newres)) != LDAP_SUCCESS)
3499 +            {
3500 +              ldap_value_free (tempstr);
3501 +              ldap_unbind (ld);
3502 +              ld = NULL;
3503 +              return;
3504 +            }
3505 +    
3506 +#if defined (DEBUG_LDAP)
3507 +          log_info ("Adding contents of subtree '%s' to config stack from '%s' reference", tempstr[j], search[i]);
3508 +#endif
3509 +          for (newent = ldap_first_entry (ld, newres);
3510 +               newent != NULL;
3511 +               newent = ldap_next_entry (ld, ent))
3512 +            {
3513 +#if defined (DEBUG_LDAP)
3514 +              dn = ldap_get_dn (ld, newent);
3515 +              if (dn != NULL)
3516 +                {
3517 +                  log_info ("Adding LDAP entry '%s' to config stack", dn);
3518 +                  ldap_memfree (dn);
3519 +                }
3520 +#endif
3521 +
3522 +              add_to_config_stack (newres, newent);
3523 +              /* don't free newres here */
3524 +            }
3525 +        }
3526 +
3527 +      ldap_value_free (tempstr);
3528 +    }
3529 +}
3530 +
3531 +
3532 +static void
3533 +free_stack_entry (struct ldap_config_stack *item)
3534 +{
3535 +  ldap_msgfree (item->res);
3536 +  dfree (item, MDL);
3537 +}
3538 +
3539 +
3540 +static void
3541 +next_ldap_entry (struct parse *cfile)
3542 +{
3543 +  struct ldap_config_stack *temp_stack;
3544 +
3545 +  if (ldap_stack != NULL && ldap_stack->close_brace)
3546 +    {
3547 +      strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
3548 +      ldap_stack->close_brace = 0;
3549 +    }
3550 +
3551 +  while (ldap_stack != NULL && 
3552 +         (ldap_stack->ldent == NULL ||
3553 +          (ldap_stack->ldent = ldap_next_entry (ld, ldap_stack->ldent)) == NULL))
3554 +    {
3555 +      if (ldap_stack->close_brace)
3556 +        {
3557 +          strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
3558 +          ldap_stack->close_brace = 0;
3559 +        }
3560 +
3561 +      temp_stack = ldap_stack;
3562 +      ldap_stack = ldap_stack->next;
3563 +      free_stack_entry (temp_stack);
3564 +    }
3565 +
3566 +  if (ldap_stack != NULL && ldap_stack->close_brace)
3567 +    {
3568 +      strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
3569 +      ldap_stack->close_brace = 0;
3570 +    }
3571 +}
3572 +
3573 +
3574 +static char
3575 +check_statement_end (const char *statement)
3576 +{
3577 +  char *ptr;
3578 +
3579 +  if (statement == NULL || *statement == '\0')
3580 +    return ('\0');
3581 +
3582 +  /*
3583 +  ** check if it ends with "}", e.g.:
3584 +  **   "zone my.domain. { ... }"
3585 +  ** optionally followed by spaces
3586 +  */
3587 +  ptr = strrchr (statement, '}');
3588 +  if (ptr != NULL)
3589 +    {
3590 +      /* skip following white-spaces */
3591 +      for (++ptr; isspace ((int)*ptr); ptr++);
3592 +
3593 +      /* check if we reached the end */
3594 +      if (*ptr == '\0')
3595 +        return ('}'); /* yes, block end */
3596 +      else
3597 +        return (*ptr);
3598 +    }
3599 +
3600 +  /*
3601 +  ** this should not happen, but...
3602 +  ** check if it ends with ";", e.g.:
3603 +  **   "authoritative;"
3604 +  ** optionally followed by spaces
3605 +  */
3606 +  ptr = strrchr (statement, ';');
3607 +  if (ptr != NULL)
3608 +    {
3609 +      /* skip following white-spaces */
3610 +      for (++ptr; isspace ((int)*ptr); ptr++);
3611 +
3612 +      /* check if we reached the end */
3613 +      if (*ptr == '\0')
3614 +        return (';'); /* ends with a ; */
3615 +      else
3616 +        return (*ptr);
3617 +    }
3618 +
3619 +  return ('\0');
3620 +}
3621 +
3622 +
3623 +static isc_result_t
3624 +ldap_parse_entry_options (LDAPMessage *ent, char *buffer, size_t size,
3625 +                          int *lease_limit)
3626 +{
3627 +  char **tempstr;
3628 +  int i;
3629 +
3630 +  if (ent == NULL || buffer == NULL || size == 0)
3631 +    return (ISC_R_FAILURE);
3632 +
3633 +  if ((tempstr = ldap_get_values (ld, ent, "dhcpStatements")) != NULL)
3634 +    {
3635 +      for (i=0; tempstr[i] != NULL; i++)
3636 +        {
3637 +          if (lease_limit != NULL &&
3638 +              strncasecmp ("lease limit ", tempstr[i], 12) == 0)
3639 +            {
3640 +              *lease_limit = (int) strtol ((tempstr[i]) + 12, NULL, 10);
3641 +              continue;
3642 +            }
3643 +
3644 +          strncat (buffer, tempstr[i], size);
3645 +
3646 +          switch((int) check_statement_end (tempstr[i]))
3647 +            {
3648 +              case '}':
3649 +              case ';':
3650 +                strncat (buffer, "\n", size);
3651 +                break;
3652 +              default:
3653 +                strncat (buffer, ";\n", size);
3654 +                break;
3655 +            }
3656 +        }
3657 +      ldap_value_free (tempstr);
3658 +    }
3659 +
3660 +  if ((tempstr = ldap_get_values (ld, ent, "dhcpOption")) != NULL)
3661 +    {
3662 +      for (i=0; tempstr[i] != NULL; i++)
3663 +        {
3664 +          strncat (buffer, "option ", size);
3665 +          strncat (buffer, tempstr[i], size);
3666 +          switch ((int) check_statement_end (tempstr[i]))
3667 +            {
3668 +              case ';':
3669 +                strncat (buffer, "\n", size);
3670 +                break;
3671 +              default:
3672 +                strncat (buffer, ";\n", size);
3673 +                break;
3674 +            }
3675 +        }
3676 +      ldap_value_free (tempstr);
3677 +    }
3678 +
3679 +  return (ISC_R_SUCCESS);
3680 +}
3681 +
3682 +
3683 +static void
3684 +ldap_generate_config_string (struct parse *cfile)
3685 +{
3686 +  char **objectClass, *dn;
3687 +  struct ldap_config_stack *entry;
3688 +  LDAPMessage * ent, * res;
3689 +  int i, j, ignore, found;
3690 +  int ret;
3691 +
3692 +  if (ld == NULL)
3693 +    ldap_start ();
3694 +  if (ld == NULL)
3695 +    return;
3696 +
3697 +  entry = ldap_stack;
3698 +  if ((objectClass = ldap_get_values (ld, entry->ldent, 
3699 +                                      "objectClass")) == NULL)
3700 +    return;
3701 +    
3702 +  ignore = 0;
3703 +  found = 1;
3704 +  for (i=0; objectClass[i] != NULL; i++)
3705 +    {
3706 +      if (strcmp (objectClass[i], "dhcpSharedNetwork") == 0)
3707 +        ldap_parse_shared_network (entry, cfile);
3708 +      else if (strcmp (objectClass[i], "dhcpClass") == 0)
3709 +        ldap_parse_class (entry, cfile);
3710 +      else if (strcmp (objectClass[i], "dhcpSubnet") == 0)
3711 +        ldap_parse_subnet (entry, cfile);
3712 +      else if (strcmp (objectClass[i], "dhcpPool") == 0)
3713 +        ldap_parse_pool (entry, cfile);
3714 +      else if (strcmp (objectClass[i], "dhcpGroup") == 0)
3715 +        ldap_parse_group (entry, cfile);
3716 +      else if (strcmp (objectClass[i], "dhcpHost") == 0)
3717 +        {
3718 +          if (ldap_method == LDAP_METHOD_STATIC)
3719 +            ldap_parse_host (entry, cfile);
3720 +          else
3721 +            {
3722 +              ignore = 1;
3723 +              break;
3724 +            }
3725 +        }
3726 +      else if (strcmp (objectClass[i], "dhcpSubClass") == 0)
3727 +        {
3728 +          if (ldap_method == LDAP_METHOD_STATIC)
3729 +            ldap_parse_subclass (entry, cfile);
3730 +          else
3731 +            {
3732 +              ignore = 1;
3733 +              break;
3734 +            }
3735 +        }
3736 +      else
3737 +        found = 0;
3738 +
3739 +      if (found && cfile->inbuf[0] == '\0')
3740 +        {
3741 +          ignore = 1;
3742 +          break;
3743 +        }
3744 +    }
3745 +
3746 +  ldap_value_free (objectClass);
3747 +
3748 +  if (ignore)
3749 +    {
3750 +      next_ldap_entry (cfile);
3751 +      return;
3752 +    }
3753 +
3754 +  ldap_parse_entry_options(entry->ldent, cfile->inbuf,
3755 +                           LDAP_BUFFER_SIZE-1, NULL);
3756 +
3757 +  dn = ldap_get_dn (ld, entry->ldent);
3758 +
3759 +#if defined(DEBUG_LDAP)
3760 +  if (dn != NULL)
3761 +    log_info ("Found LDAP entry '%s'", dn);
3762 +#endif
3763 +
3764 +  if (dn == NULL ||
3765 +      (ret = ldap_search_s (ld, dn, LDAP_SCOPE_ONELEVEL, "objectClass=*", 
3766 +                            NULL, 0, &res)) != LDAP_SUCCESS)
3767 +    {
3768 +      if (dn)
3769 +        ldap_memfree (dn);
3770 +
3771 +      ldap_unbind (ld);
3772 +      ld = NULL;
3773 +      return;
3774 +    }
3775 +
3776 +  ldap_memfree (dn);
3777 +
3778 +  if ((ent = ldap_first_entry (ld, res)) != NULL)
3779 +    {
3780 +      add_to_config_stack (res, ent);
3781 +      parse_external_dns (entry->ldent);
3782 +    }
3783 +  else
3784 +    {
3785 +      ldap_msgfree (res);
3786 +      parse_external_dns (entry->ldent);
3787 +      next_ldap_entry (cfile);
3788 +    }
3789 +}
3790 +
3791 +
3792 +static void
3793 +ldap_close_debug_fd()
3794 +{
3795 +  if (ldap_debug_fd != -1)
3796 +    {
3797 +      close (ldap_debug_fd);
3798 +      ldap_debug_fd = -1;
3799 +    }
3800 +}
3801 +
3802 +
3803 +static void
3804 +ldap_write_debug (const void *buff, size_t size)
3805 +{
3806 +  if (ldap_debug_fd != -1)
3807 +    {
3808 +      if (write (ldap_debug_fd, buff, size) < 0)
3809 +        {
3810 +          log_error ("Error writing to LDAP debug file %s: %s."
3811 +                     " Disabling log file.", ldap_debug_file,
3812 +                     strerror (errno));
3813 +          ldap_close_debug_fd();
3814 +        }
3815 +    }
3816 +}
3817 +
3818 +static char
3819 +ldap_read_function (struct parse *cfile)
3820 +{
3821 +  char eofstring[2] = {EOF, '\0'};
3822
3823 +  cfile->inbuf[0] = '\0';
3824 +  cfile->buflen = 0;
3825 +
3826 +  while (ldap_stack != NULL && *cfile->inbuf == '\0')
3827 +    ldap_generate_config_string (cfile);
3828 +
3829 +  cfile->buflen = strlen (cfile->inbuf);
3830 +  if (cfile->buflen > 0)
3831 +    ldap_write_debug (cfile->inbuf, cfile->buflen);
3832 +
3833 +#if defined (DEBUG_LDAP)
3834 +  log_info ("Sending config line '%s'", cfile->inbuf);
3835 +#endif
3836 +
3837 +  if (ldap_stack == NULL)
3838 +    strncat (cfile->inbuf, eofstring, LDAP_BUFFER_SIZE);
3839 +
3840 +  cfile->buflen = strlen (cfile->inbuf);
3841 +  cfile->bufix = 1;
3842 +
3843 +  return (cfile->inbuf[0]);
3844 +}
3845 +
3846 +
3847 +static char *
3848 +ldap_get_host_name (LDAPMessage * ent)
3849 +{
3850 +  char **name, *ret;
3851 +
3852 +  ret = NULL;
3853 +  if ((name = ldap_get_values (ld, ent, "cn")) == NULL || name[0] == NULL)
3854 +    {
3855 +      if (name != NULL)
3856 +        ldap_value_free (name);
3857 +
3858 +#if defined (DEBUG_LDAP)
3859 +      ret = ldap_get_dn (ld, ent);
3860 +      if (ret != NULL)
3861 +        {
3862 +          log_info ("Cannot get cn attribute for LDAP entry %s", ret);
3863 +          ldap_memfree(ret);
3864 +        }
3865 +#endif
3866 +      return (NULL);
3867 +    }
3868 +
3869 +  ret = dmalloc (strlen (name[0]) + 1, MDL);
3870 +  strcpy (ret, name[0]);
3871 +  ldap_value_free (name);
3872 +
3873 +  return (ret);
3874 +}
3875 +
3876 +
3877 +static int
3878 +getfqhostname(char *fqhost, size_t size)
3879 +{
3880 +#if defined(MAXHOSTNAMELEN)
3881 +  char   hname[MAXHOSTNAMELEN];
3882 +#else
3883 +  char   hname[65];
3884 +#endif
3885 +  struct hostent *hp;
3886 +
3887 +  if(NULL == fqhost || 1 >= size)
3888 +    return -1;
3889 +
3890 +  memset(hname, 0, sizeof(hname));
3891 +  if( gethostname(hname, sizeof(hname)-1))
3892 +    return -1;
3893 +
3894 +  if(NULL == (hp = gethostbyname(hname)))
3895 +    return -1;
3896 +
3897 +  strncpy(fqhost, hp->h_name, size-1);
3898 +  fqhost[size-1] = '\0';
3899 +  return 0;
3900 +}
3901 +
3902 +
3903 +isc_result_t
3904 +ldap_read_config (void)
3905 +{
3906 +  LDAPMessage * ldres, * hostres, * ent, * hostent;
3907 +  char hfilter[1024], sfilter[1024], fqdn[257];
3908 +  char *buffer, **tempstr = NULL, *hostdn;
3909 +  ldap_dn_node *curr = NULL;
3910 +  struct parse *cfile;
3911 +  struct utsname unme;
3912 +  isc_result_t res;
3913 +  size_t length;
3914 +  int ret, cnt;
3915 +
3916 +  if (ld == NULL)
3917 +    ldap_start ();
3918 +  if (ld == NULL)
3919 +    return (ldap_server == NULL ? ISC_R_SUCCESS : ISC_R_FAILURE);
3920
3921 +  buffer = dmalloc (LDAP_BUFFER_SIZE+1, MDL);
3922 +  if (buffer == NULL)
3923 +    return (ISC_R_FAILURE);
3924 +
3925 +  cfile = (struct parse *) NULL;
3926 +  res = new_parse (&cfile, -1, buffer, LDAP_BUFFER_SIZE, "LDAP", 0);
3927 +  if (res != ISC_R_SUCCESS)
3928 +    return (res);
3929
3930 +  uname (&unme);
3931 +  if(0 == getfqhostname(fqdn, sizeof(fqdn)))
3932 +    {
3933 +      snprintf (hfilter, sizeof (hfilter),
3934 +                "(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))", 
3935 +                unme.nodename, fqdn);
3936 +    }
3937 +  else
3938 +    {
3939 +      snprintf (hfilter, sizeof (hfilter),
3940 +                "(&(objectClass=dhcpServer)(cn=%s))", unme.nodename);
3941 +    }
3942 +
3943 +  hostres = NULL;
3944 +  if ((ret = ldap_search_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE,
3945 +                            hfilter, NULL, 0, &hostres)) != LDAP_SUCCESS)
3946 +    {
3947 +      log_error ("Cannot find host LDAP entry %s %s",
3948 +                 unme.nodename, hfilter);
3949 +      if(NULL != hostres)
3950 +        ldap_msgfree (hostres);
3951 +      ldap_unbind (ld);
3952 +      ld = NULL;
3953 +      return (ISC_R_FAILURE);
3954 +    }
3955 +
3956 +  if ((hostent = ldap_first_entry (ld, hostres)) == NULL)
3957 +    {
3958 +      log_error ("Error: Cannot find LDAP entry matching %s", hfilter);
3959 +      ldap_msgfree (hostres);
3960 +      ldap_unbind (ld);
3961 +      ld = NULL;
3962 +      return (ISC_R_FAILURE);
3963 +    }
3964 +
3965 +  hostdn = ldap_get_dn (ld, hostent);
3966 +#if defined(DEBUG_LDAP)
3967 +  if (hostdn != NULL)
3968 +    log_info ("Found dhcpServer LDAP entry '%s'", hostdn);
3969 +#endif
3970 +
3971 +  if (hostdn == NULL ||
3972 +      (tempstr = ldap_get_values (ld, hostent, "dhcpServiceDN")) == NULL ||
3973 +      tempstr[0] == NULL)
3974 +    {
3975 +      log_error ("Error: Cannot find LDAP entry matching %s", hfilter);
3976 +
3977 +      if (tempstr != NULL)
3978 +        ldap_value_free (tempstr);
3979 +
3980 +      if (hostdn)
3981 +        ldap_memfree (hostdn);
3982 +      ldap_msgfree (hostres);
3983 +      ldap_unbind (ld);
3984 +      ld = NULL;
3985 +      return (ISC_R_FAILURE);
3986 +    }
3987 +
3988 +#if defined(DEBUG_LDAP)
3989 +  log_info ("LDAP: Parsing dhcpServer options '%s' ...", hostdn);
3990 +#endif
3991 +
3992 +  cfile->inbuf[0] = '\0';
3993 +  ldap_parse_entry_options(hostent, cfile->inbuf, LDAP_BUFFER_SIZE, NULL);
3994 +  cfile->buflen = strlen (cfile->inbuf);
3995 +  if(cfile->buflen > 0)
3996 +    {
3997 +      ldap_write_debug (cfile->inbuf, cfile->buflen);
3998 +
3999 +      res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
4000 +      if (res != ISC_R_SUCCESS)
4001 +        {
4002 +          log_error ("LDAP: cannot parse dhcpServer entry '%s'", hostdn);
4003 +          ldap_memfree (hostdn);
4004 +          ldap_unbind (ld);
4005 +          ld = NULL;
4006 +          return res;
4007 +        }
4008 +      cfile->inbuf[0] = '\0';
4009 +    }
4010 +  ldap_msgfree (hostres);
4011 +
4012 +  /*
4013 +  ** attach ldap (tree) read function now
4014 +  */
4015 +  cfile->bufix = cfile->buflen = 0;
4016 +  cfile->read_function = ldap_read_function;
4017 +
4018 +  res = ISC_R_SUCCESS;
4019 +  for (cnt=0; tempstr[cnt] != NULL; cnt++)
4020 +    {
4021 +      snprintf(sfilter, sizeof(sfilter), "(&(objectClass=dhcpService)"
4022 +                        "(|(dhcpPrimaryDN=%s)(dhcpSecondaryDN=%s)))",
4023 +                        hostdn, hostdn);
4024 +      ldres = NULL;
4025 +      if ((ret = ldap_search_s (ld, tempstr[cnt], LDAP_SCOPE_BASE,
4026 +                                sfilter, NULL, 0, &ldres)) != LDAP_SUCCESS)
4027 +        {
4028 +          log_error ("Error searching for dhcpServiceDN '%s': %s. Please update the LDAP entry '%s'",
4029 +                     tempstr[cnt], ldap_err2string (ret), hostdn);
4030 +          if(NULL != ldres)
4031 +            ldap_msgfree(ldres);
4032 +          res = ISC_R_FAILURE;
4033 +          break;
4034 +        }
4035 +
4036 +      if ((ent = ldap_first_entry (ld, ldres)) == NULL)
4037 +        {
4038 +          log_error ("Error: Cannot find dhcpService DN '%s' with primary or secondary server reference. Please update the LDAP server entry '%s'",
4039 +                     tempstr[cnt], hostdn);
4040 +
4041 +          ldap_msgfree(ldres);
4042 +          res = ISC_R_FAILURE;
4043 +          break;
4044 +        }
4045 +
4046 +      /*
4047 +      ** FIXME: how to free the remembered dn's on exit?
4048 +      **        This should be OK if dmalloc registers the
4049 +      **        memory it allocated and frees it on exit..
4050 +      */
4051 +
4052 +      curr = dmalloc (sizeof (*curr), MDL);
4053 +      if (curr != NULL)
4054 +        {
4055 +          length = strlen (tempstr[cnt]);
4056 +          curr->dn = dmalloc (length + 1, MDL);
4057 +          if (curr->dn == NULL)
4058 +            {
4059 +              dfree (curr, MDL);
4060 +              curr = NULL;
4061 +            }
4062 +          else
4063 +            strcpy (curr->dn, tempstr[cnt]);
4064 +        }
4065 +
4066 +      if (curr != NULL)
4067 +        {
4068 +          curr->refs++;
4069 +
4070 +          /* append to service-dn list */
4071 +          if (ldap_service_dn_tail != NULL)
4072 +            ldap_service_dn_tail->next = curr;
4073 +          else
4074 +            ldap_service_dn_head = curr;
4075 +
4076 +          ldap_service_dn_tail = curr;
4077 +        }
4078 +      else
4079 +        log_fatal ("no memory to remember ldap service dn");
4080 +
4081 +#if defined (DEBUG_LDAP)
4082 +      log_info ("LDAP: Parsing dhcpService DN '%s' ...", tempstr[cnt]);
4083 +#endif
4084 +      add_to_config_stack (ldres, ent);
4085 +      res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
4086 +      if (res != ISC_R_SUCCESS)
4087 +        {
4088 +          log_error ("LDAP: cannot parse dhcpService entry '%s'", tempstr[cnt]);
4089 +          break;
4090 +        }
4091 +    }
4092 +
4093 +  end_parse (&cfile);
4094 +  ldap_close_debug_fd();
4095 +
4096 +  ldap_memfree (hostdn);
4097 +  ldap_value_free (tempstr);
4098 +
4099 +  if (res != ISC_R_SUCCESS)
4100 +    {
4101 +      struct ldap_config_stack *temp_stack;
4102 +
4103 +      while ((curr = ldap_service_dn_head) != NULL)
4104 +        {
4105 +          ldap_service_dn_head = curr->next;
4106 +          dfree (curr->dn, MDL);
4107 +          dfree (curr, MDL);
4108 +        }
4109 +
4110 +      ldap_service_dn_tail = NULL;
4111 +
4112 +      while ((temp_stack = ldap_stack) != NULL)
4113 +        {
4114 +          ldap_stack = temp_stack->next;
4115 +          free_stack_entry (temp_stack);
4116 +        }
4117 +
4118 +      ldap_unbind (ld);
4119 +      ld = NULL;
4120 +    }
4121 +
4122 +  return (res);
4123 +}
4124 +
4125 +
4126 +/* This function will parse the dhcpOption and dhcpStatements field in the LDAP
4127 +   entry if it exists. Right now, type will be either HOST_DECL or CLASS_DECL.
4128 +   If we are parsing a HOST_DECL, this always returns 0. If we are parsing a 
4129 +   CLASS_DECL, this will return what the current lease limit is in LDAP. If
4130 +   there is no lease limit specified, we return 0 */
4131 +
4132 +static int
4133 +ldap_parse_options (LDAPMessage * ent, struct group *group,
4134 +                         int type, struct host_decl *host,
4135 +                         struct class **class)
4136 +{
4137 +  int i, declaration, lease_limit;
4138 +  char option_buffer[8192];
4139 +  enum dhcp_token token;
4140 +  struct parse *cfile;
4141 +  isc_result_t res;
4142 +  const char *val;
4143 +
4144 +  lease_limit = 0;
4145 +  *option_buffer = '\0';
4146 +  res = ldap_parse_entry_options (ent, option_buffer, sizeof(option_buffer) - 1,
4147 +                                  &lease_limit);
4148 +  if (res != ISC_R_SUCCESS)
4149 +    return (lease_limit);
4150 +
4151 +  option_buffer[sizeof(option_buffer) - 1] = '\0';
4152 +  if (*option_buffer == '\0')
4153 +    return (lease_limit);
4154 +
4155 +  cfile = (struct parse *) NULL;
4156 +  res = new_parse (&cfile, -1, option_buffer, strlen (option_buffer), 
4157 +                   type == HOST_DECL ? "LDAP-HOST" : "LDAP-SUBCLASS", 0);
4158 +  if (res != ISC_R_SUCCESS)
4159 +    return (lease_limit);
4160 +
4161 +#if defined (DEBUG_LDAP)
4162 +  log_info ("Sending the following options: '%s'", option_buffer);
4163 +#endif
4164 +
4165 +  declaration = 0;
4166 +  do
4167 +    {
4168 +      token = peek_token (&val, NULL, cfile);
4169 +      if (token == END_OF_FILE)
4170 +        break;
4171 +       declaration = parse_statement (cfile, group, type, host, declaration);
4172 +    } while (1);
4173 +
4174 +  end_parse (&cfile);
4175 +
4176 +  return (lease_limit);
4177 +}
4178 +
4179 +
4180 +
4181 +int
4182 +find_haddr_in_ldap (struct host_decl **hp, int htype, unsigned hlen,
4183 +                    const unsigned char *haddr, const char *file, int line)
4184 +{
4185 +  char buf[128], *type_str, **tempstr, *addr_str;
4186 +  LDAPMessage * res, *ent;
4187 +  struct host_decl * host;
4188 +  isc_result_t status;
4189 +  ldap_dn_node *curr;
4190 +  int ret;
4191 +
4192 +  if (ldap_method == LDAP_METHOD_STATIC)
4193 +    return (0);
4194 +
4195 +  if (ld == NULL)
4196 +    ldap_start ();
4197 +  if (ld == NULL)
4198 +    return (0);
4199 +
4200 +  switch (htype)
4201 +    {
4202 +      case HTYPE_ETHER:
4203 +        type_str = "ethernet";
4204 +        break;
4205 +      case HTYPE_IEEE802:
4206 +        type_str = "token-ring";
4207 +        break;
4208 +      case HTYPE_FDDI:
4209 +        type_str = "fddi";
4210 +        break;
4211 +      default:
4212 +        log_info ("Ignoring unknown type %d", htype);
4213 +        return (0);
4214 +    }
4215 +
4216 +  /*
4217 +  ** FIXME: dhcpHWAddress attribute uses octetStringMatch
4218 +  **        (what means exact octet match, case sensitive)!
4219 +  **
4220 +  **        it is not guaranted, that ldap contains _exactly_
4221 +  **        "type addr" with one space between!
4222 +  **        AFAIK print_hw_addr() produces a lower case string.
4223 +  */
4224 +  snprintf (buf, sizeof (buf),
4225 +            "(&(objectClass=dhcpHost)(dhcpHWAddress=%s %s))",
4226 +           type_str, print_hw_addr (htype, hlen, haddr));
4227 +
4228 +  res = ent = NULL;
4229 +  for (curr = ldap_service_dn_head;
4230 +       curr != NULL && *curr->dn != '\0';
4231 +       curr = curr->next)
4232 +    {
4233 +#if defined (DEBUG_LDAP)
4234 +      log_info ("Searching for %s in LDAP tree %s", buf, curr->dn);
4235 +#endif
4236 +      ret = ldap_search_s (ld, curr->dn, LDAP_SCOPE_SUBTREE,
4237 +                           buf, NULL, 0, &res);
4238 +      if (ret == LDAP_SUCCESS)
4239 +        {
4240 +          if( (ent = ldap_first_entry (ld, res)) != NULL)
4241 +            break; /* search OK and have entry */
4242 +
4243 +#if defined (DEBUG_LDAP)
4244 +          log_info ("No host entry for %s in LDAP tree %s",
4245 +                    buf, curr->dn);
4246 +#endif
4247 +          if(res)
4248 +            {
4249 +              ldap_msgfree (res);
4250 +              res = NULL;
4251 +            }
4252 +        }
4253 +      else
4254 +        {
4255 +          if(res)
4256 +            {
4257 +              ldap_msgfree (res);
4258 +              res = NULL;
4259 +            }
4260 +
4261 +          if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
4262 +            {
4263 +              log_error ("Cannot search for %s in LDAP tree %s: %s", buf, 
4264 +                         curr->dn, ldap_err2string (ret));
4265 +              ldap_unbind (ld);
4266 +              ld = NULL;
4267 +              return (0);
4268 +            }
4269 +#if defined (DEBUG_LDAP)
4270 +          else
4271 +            {
4272 +              log_info ("ldap_search_s returned %s when searching for %s in %s",
4273 +                        ldap_err2string (ret), buf, curr->dn);
4274 +            }
4275 +#endif
4276 +        }
4277 +    }
4278 +
4279 +  if (res && ent)
4280 +    {
4281 +#if defined (DEBUG_LDAP)
4282 +      char *dn = ldap_get_dn (ld, ent);
4283 +      if (dn != NULL)
4284 +        {
4285 +          log_info ("Found dhcpHWAddress LDAP entry %s", dn);
4286 +          ldap_memfree(dn);
4287 +        }
4288 +#endif
4289 +
4290 +      host = (struct host_decl *)0;
4291 +      status = host_allocate (&host, MDL);
4292 +      if (status != ISC_R_SUCCESS)
4293 +        {
4294 +          log_fatal ("can't allocate host decl struct: %s", 
4295 +                     isc_result_totext (status)); 
4296 +          ldap_msgfree (res);
4297 +          return (0);
4298 +        }
4299 +
4300 +      host->name = ldap_get_host_name (ent);
4301 +      if (host->name == NULL)
4302 +        {
4303 +          host_dereference (&host, MDL);
4304 +          ldap_msgfree (res);
4305 +          return (0);
4306 +        }
4307 +
4308 +      if (!clone_group (&host->group, root_group, MDL))
4309 +        {
4310 +          log_fatal ("can't clone group for host %s", host->name);
4311 +          host_dereference (&host, MDL);
4312 +          ldap_msgfree (res);
4313 +          return (0);
4314 +        }
4315 +
4316 +      /*
4317 +      ** PROBLEM: since dhcpd uses no unique names for groups,
4318 +      **          it seems to be not possible to find the right
4319 +      **          one, our host may belong to.
4320 +      **
4321 +      ** PERHAPS: Check if parent DN is a dhcpGroup or the host-dn
4322 +      **          is referenced via dhcpHostDN in a dhcpGroup.
4323 +      **          If found, we may fetch and apply group options
4324 +      **          and statements to above host->group ?
4325 +      */
4326 +      ldap_parse_options (ent, host->group, HOST_DECL, host, NULL);
4327 +
4328 +      *hp = host;
4329 +      ldap_msgfree (res);
4330 +      return (1);
4331 +    }
4332 +
4333 +
4334 +  if(res) ldap_msgfree (res);
4335 +  return (0);
4336 +}
4337 +
4338 +
4339 +int
4340 +find_subclass_in_ldap (struct class *class, struct class **newclass, 
4341 +                       struct data_string *data)
4342 +{
4343 +  LDAPMessage * res, * ent;
4344 +  int i, ret, lease_limit;
4345 +  isc_result_t status;
4346 +  ldap_dn_node *curr;
4347 +  char buf[1024];
4348 +
4349 +  if (ldap_method == LDAP_METHOD_STATIC)
4350 +    return (0);
4351 +
4352 +  if (ld == NULL)
4353 +    ldap_start ();
4354 +  if (ld == NULL)
4355 +    return (0);
4356 +
4357 +  snprintf (buf, sizeof (buf), "(&(objectClass=dhcpSubClass)(cn=%s)(dhcpClassData=%s))", print_hex_1 (data->len, data->data, 60), print_hex_2 (strlen (class->name), class->name, 60));
4358 +#if defined (DEBUG_LDAP)
4359 +  log_info ("Searching LDAP for %s", buf);
4360 +#endif
4361 +
4362 +  res = ent = NULL;
4363 +  for (curr = ldap_service_dn_head;
4364 +       curr != NULL && *curr->dn != '\0';
4365 +       curr = curr->next)
4366 +    {
4367 +#if defined (DEBUG_LDAP)
4368 +      log_info ("Searching for %s in LDAP tree %s", buf, curr->dn);
4369 +#endif
4370 +      ret = ldap_search_s (ld, curr->dn, LDAP_SCOPE_SUBTREE,
4371 +                           buf, NULL, 0, &res);
4372 +      if (ret == LDAP_SUCCESS)
4373 +        {
4374 +          if( (ent = ldap_first_entry (ld, res)) != NULL)
4375 +            break; /* search OK and have entry */
4376 +
4377 +#if defined (DEBUG_LDAP)
4378 +          log_info ("No subclass entry for %s in LDAP tree %s",
4379 +                    buf, curr->dn);
4380 +#endif
4381 +          if(res)
4382 +            {
4383 +              ldap_msgfree (res);
4384 +              res = NULL;
4385 +            }
4386 +        }
4387 +      else
4388 +        {
4389 +          if(res)
4390 +            {
4391 +              ldap_msgfree (res);
4392 +              res = NULL;
4393 +            }
4394 +
4395 +          if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
4396 +            {
4397 +              log_error ("Cannot search for %s in LDAP tree %s: %s", buf, 
4398 +                         curr->dn, ldap_err2string (ret));
4399 +              ldap_unbind (ld);
4400 +              ld = NULL;
4401 +              return (0);
4402 +            }
4403 +#if defined (DEBUG_LDAP)
4404 +          else
4405 +            {
4406 +              log_info ("ldap_search_s returned %s when searching for %s in %s",
4407 +                        ldap_err2string (ret), buf, curr->dn);
4408 +            }
4409 +#endif
4410 +        }
4411 +    }
4412 +
4413 +  if (res && ent)
4414 +    {
4415 +#if defined (DEBUG_LDAP)
4416 +      char *dn = ldap_get_dn (ld, ent);
4417 +      if (dn != NULL)
4418 +        {
4419 +          log_info ("Found subclass LDAP entry %s", dn);
4420 +          ldap_memfree(dn);
4421 +        }
4422 +#endif
4423 +
4424 +      status = class_allocate (newclass, MDL);
4425 +      if (status != ISC_R_SUCCESS)
4426 +        {
4427 +          log_error ("Cannot allocate memory for a new class");
4428 +          ldap_msgfree (res);
4429 +          return (0);
4430 +        }
4431 +
4432 +      group_reference (&(*newclass)->group, class->group, MDL);
4433 +      class_reference (&(*newclass)->superclass, class, MDL);
4434 +      lease_limit = ldap_parse_options (ent, (*newclass)->group, 
4435 +                                        CLASS_DECL, NULL, newclass);
4436 +      if (lease_limit == 0)
4437 +        (*newclass)->lease_limit = class->lease_limit; 
4438 +      else
4439 +        class->lease_limit = lease_limit;
4440 +
4441 +      if ((*newclass)->lease_limit) 
4442 +        {
4443 +          (*newclass)->billed_leases = 
4444 +              dmalloc ((*newclass)->lease_limit * sizeof (struct lease *), MDL);
4445 +          if (!(*newclass)->billed_leases) 
4446 +            {
4447 +              log_error ("no memory for billing");
4448 +              class_dereference (newclass, MDL);
4449 +              ldap_msgfree (res);
4450 +              return (0);
4451 +            }
4452 +          memset ((*newclass)->billed_leases, 0, 
4453 +                ((*newclass)->lease_limit * sizeof (*newclass)->billed_leases));
4454 +        }
4455 +
4456 +      data_string_copy (&(*newclass)->hash_string, data, MDL);
4457 +
4458 +      ldap_msgfree (res);
4459 +      return (1);
4460 +    }
4461 +
4462 +  if(res) ldap_msgfree (res);
4463 +  return (0);
4464 +}
4465 +
4466 +#endif
4467 +
4468 diff -Naur dhcp-3.0.1rc14/server/mdb.c dhcp-3.0.1rc14-ldap/server/mdb.c
4469 --- dhcp-3.0.1rc14/server/mdb.c 2004-06-10 13:59:56.000000000 -0400
4470 +++ dhcp-3.0.1rc14-ldap/server/mdb.c    2004-06-22 15:18:20.000000000 -0400
4471 @@ -375,6 +375,12 @@
4472  {
4473         struct host_decl *foo;
4474         struct hardware h;
4475 +       int ret;
4476 +
4477 +#if defined(LDAP_CONFIGURATION)
4478 +       if ((ret = find_haddr_in_ldap (hp, htype, hlen, haddr, file, line)))
4479 +               return ret;
4480 +#endif
4481  
4482         h.hlen = hlen + 1;
4483         h.hbuf [0] = htype;
4484 diff -Naur dhcp-3.0.1rc14/server/stables.c dhcp-3.0.1rc14-ldap/server/stables.c
4485 --- dhcp-3.0.1rc14/server/stables.c     2004-06-10 13:59:58.000000000 -0400
4486 +++ dhcp-3.0.1rc14-ldap/server/stables.c        2004-06-22 15:18:20.000000000 -0400
4487 @@ -483,6 +483,15 @@
4488         { "log-facility", "Nsyslog-facilities.",        &server_universe, 44 },
4489         { "do-forward-updates", "f",                    &server_universe, 45 },
4490         { "ping-timeout", "T",                          &server_universe, 46 },
4491 +#if defined(LDAP_CONFIGURATION)
4492 +       { "ldap-server", "t",                           &server_universe, 47 },
4493 +       { "ldap-port", "d",                             &server_universe, 48 },
4494 +       { "ldap-username", "t",                         &server_universe, 49 },
4495 +       { "ldap-password", "t",                         &server_universe, 50 },
4496 +       { "ldap-base-dn", "t",                          &server_universe, 51 },
4497 +       { "ldap-method", "Nldap-methods.",              &server_universe, 52 },
4498 +       { "ldap-debug-file", "t",                       &server_universe, 53 },
4499 +#else
4500         { "unknown-47", "X",                            &server_universe, 47 },
4501         { "unknown-48", "X",                            &server_universe, 48 },
4502         { "unknown-49", "X",                            &server_universe, 49 },
4503 @@ -490,6 +499,7 @@
4504         { "unknown-51", "X",                            &server_universe, 51 },
4505         { "unknown-52", "X",                            &server_universe, 52 },
4506         { "unknown-53", "X",                            &server_universe, 53 },
4507 +#endif
4508         { "unknown-54", "X",                            &server_universe, 54 },
4509         { "unknown-55", "X",                            &server_universe, 55 },
4510         { "unknown-56", "X",                            &server_universe, 56 },
4511 @@ -694,6 +704,20 @@
4512         { "option-end", "e",                            &server_universe, 255 },
4513  };
4514  
4515 +#if defined(LDAP_CONFIGURATION)
4516 +struct enumeration_value ldap_values [] = {
4517 +       { "static", LDAP_METHOD_STATIC },
4518 +       { "dynamic", LDAP_METHOD_DYNAMIC },
4519 +       { (char *) 0, 0 }
4520 +};
4521 +
4522 +struct enumeration ldap_methods = {
4523 +       (struct enumeration *)0,
4524 +       "ldap-methods",
4525 +       ldap_values
4526 +};
4527 +#endif
4528 +
4529  struct enumeration_value ddns_styles_values [] = {
4530         { "none", 0 },
4531         { "ad-hoc", 1 },
4532 diff -Naur dhcp-3.0.1rc14/site.conf dhcp-3.0.1rc14-ldap/site.conf
4533 --- dhcp-3.0.1rc14/site.conf    1999-07-07 11:20:10.000000000 -0400
4534 +++ dhcp-3.0.1rc14-ldap/site.conf       2004-06-22 15:24:59.000000000 -0400
4535 @@ -1,2 +1,3 @@
4536  # Put local site configuration stuff here to override the default
4537  # settings in Makefile.conf
4538 +#COPTS = -DDEBUG_LDAP -DDEBUG_CLASS_MATCHING -Wall -O -Wno-unused
This page took 0.420367 seconds and 3 git commands to generate.