Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 72355
Collapse All | Expand All

(-)dhcp-3.0.1/Changelog-LDAP (+113 lines)
Line 0 Link Here
1
2004-11-8 Brian Masney <masneyb@ntelos.net>
2
	* debian/control - updated the depends and build-depends line
3
	(from Andrew Pollock <me@andrew.net.au>)
4
5
2004-10-13 Brian Masney <masneyb@ntelos.net>
6
	* server/ldap.c (ldap_start) - allow doing an anonymous bind to the
7
	LDAP server
8
9
2004-9-27 Brian Masney <masneyb@ntelos.net>
10
	* contrib/dhcpd-conf-to-ldap.pl - make sure the DHCP hardware address
11
	is always lowercased
12
13
2004-7-30 Brian Masney <masneyb@ntelos.net>
14
	* server/ldap.c - added more debbuging statements. Fixed possible crash
15
	that could occur whenever more than 1 external DN is added to an LDAP
16
	entry. Fixed possible infinite loop when reading the external DNs.
17
	(from Sebastian Hetze <s.hetze@linux-ag.de>)
18
19
2004-7-1 Brian Masney <masneyb@ntelos.net>
20
	* README.ldap - updated build instructions paragraph
21
	(from Mason Schmitt <sysadmin@sunwave.net>)
22
23
2004-6-29 Brian Masney <masneyb@ntelos.net>
24
	* debian/control - set the minimum required version of the DHCP server
25
	to be 3.0.1rc9
26
27
	* configure - fix for sed when configure was run from an older shell
28
29
2004-6-22 Brian Masney <masneyb@ntelos.net>
30
	* Updated patch to use ISC DHCP 3.0.1rc14
31
32
2004-5-24 Brian Masney <masneyb@ntelos.net>
33
	* server/ldap.c - don't append a ; to the end of a dhcpStatement if it
34
	ends in }
35
36
	* server/ldap.c contrib/dhcpd-conf-to-ldap.pl - support having multiple
37
	dhcpRange statements (from Marco D'Ettorre <marco.dettorre@sys-net.it>)
38
39
2004-5-5 Brian Masney <masneyb@ntelos.net>
40
	* server/ldap.c - added more debugging statements when
41
	it is compiled in to help troubleshoot parsing errors. Don't free
42
	a LDAP connection prematurely when there is a reference to another
43
	LDAP tree. If the config entry ends in }, make sure a ; gets tacked
44
	on
45
46
	* debian/* - Updated version number. Renamed package from
47
	dhcp3-ldap-ntelos to dhcp3-server-ldap.
48
49
	* server/ldap.c - enclose the shared-network name in quotes so
50
	that there can be shared network statements in LDAP that have spaces
51
	in them
52
53
	* configure - after the work directory is setup, add -lldap -llber
54
	to the server Makefile
55
56
Wed Apr 21 15:09:08 CEST 2004 - mt@suse.de
57
	* contrib/dhcpd-conf-to-ldap.pl:
58
	  - added "--conf=file" option usable instead of stdin
59
	  - added "--ldif=file" option usable instead of stdout
60
	  - added "--second=host|dn" option usefull for failover
61
	  - added "--use=feature" option to enable extended features;
62
	    currently used to enable failover (default is disabled).
63
	  - extended remaining_line() to support block statements
64
	  - fixed / improved failover support, added notes about
65
66
	* server/ldap.c:
67
	  - moved code checking statement ends to check_statement_end()
68
	  - moved parsing of entry options/statements to
69
	    ldap_parse_entry_options()
70
	  - moved code closing debug fd into ldap_close_debug_fd()
71
	  - moved code writing to debug fd into ldap_write_debug()
72
	  - added support for full hostname in dhcpServer search filter
73
	  - added support for multiple dhcpService entries in dhcpServer object
74
	  - added parsing of options and statements for dhcpServer object
75
	  - added verify if dhcpService contains server dn as primary or
76
	    secondary
77
	  - changed to search for dhcpHost,dhcpSubClass bellow of all
78
	    dhcpService trees instead of base-dn (avoids finding of hosts in
79
	    foreign configs)
80
	  - fixes to free all dn's fetched by ldap_get_dn (e.g. debug output)
81
	  - fixes to free ldap results, mainly in cases where no LDAP_SUCCESS
82
	    returned or other error conditions happened
83
	  - fixed/improved some log messages
84
85
2004-3-30 Brian Masney <masneyb@ntelos.net>
86
	* contrib/dhcpd-conf-to-ldap.pl - added option to control the
87
	DHCP Config DN. Wrap the DHCP Statements in { }
88
	This patch was contributed by Marius Tomaschewski <mt@suse.de>
89
90
	* server/ldap.c - changed ldap_username and ldap_password to
91
	be optional (anonymous bind is used then). Added {} block support
92
	to dhcpStatements. (no ";" at end if statement ends with a "}").
93
	Fixed writing to ldap-debug-file. Changed find_haddr_in_ldap() to
94
	use dhcpHost objectClass in its filter
95
	This patch was contributed by Marius Tomaschewski <mt@suse.de>
96
97
2004-3-23 Brian Masney <masneyb@ntelos.net>
98
	* contrib/dhcpd-conf-to-ldap.pl - added options for server, basedn
99
	options and usage message (Net::Domain instead of SYS::Hostname).
100
	Added handling of zone, authoritative and failover (config and
101
	pool-refs) statements. Added numbering of groups and pools per
102
	subnet. This patch was contributed by Marius Tomaschewski <mt@suse.de>
103
104
2004-2-26 Brian Masney <masneyb@ntelos.net>
105
	* fixed an instance where the LDAP server would restart, but the DHCP
106
	server would not reconnect
107
108
2004-2-18 Brian Masney <masneyb@ntelos.net>
109
	* allow multiple dhcp*DN entries in the LDAP entry.
110
111
2003-9-11 Brian Masney <masneyb@ntelos.net>
112
	* updated patch to work with 3.0.1rc12
113
(-)dhcp-3.0.1/common/conflex.c (-15 / +31 lines)
Lines 47-52 Link Here
47
static enum dhcp_token read_number PROTO ((int, struct parse *));
47
static enum dhcp_token read_number PROTO ((int, struct parse *));
48
static enum dhcp_token read_num_or_name PROTO ((int, struct parse *));
48
static enum dhcp_token read_num_or_name PROTO ((int, struct parse *));
49
static enum dhcp_token intern PROTO ((char *, enum dhcp_token));
49
static enum dhcp_token intern PROTO ((char *, enum dhcp_token));
50
static char read_function PROTO ((struct parse *));
50
51
51
isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
52
isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
52
	struct parse **cfile;
53
	struct parse **cfile;
Lines 74-79 Link Here
74
	tmp -> file = file;
75
	tmp -> file = file;
75
	tmp -> eol_token = eolp;
76
	tmp -> eol_token = eolp;
76
77
78
	if (file != -1) {
79
		tmp -> read_function = read_function;;
80
	}
81
77
	tmp -> bufix = 0;
82
	tmp -> bufix = 0;
78
	tmp -> buflen = buflen;
83
	tmp -> buflen = buflen;
79
	if (inbuf) {
84
	if (inbuf) {
Lines 109-130 Link Here
109
	int c;
114
	int c;
110
115
111
	if (cfile -> bufix == cfile -> buflen) {
116
	if (cfile -> bufix == cfile -> buflen) {
112
		if (cfile -> file != -1) {
117
		if (cfile -> read_function) {
113
			cfile -> buflen =
118
			c = cfile -> read_function (cfile);
114
				read (cfile -> file,
119
		} else {
115
				      cfile -> inbuf, cfile -> bufsiz);
116
			if (cfile -> buflen == 0) {
117
				c = EOF;
118
				cfile -> bufix = 0;
119
			} else if (cfile -> buflen < 0) {
120
				c = EOF;
121
				cfile -> bufix = cfile -> buflen = 0;
122
			} else {
123
				c = cfile -> inbuf [0];
124
				cfile -> bufix = 1;
125
			}
126
		} else
127
			c = EOF;
120
			c = EOF;
121
		}
128
	} else {
122
	} else {
129
		c = cfile -> inbuf [cfile -> bufix];
123
		c = cfile -> inbuf [cfile -> bufix];
130
		cfile -> bufix++;
124
		cfile -> bufix++;
Lines 1071-1073 Link Here
1071
	}
1065
	}
1072
	return dfv;
1066
	return dfv;
1073
}
1067
}
1068
1069
1070
static char
1071
read_function (struct parse * cfile)
1072
{
1073
  char c;
1074
1075
	cfile -> buflen = read (cfile -> file, cfile -> inbuf, cfile -> bufsiz);
1076
	if (cfile -> buflen == 0) {
1077
		c = EOF;
1078
		cfile -> bufix = 0;
1079
	} else if (cfile -> buflen < 0) {
1080
		c = EOF;
1081
		cfile -> bufix = cfile -> buflen = 0;
1082
	} else {
1083
		c = cfile -> inbuf [0];
1084
		cfile -> bufix = 1;
1085
	}
1086
1087
	return c;
1088
}
1089
(-)dhcp-3.0.1/common/print.c (-3 / +3 lines)
Lines 166-174 Link Here
166
}
166
}
167
167
168
char *print_hw_addr (htype, hlen, data)
168
char *print_hw_addr (htype, hlen, data)
169
	int htype;
169
	const int htype;
170
	int hlen;
170
	const int hlen;
171
	unsigned char *data;
171
	const unsigned char *data;
172
{
172
{
173
	static char habuf [49];
173
	static char habuf [49];
174
	char *s;
174
	char *s;
(-)dhcp-3.0.1/configure (+4 lines)
Lines 256-259 Link Here
256
  make links
256
  make links
257
fi
257
fi
258
258
259
mv $workname/server/Makefile $workname/server/Makefile.noldap
260
cat $workname/server/Makefile.noldap | sed 's/^LIBS =/LIBS=-lldap -llber/' > $workname/server/Makefile.ldap
261
ln $workname/server/Makefile.ldap $workname/server/Makefile
262
259
exit 0
263
exit 0
(-)dhcp-3.0.1/contrib/dhcpd-conf-to-ldap.pl (+752 lines)
Line 0 Link Here
1
#!/usr/bin/perl -w
2
3
# Brian Masney <masneyb@ntelos.net>
4
# To use this script, set your base DN below. Then run 
5
# ./dhcpd-conf-to-ldap.pl < /path-to-dhcpd-conf/dhcpd.conf > output-file
6
# The output of this script will generate entries in LDIF format. You can use
7
# the slapadd command to add these entries into your LDAP server. You will
8
# definately want to double check that your LDAP entries are correct before
9
# you load them into LDAP.
10
11
# This script does not do much error checking. Make sure before you run this
12
# that the DHCP server doesn't give any errors about your config file
13
14
# FailOver notes:
15
#   Failover is disabled by default, since it may need manually intervention.
16
#   You can try the '--use=failover' option to see what happens :-)
17
#
18
#   If enabled, the failover pool references will be written to LDIF output.
19
#   The failover configs itself will be added to the dhcpServer statements
20
#   and not to the dhcpService object (since this script uses only one and
21
#   it may be usefull to have multiple service containers in failover mode).
22
#   Further, this script does not check if primary or secondary makes sense,
23
#   it simply converts what it gets...
24
25
use Net::Domain qw(hostname hostfqdn hostdomain);
26
use Getopt::Long;
27
28
my $domain = hostdomain();           # your.domain
29
my $basedn = "dc=".$domain;
30
   $basedn =~ s/\./,dc=/g;           # dc=your,dc=domain
31
my $server = hostname();             # hostname (nodename)
32
my $dhcpcn = 'DHCP Config';          # CN of DHCP config tree
33
my $dhcpdn = "cn=$dhcpcn, $basedn";  # DHCP config tree DN
34
my $second = '';                     # secondary server DN / hostname
35
my $i_conf = '';                     # dhcp.conf file to read or stdin
36
my $o_ldif = '';                     # output ldif file name or stdout
37
my @use    = ();                     # extended flags (failover)
38
39
sub usage($;$)
40
{
41
  my $rc = shift;
42
  my $err= shift;
43
44
  print STDERR "Error: $err\n\n" if(defined $err);
45
  print STDERR <<__EOF_USAGE__;
46
usage: 
47
  $0 [options] < dhcpd.conf > dhcpd.ldif
48
49
options:
50
51
  --basedn  "dc=your,dc=domain"        ("$basedn")
52
53
  --dhcpdn  "dhcp config DN"           ("$dhcpdn")
54
55
  --server  "dhcp server name"         ("$server")
56
57
  --second  "secondary server or DN"   ("$second")
58
59
  --conf    "/path/to/dhcpd.conf"      (default is stdin)
60
  --ldif    "/path/to/output.ldif"     (default is stdout)
61
62
  --use     "extended features"        (see source comments)
63
__EOF_USAGE__
64
  exit($rc);
65
}
66
67
68
sub next_token
69
{
70
  local ($lowercase) = @_;
71
  local ($token, $newline);
72
73
  do 
74
    {
75
      if (!defined ($line) || length ($line) == 0)
76
        {
77
          $line = <>;
78
          return undef if !defined ($line);
79
          chop $line;
80
          $line_number++;
81
          $token_number = 0;
82
        }
83
84
      $line =~ s/#.*//;
85
      $line =~ s/^\s+//;
86
      $line =~ s/\s+$//;
87
    }
88
  while (length ($line) == 0);
89
90
  if (($token, $newline) = $line =~ /^(.*?)\s+(.*)/)
91
    {
92
      $line = $newline;
93
    }
94
  else
95
    {
96
      $token = $line;
97
      $line = '';
98
    }
99
  $token_number++;
100
101
  $token =~ y/[A-Z]/[a-z]/ if $lowercase;
102
103
  return ($token);
104
}
105
106
107
sub remaining_line
108
{
109
  local ($block) = shift || 0;
110
  local ($tmp, $str);
111
112
  $str = "";
113
  while (defined($tmp = next_token (0)))
114
    {
115
      $str .= ' ' if !($str eq "");
116
      $str .= $tmp;
117
      last if $tmp =~ /;\s*$/;
118
      last if($block and $tmp =~ /\s*[}{]\s*$/);
119
    }
120
121
  $str =~ s/;$//;
122
  return ($str);
123
}
124
125
126
sub
127
add_dn_to_stack
128
{
129
  local ($dn) = @_;
130
131
  $current_dn = "$dn, $current_dn";
132
}
133
134
135
sub
136
remove_dn_from_stack
137
{
138
  $current_dn =~ s/^.*?,\s*//;
139
}
140
141
142
sub
143
parse_error
144
{
145
  print "Parse error on line number $line_number at token number $token_number\n";
146
  exit (1);
147
}
148
149
150
sub
151
print_entry
152
{
153
  return if (scalar keys %curentry == 0);
154
155
  if (!defined ($curentry{'type'}))
156
    {
157
      $hostdn = "cn=$server, $basedn";
158
      print "dn: $hostdn\n";
159
      print "cn: $server\n";
160
      print "objectClass: top\n";
161
      print "objectClass: dhcpServer\n";
162
      print "dhcpServiceDN: $current_dn\n";
163
      if(grep(/FaIlOvEr/i, @use))
164
        {
165
          foreach my $fo_peer (keys %failover)
166
            {
167
              next if(scalar(@{$failover{$fo_peer}}) <= 1);
168
              print "dhcpStatements: failover peer $fo_peer { ",
169
                    join('; ', @{$failover{$fo_peer}}), "; }\n";
170
            }
171
        }
172
      print "\n";
173
174
      print "dn: $current_dn\n";
175
      print "cn: $dhcpcn\n";
176
      print "objectClass: top\n";
177
      print "objectClass: dhcpService\n";
178
      if (defined ($curentry{'options'}))
179
        {
180
          print "objectClass: dhcpOptions\n";
181
        }
182
      print "dhcpPrimaryDN: $hostdn\n";
183
      if(grep(/FaIlOvEr/i, @use) and ($second ne ''))
184
        {
185
          print "dhcpSecondaryDN: $second\n";
186
        }
187
    }
188
  elsif ($curentry{'type'} eq 'subnet')
189
    {
190
      print "dn: $current_dn\n";
191
      print "cn: " . $curentry{'ip'} . "\n";
192
      print "objectClass: top\n";
193
      print "objectClass: dhcpSubnet\n";
194
      if (defined ($curentry{'options'}))
195
        {
196
          print "objectClass: dhcpOptions\n";
197
        }
198
      
199
      print "dhcpNetMask: " . $curentry{'netmask'} . "\n";
200
      if (defined ($curentry{'ranges'}))
201
        {
202
          foreach $statement (@{$curentry{'ranges'}})
203
            {
204
              print "dhcpRange: $statement\n";
205
            }
206
        }
207
    }
208
  elsif ($curentry{'type'} eq 'shared-network')
209
    {
210
      print "dn: $current_dn\n";
211
      print "cn: " . $curentry{'descr'} . "\n";
212
      print "objectClass: top\n";
213
      print "objectClass: dhcpSharedNetwork\n";
214
      if (defined ($curentry{'options'}))
215
        {
216
          print "objectClass: dhcpOptions\n";
217
        }
218
    }
219
  elsif ($curentry{'type'} eq 'group')
220
    {
221
      print "dn: $current_dn\n";
222
      print "cn: group", $curentry{'idx'}, "\n";
223
      print "objectClass: top\n";
224
      print "objectClass: dhcpGroup\n";
225
      if (defined ($curentry{'options'}))
226
        {
227
          print "objectClass: dhcpOptions\n";
228
        }
229
    }
230
  elsif ($curentry{'type'} eq 'host')
231
    {
232
      print "dn: $current_dn\n";
233
      print "cn: " . $curentry{'host'} . "\n";
234
      print "objectClass: top\n";
235
      print "objectClass: dhcpHost\n";
236
      if (defined ($curentry{'options'}))
237
        {
238
          print "objectClass: dhcpOptions\n";
239
        }
240
241
      if (defined ($curentry{'hwaddress'}))
242
        {
243
          $curentry{'hwaddress'} =~ y/[A-Z]/[a-z]/;
244
          print "dhcpHWAddress: " . $curentry{'hwaddress'} . "\n";
245
        }
246
    }
247
  elsif ($curentry{'type'} eq 'pool')
248
    {
249
      print "dn: $current_dn\n";
250
      print "cn: pool", $curentry{'idx'}, "\n";
251
      print "objectClass: top\n";
252
      print "objectClass: dhcpPool\n";
253
      if (defined ($curentry{'options'}))
254
        {
255
          print "objectClass: dhcpOptions\n";
256
        }
257
258
      if (defined ($curentry{'ranges'}))
259
        {
260
          foreach $statement (@{$curentry{'ranges'}})
261
            {
262
              print "dhcpRange: $statement\n";
263
            }
264
        }
265
    }
266
  elsif ($curentry{'type'} eq 'class')
267
    {
268
      print "dn: $current_dn\n";
269
      print "cn: " . $curentry{'class'} . "\n";
270
      print "objectClass: top\n";
271
      print "objectClass: dhcpClass\n";
272
      if (defined ($curentry{'options'}))
273
        {
274
          print "objectClass: dhcpOptions\n";
275
        }
276
    }
277
  elsif ($curentry{'type'} eq 'subclass')
278
    {
279
      print "dn: $current_dn\n";
280
      print "cn: " . $curentry{'subclass'} . "\n";
281
      print "objectClass: top\n";
282
      print "objectClass: dhcpSubClass\n";
283
      if (defined ($curentry{'options'}))
284
        {
285
          print "objectClass: dhcpOptions\n";
286
        }
287
      print "dhcpClassData: " . $curentry{'class'} . "\n";
288
    }
289
290
  if (defined ($curentry{'statements'}))
291
    {
292
      foreach $statement (@{$curentry{'statements'}})
293
        {
294
          print "dhcpStatements: $statement\n";
295
        }
296
    }
297
298
  if (defined ($curentry{'options'}))
299
    {
300
      foreach $statement (@{$curentry{'options'}})
301
        {
302
          print "dhcpOption: $statement\n";
303
        }
304
    }
305
306
  print "\n";
307
  undef (%curentry);
308
}
309
310
311
sub parse_netmask
312
{
313
  local ($netmask) = @_;
314
  local ($i);
315
316
  if ((($a, $b, $c, $d) = $netmask =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) != 4)
317
    {
318
      parse_error ();
319
    }
320
321
  $num = (($a & 0xff) << 24) |
322
         (($b & 0xff) << 16) |
323
         (($c & 0xff) << 8) |
324
          ($d & 0xff);
325
326
  for ($i=1; $i<=32 && $num & (1 << (32 - $i)); $i++)
327
    {
328
    }
329
  $i--;
330
331
  return ($i);
332
}
333
334
335
sub parse_subnet
336
{
337
  local ($ip, $tmp, $netmask);
338
339
  print_entry () if %curentry;
340
    
341
  $ip = next_token (0);
342
  parse_error () if !defined ($ip);
343
344
  $tmp = next_token (1);
345
  parse_error () if !defined ($tmp);
346
  parse_error () if !($tmp eq 'netmask');
347
348
  $tmp = next_token (0);
349
  parse_error () if !defined ($tmp);
350
  $netmask = parse_netmask ($tmp);
351
352
  $tmp = next_token (0);
353
  parse_error () if !defined ($tmp);
354
  parse_error () if !($tmp eq '{');
355
356
  add_dn_to_stack ("cn=$ip");
357
  $curentry{'type'} = 'subnet';
358
  $curentry{'ip'} = $ip;
359
  $curentry{'netmask'} = $netmask;
360
  $cursubnet = $ip;
361
  $curcounter{$ip} = { pool  => 0, group => 0 };
362
}
363
364
365
sub parse_shared_network
366
{
367
  local ($descr, $tmp);
368
369
  print_entry () if %curentry;
370
371
  $descr = next_token (0);
372
  parse_error () if !defined ($descr);
373
374
  $tmp = next_token (0);
375
  parse_error () if !defined ($tmp);
376
  parse_error () if !($tmp eq '{');
377
378
  add_dn_to_stack ("cn=$descr");
379
  $curentry{'type'} = 'shared-network';
380
  $curentry{'descr'} = $descr;
381
}
382
383
384
sub parse_host
385
{
386
  local ($descr, $tmp);
387
388
  print_entry () if %curentry;
389
390
  $host = next_token (0);
391
  parse_error () if !defined ($host);
392
393
  $tmp = next_token (0);
394
  parse_error () if !defined ($tmp);
395
  parse_error () if !($tmp eq '{');
396
397
  add_dn_to_stack ("cn=$host");
398
  $curentry{'type'} = 'host';
399
  $curentry{'host'} = $host;
400
}
401
402
403
sub parse_group
404
{
405
  local ($descr, $tmp);
406
407
  print_entry () if %curentry;
408
409
  $tmp = next_token (0);
410
  parse_error () if !defined ($tmp);
411
  parse_error () if !($tmp eq '{');
412
413
  my $idx;
414
  if(exists($curcounter{$cursubnet})) {
415
    $idx = ++$curcounter{$cursubnet}->{'group'};
416
  } else {
417
    $idx = ++$curcounter{''}->{'group'};
418
  }
419
420
  add_dn_to_stack ("cn=group".$idx);
421
  $curentry{'type'} = 'group';
422
  $curentry{'idx'} = $idx;
423
}
424
425
426
sub parse_pool
427
{
428
  local ($descr, $tmp);
429
430
  print_entry () if %curentry;
431
432
  $tmp = next_token (0);
433
  parse_error () if !defined ($tmp);
434
  parse_error () if !($tmp eq '{');
435
436
  my $idx;
437
  if(exists($curcounter{$cursubnet})) {
438
    $idx = ++$curcounter{$cursubnet}->{'pool'};
439
  } else {
440
    $idx = ++$curcounter{''}->{'pool'};
441
  }
442
443
  add_dn_to_stack ("cn=pool".$idx);
444
  $curentry{'type'} = 'pool';
445
  $curentry{'idx'} = $idx;
446
}
447
448
449
sub parse_class
450
{
451
  local ($descr, $tmp);
452
453
  print_entry () if %curentry;
454
455
  $class = next_token (0);
456
  parse_error () if !defined ($class);
457
458
  $tmp = next_token (0);
459
  parse_error () if !defined ($tmp);
460
  parse_error () if !($tmp eq '{');
461
462
  $class =~ s/\"//g;
463
  add_dn_to_stack ("cn=$class");
464
  $curentry{'type'} = 'class';
465
  $curentry{'class'} = $class;
466
}
467
468
469
sub parse_subclass
470
{
471
  local ($descr, $tmp);
472
473
  print_entry () if %curentry;
474
475
  $class = next_token (0);
476
  parse_error () if !defined ($class);
477
478
  $subclass = next_token (0);
479
  parse_error () if !defined ($subclass);
480
481
  $tmp = next_token (0);
482
  parse_error () if !defined ($tmp);
483
  parse_error () if !($tmp eq '{');
484
485
  add_dn_to_stack ("cn=$subclass");
486
  $curentry{'type'} = 'subclass';
487
  $curentry{'class'} = $class;
488
  $curentry{'subclass'} = $subclass;
489
}
490
491
492
sub parse_hwaddress
493
{
494
  local ($type, $hw, $tmp);
495
496
  $type = next_token (1);
497
  parse_error () if !defined ($type);
498
499
  $hw = next_token (1);
500
  parse_error () if !defined ($hw);
501
  $hw =~ s/;$//;
502
503
  $curentry{'hwaddress'} = "$type $hw";
504
}
505
506
    
507
sub parse_range
508
{
509
  local ($tmp, $str);
510
511
  $str = remaining_line ();
512
513
  if (!($str eq ''))
514
    {
515
      $str =~ s/;$//;
516
      push (@{$curentry{'ranges'}}, $str);
517
    }
518
}
519
520
521
sub parse_statement
522
{
523
  local ($token) = shift;
524
  local ($str);
525
526
  if ($token eq 'option')
527
    {
528
      $str = remaining_line ();
529
      push (@{$curentry{'options'}}, $str);
530
    }
531
  elsif($token eq 'failover')
532
    {
533
      $str = remaining_line (1); # take care on block
534
      if($str =~ /[{]/)
535
        {
536
          my ($peername, @statements);
537
538
          parse_error() if($str !~ /^\s*peer\s+(.+?)\s+[{]\s*$/);
539
          parse_error() if(($peername = $1) !~ /^\"?[^\"]+\"?$/);
540
541
          #
542
          # failover config block found:
543
          # e.g. 'failover peer "some-name" {'
544
          #
545
          if(not grep(/FaIlOvEr/i, @use))
546
            {
547
              print STDERR "Warning: Failover config 'peer $peername' found!\n";
548
              print STDERR "         Skipping it, since failover disabled!\n";
549
              print STDERR "         You may try out --use=failover option.\n";
550
            }
551
552
          until($str =~ /[}]/ or $str eq "")
553
            {
554
                $str = remaining_line (1);
555
                # collect all statements, except ending '}'
556
                push(@statements, $str) if($str !~ /[}]/);
557
            }
558
          $failover{$peername} = [@statements];
559
        }
560
      else
561
        {
562
          #
563
          # pool reference to failover config is fine
564
          # e.g. 'failover peer "some-name";'
565
          #
566
          if(not grep(/FaIlOvEr/i, @use))
567
            {
568
              print STDERR "Warning: Failover reference '$str' found!\n";
569
              print STDERR "         Skipping it, since failover disabled!\n";
570
              print STDERR "         You may try out --use=failover option.\n";
571
            }
572
          else
573
            {
574
              push (@{$curentry{'statements'}}, $token. " " . $str);
575
            }
576
        }
577
    }
578
  elsif($token eq 'zone')
579
    {
580
      $str = $token;
581
      while($str !~ /}$/) {
582
        $str .= ' ' . next_token (0);
583
      }
584
      push (@{$curentry{'statements'}}, $str);
585
    }
586
  elsif($token =~ /^(authoritative)[;]*$/)
587
    {
588
      push (@{$curentry{'statements'}}, $1);
589
    }
590
  else
591
    {
592
      $str = $token . " " . remaining_line ();
593
      push (@{$curentry{'statements'}}, $str);
594
    }
595
}
596
597
598
my $ok = GetOptions(
599
    'basedn=s'      => \$basedn,
600
    'dhcpdn=s'      => \$dhcpdn,
601
    'server=s'      => \$server,
602
    'second=s'      => \$second,
603
    'conf=s'        => \$i_conf,
604
    'ldif=s'        => \$o_ldif,
605
    'use=s'         => \@use,
606
    'h|help|usage'  => sub { usage(0); },
607
);
608
609
unless($server =~ /^\w+/)
610
  {
611
    usage(1, "invalid server name '$server'");
612
  }
613
unless($basedn =~ /^\w+=[^,]+/)
614
  {
615
    usage(1, "invalid base dn '$basedn'");
616
  }
617
618
if($dhcpdn =~ /^cn=([^,]+)/i)
619
  {
620
    $dhcpcn = "$1";
621
  }
622
$second = '' if not defined $second;
623
unless($second eq '' or $second =~ /^cn=[^,]+\s*,\s*\w+=[^,]+/i)
624
  {
625
    if($second =~ /^cn=[^,]+$/i)
626
      {
627
        # relative DN 'cn=name'
628
        $second = "$second, $basedn";
629
      }
630
    elsif($second =~ /^\w+/)
631
      {
632
        # assume hostname only
633
        $second = "cn=$second, $basedn";
634
      }
635
    else
636
      {
637
        usage(1, "invalid secondary '$second'")
638
      }
639
  }
640
641
usage(1) unless($ok);
642
643
if($i_conf ne "" and -f $i_conf)
644
  {
645
    if(not open(STDIN, '<', $i_conf))
646
      {
647
        print STDERR "Error: can't open conf file '$i_conf': $!\n";
648
        exit(1);
649
      }
650
  }
651
if($o_ldif ne "")
652
  {
653
    if(-e $o_ldif)
654
      {
655
        print STDERR "Error: output ldif name '$o_ldif' already exists!\n";
656
        exit(1);
657
      }
658
    if(not open(STDOUT, '>', $o_ldif))
659
      {
660
        print STDERR "Error: can't open ldif file '$o_ldif': $!\n";
661
        exit(1);
662
      }
663
  }
664
665
666
print STDERR "Creating LDAP Configuration with the following options:\n";
667
print STDERR "\tBase DN: $basedn\n";
668
print STDERR "\tDHCP DN: $dhcpdn\n";
669
print STDERR "\tServer DN: cn=$server, $basedn\n";
670
print STDERR "\tSecondary DN: $second\n"
671
             if(grep(/FaIlOvEr/i, @use) and $second ne '');
672
print STDERR "\n";
673
674
my $token;
675
my $token_number = 0;
676
my $line_number = 0;
677
my %curentry;
678
my $cursubnet = '';
679
my %curcounter = ( '' => { pool => 0, group => 0 } );
680
681
$current_dn = "$dhcpdn";
682
$curentry{'descr'} = $dhcpcn;
683
$line = '';
684
%failover = ();
685
686
while (($token = next_token (1)))
687
  {
688
    if ($token eq '}')
689
      {
690
        print_entry () if %curentry;
691
        if($current_dn =~ /.+?,\s*${dhcpdn}$/) {
692
          # don't go below dhcpdn ...
693
          remove_dn_from_stack ();
694
        }
695
      }
696
    elsif ($token eq 'subnet')
697
      {
698
        parse_subnet ();
699
        next;
700
      }
701
    elsif ($token eq 'shared-network')
702
      {
703
        parse_shared_network ();
704
        next;
705
      }
706
    elsif ($token eq 'class')
707
      {
708
        parse_class ();
709
        next;
710
      }
711
    elsif ($token eq 'subclass')
712
      {
713
        parse_subclass ();
714
        next;
715
      }
716
    elsif ($token eq 'pool')
717
      {
718
        parse_pool ();
719
        next;
720
      }
721
    elsif ($token eq 'group')
722
      {
723
        parse_group ();
724
        next;
725
      }
726
    elsif ($token eq 'host')
727
      {
728
        parse_host ();
729
        next;
730
      }
731
    elsif ($token eq 'hardware')
732
      {
733
        parse_hwaddress ();
734
        next;
735
      }
736
    elsif ($token eq 'range')
737
      {
738
        parse_range ();
739
        next;
740
      }
741
    else
742
      {
743
        parse_statement ($token);
744
        next;
745
      }
746
  }
747
748
close(STDIN)  if($i_conf);
749
close(STDOUT) if($o_ldif);
750
751
print STDERR "Done.\n";
752
(-)dhcp-3.0.1/contrib/dhcp.schema (+343 lines)
Line 0 Link Here
1
attributetype ( 2.16.840.1.113719.1.203.4.1 
2
	NAME 'dhcpPrimaryDN' 
3
	EQUALITY distinguishedNameMatch
4
	DESC 'The DN of the dhcpServer which is the primary server for the configuration.' 
5
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
6
7
attributetype ( 2.16.840.1.113719.1.203.4.2 
8
	NAME 'dhcpSecondaryDN' 
9
	EQUALITY distinguishedNameMatch
10
	DESC 'The DN of dhcpServer(s) which provide backup service for the configuration.'
11
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
12
13
attributetype ( 2.16.840.1.113719.1.203.4.3 
14
	NAME 'dhcpStatements' 
15
	EQUALITY caseIgnoreIA5Match
16
	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.' 
17
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
18
19
attributetype ( 2.16.840.1.113719.1.203.4.4 
20
	NAME 'dhcpRange' 
21
	EQUALITY caseIgnoreIA5Match
22
	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.'
23
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
24
25
attributetype ( 2.16.840.1.113719.1.203.4.5 
26
	NAME 'dhcpPermitList' 
27
	EQUALITY caseIgnoreIA5Match
28
	DESC 'This attribute contains the permit lists associated with a pool. Each permit list is defined as a separate value.' 
29
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
30
31
attributetype ( 2.16.840.1.113719.1.203.4.6 
32
	NAME 'dhcpNetMask' 
33
	EQUALITY integerMatch
34
	DESC 'The subnet mask length for the subnet.  The mask can be easily computed from this length.' 
35
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
36
37
attributetype ( 2.16.840.1.113719.1.203.4.7 
38
	NAME 'dhcpOption' 
39
	EQUALITY caseIgnoreIA5Match
40
	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.' 
41
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
42
43
attributetype ( 2.16.840.1.113719.1.203.4.8 
44
	NAME 'dhcpClassData' 
45
	EQUALITY caseIgnoreIA5Match
46
	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.' 
47
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
48
49
attributetype ( 2.16.840.1.113719.1.203.4.9 
50
	NAME 'dhcpOptionsDN' 
51
	EQUALITY distinguishedNameMatch
52
	DESC 'The distinguished name(s) of the dhcpOption objects containing the configuration options provided by the server.' 
53
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
54
55
attributetype ( 2.16.840.1.113719.1.203.4.10 
56
	NAME 'dhcpHostDN' 
57
	EQUALITY distinguishedNameMatch
58
	DESC 'the distinguished name(s) of the dhcpHost objects.' 
59
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) 
60
61
attributetype ( 2.16.840.1.113719.1.203.4.11 
62
	NAME 'dhcpPoolDN' 
63
	EQUALITY distinguishedNameMatch
64
	DESC 'The distinguished name(s) of pools.' 
65
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
66
67
attributetype ( 2.16.840.1.113719.1.203.4.12 
68
	NAME 'dhcpGroupDN' 
69
	EQUALITY distinguishedNameMatch
70
	DESC 'The distinguished name(s)   of the groups.' 
71
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
72
73
attributetype ( 2.16.840.1.113719.1.203.4.13 
74
	NAME 'dhcpSubnetDN' 
75
	EQUALITY distinguishedNameMatch
76
	DESC 'The distinguished name(s) of the subnets.' 
77
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
78
79
attributetype ( 2.16.840.1.113719.1.203.4.14 
80
	NAME 'dhcpLeaseDN' 
81
	EQUALITY distinguishedNameMatch
82
	DESC 'The distinguished name of a client address.' 
83
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE)
84
85
attributetype ( 2.16.840.1.113719.1.203.4.15 NAME 'dhcpLeasesDN' 
86
	DESC 'The distinguished name(s) client addresses.' 
87
	EQUALITY distinguishedNameMatch
88
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
89
90
attributetype ( 2.16.840.1.113719.1.203.4.16 
91
	NAME 'dhcpClassesDN' 
92
	EQUALITY distinguishedNameMatch
93
	DESC 'The distinguished name(s) of a class(es) in a subclass.' 
94
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
95
96
attributetype ( 2.16.840.1.113719.1.203.4.17 
97
	NAME 'dhcpSubclassesDN' 
98
	EQUALITY distinguishedNameMatch
99
	DESC 'The distinguished name(s) of subclass(es).' 
100
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
101
102
attributetype ( 2.16.840.1.113719.1.203.4.18 
103
	NAME 'dhcpSharedNetworkDN' 
104
	EQUALITY distinguishedNameMatch
105
	DESC 'The distinguished name(s) of sharedNetworks.' 
106
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
107
108
attributetype ( 2.16.840.1.113719.1.203.4.19 
109
	NAME 'dhcpServiceDN' 
110
	EQUALITY distinguishedNameMatch
111
	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.' 
112
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
113
114
attributetype ( 2.16.840.1.113719.1.203.4.20 
115
	NAME 'dhcpVersion' DESC 'The version attribute of this object.' 
116
	EQUALITY caseIgnoreIA5Match
117
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
118
119
attributetype ( 2.16.840.1.113719.1.203.4.21 
120
	NAME 'dhcpImplementation' 
121
	EQUALITY caseIgnoreIA5Match
122
	DESC 'Description of the DHCP Server implementation e.g. DHCP Servers vendor.' 
123
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
124
125
attributetype ( 2.16.840.1.113719.1.203.4.22 
126
	NAME 'dhcpAddressState' 
127
	EQUALITY caseIgnoreIA5Match
128
	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".'
129
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
130
131
attributetype ( 2.16.840.1.113719.1.203.4.23 
132
	NAME 'dhcpExpirationTime' 
133
	EQUALITY generalizedTimeMatch 
134
	DESC 'This is the time the current lease for an address expires.' 
135
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
136
137
attributetype ( 2.16.840.1.113719.1.203.4.24 
138
	NAME 'dhcpStartTimeOfState' 
139
	EQUALITY generalizedTimeMatch 
140
	DESC 'This is the time of the last state change for a leased address.' 
141
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
142
143
attributetype ( 2.16.840.1.113719.1.203.4.25 
144
	NAME 'dhcpLastTransactionTime' 
145
	EQUALITY generalizedTimeMatch 
146
	DESC 'This is the last time a valid DHCP packet was received from the client.'
147
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
148
149
attributetype ( 2.16.840.1.113719.1.203.4.26 
150
	NAME 'dhcpBootpFlag' 
151
	EQUALITY booleanMatch 
152
	DESC 'This indicates whether the address was assigned via BOOTP.' 
153
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
154
155
attributetype ( 2.16.840.1.113719.1.203.4.27 
156
	NAME 'dhcpDomainName' 
157
	EQUALITY caseIgnoreIA5Match
158
	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 ".".' 
159
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
160
161
attributetype ( 2.16.840.1.113719.1.203.4.28 
162
	NAME 'dhcpDnsStatus' 
163
	EQUALITY integerMatch
164
	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.'
165
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
166
167
attributetype ( 2.16.840.1.113719.1.203.4.29 
168
	NAME 'dhcpRequestedHostName' 
169
	EQUALITY caseIgnoreIA5Match
170
	DESC 'This is the hostname that was requested by the client.' 
171
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
172
173
attributetype ( 2.16.840.1.113719.1.203.4.30 
174
	NAME 'dhcpAssignedHostName' 
175
	EQUALITY caseIgnoreIA5Match
176
	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.' 
177
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
178
179
attributetype ( 2.16.840.1.113719.1.203.4.31 
180
	NAME 'dhcpReservedForClient' 
181
	EQUALITY distinguishedNameMatch
182
	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.'
183
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
184
185
attributetype ( 2.16.840.1.113719.1.203.4.32 
186
	NAME 'dhcpAssignedToClient' 
187
	EQUALITY distinguishedNameMatch
188
	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.' 
189
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
190
191
attributetype ( 2.16.840.1.113719.1.203.4.33 
192
	NAME 'dhcpRelayAgentInfo' 
193
	EQUALITY octetStringMatch
194
	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.' 
195
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
196
197
attributetype ( 2.16.840.1.113719.1.203.4.34 
198
	NAME 'dhcpHWAddress' 
199
	EQUALITY octetStringMatch
200
	DESC 'The clients hardware address that requested this IP address.' 
201
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
202
203
attributetype ( 2.16.840.1.113719.1.203.4.35 
204
	NAME 'dhcpHashBucketAssignment' 
205
	EQUALITY octetStringMatch
206
	DESC 'HashBucketAssignment bit map for the DHCP Server, as defined in DHC Load Balancing Algorithm [RFC 3074].' 
207
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
208
209
attributetype ( 2.16.840.1.113719.1.203.4.36 
210
	NAME 'dhcpDelayedServiceParameter' 
211
	EQUALITY integerMatch
212
	DESC 'Delay in seconds corresponding to Delayed Service Parameter configuration, as defined in  DHC Load Balancing Algorithm [RFC 3074]. '
213
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
214
215
attributetype ( 2.16.840.1.113719.1.203.4.37 
216
	NAME 'dhcpMaxClientLeadTime' 
217
	EQUALITY integerMatch
218
	DESC 'Maximum Client Lead Time configuration in seconds, as defined in DHCP Failover Protocol [FAILOVR]' 
219
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
220
221
attributetype ( 2.16.840.1.113719.1.203.4.38 
222
	NAME 'dhcpFailOverEndpointState' 
223
	EQUALITY caseIgnoreIA5Match
224
	DESC 'Server (Failover Endpoint) state, as defined in DHCP Failover Protocol [FAILOVR]' 
225
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
226
227
attributetype ( 2.16.840.1.113719.1.203.4.39 
228
	NAME 'dhcpErrorLog' 
229
	EQUALITY caseIgnoreIA5Match
230
	DESC 'Generic error log attribute that allows logging error conditions within a dhcpService or a dhcpSubnet, like no IP addresses available for lease.'
231
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
232
233
# Classes
234
235
objectclass ( 2.16.840.1.113719.1.203.6.1 
236
	NAME 'dhcpService' 
237
	DESC 'Service object that represents the actual DHCP Service configuration. This is a container object.' 
238
	SUP top 
239
	MUST (cn $ dhcpPrimaryDN) 
240
	MAY ( dhcpSecondaryDN $ dhcpSharedNetworkDN $ dhcpSubnetDN $ 
241
		dhcpGroupDN $ dhcpHostDN $  dhcpClassesDN $ dhcpOptionsDN $ 
242
		dhcpStatements ) )
243
244
objectclass ( 2.16.840.1.113719.1.203.6.2 
245
	NAME 'dhcpSharedNetwork' 
246
	DESC 'This stores configuration information for a shared network.' 
247
	SUP top 
248
	MUST cn 
249
	MAY ( dhcpSubnetDN $ dhcpPoolDN $ dhcpOptionsDN $ dhcpStatements) 
250
	X-NDS_CONTAINMENT ('dhcpService' ) )
251
252
objectclass ( 2.16.840.1.113719.1.203.6.3 
253
	NAME 'dhcpSubnet' 
254
	DESC 'This class defines a subnet. This is a container object.' 
255
	SUP top 
256
	MUST ( cn $ dhcpNetMask ) 
257
	MAY ( dhcpRange $ dhcpPoolDN $ dhcpGroupDN $ dhcpHostDN $ 
258
		dhcpClassesDN $ dhcpLeasesDN $ dhcpOptionsDN $ dhcpStatements) 
259
	X-NDS_CONTAINMENT ('dhcpService' 'dhcpSharedNetwork') )
260
261
objectclass ( 2.16.840.1.113719.1.203.6.4 
262
	NAME 'dhcpPool' 
263
	DESC 'This stores configuration information about a pool.' 
264
	SUP top 
265
	MUST ( cn $ dhcpRange ) 
266
	MAY (dhcpClassesDN $ dhcpPermitList $ dhcpLeasesDN $ dhcpOptionsDN $ 
267
		dhcpStatements) 
268
	X-NDS_CONTAINMENT ('dhcpSubnet' 'dhcpSharedNetwork') )
269
270
objectclass ( 2.16.840.1.113719.1.203.6.5 
271
	NAME 'dhcpGroup' 
272
	DESC 'Group object that lists host DNs and parameters. This is a container object.' 
273
	SUP top 
274
	MUST cn 
275
	MAY ( dhcpHostDN $ dhcpOptionsDN $ dhcpStatements ) 
276
	X-NDS_CONTAINMENT ('dhcpSubnet' 'dhcpService' ) )
277
278
objectclass ( 2.16.840.1.113719.1.203.6.6 
279
	NAME 'dhcpHost' 
280
	DESC 'This represents information about a particular client' 
281
	SUP top 
282
	MUST cn 
283
	MAY  (dhcpLeaseDN $ dhcpHWAddress $ dhcpOptionsDN $ dhcpStatements) 
284
	X-NDS_CONTAINMENT ('dhcpService' 'dhcpSubnet' 'dhcpGroup') )
285
286
objectclass ( 2.16.840.1.113719.1.203.6.7 
287
	NAME 'dhcpClass' 
288
	DESC 'Represents information about a collection of related clients.' 
289
	SUP top 
290
	MUST cn 
291
	MAY (dhcpSubClassesDN $ dhcpOptionsDN $ dhcpStatements) 
292
	X-NDS_CONTAINMENT ('dhcpService' 'dhcpSubnet' ) )
293
294
objectclass ( 2.16.840.1.113719.1.203.6.8 
295
	NAME 'dhcpSubClass' 
296
	DESC 'Represents information about a collection of related classes.' 
297
	SUP top 
298
	MUST cn 
299
	MAY (dhcpClassData $ dhcpOptionsDN $ dhcpStatements) 
300
	X-NDS_CONTAINMENT 'dhcpClass' ) 
301
302
objectclass ( 2.16.840.1.113719.1.203.6.9 
303
	NAME 'dhcpOptions' 
304
	DESC 'Represents information about a collection of options defined.' 
305
	SUP top AUXILIARY
306
	MUST cn 
307
	MAY ( dhcpOption ) 
308
	X-NDS_CONTAINMENT  ('dhcpService' 'dhcpSharedNetwork' 'dhcpSubnet' 
309
			'dhcpPool' 'dhcpGroup' 'dhcpHost' 'dhcpClass' ) )
310
311
objectclass ( 2.16.840.1.113719.1.203.6.10 
312
	NAME 'dhcpLeases' 
313
	DESC 'This class represents an IP Address, which may or may not have been leased.' 
314
	SUP top 
315
	MUST ( cn $ dhcpAddressState ) 
316
	MAY ( dhcpExpirationTime $ dhcpStartTimeOfState $ 
317
		dhcpLastTransactionTime $ dhcpBootpFlag $ dhcpDomainName $ 
318
		dhcpDnsStatus $ dhcpRequestedHostName $ dhcpAssignedHostName $ 
319
		dhcpReservedForClient $ dhcpAssignedToClient $ 
320
		dhcpRelayAgentInfo $ dhcpHWAddress ) 
321
	X-NDS_CONTAINMENT ( 'dhcpService' 'dhcpSubnet' 'dhcpPool') )
322
323
objectclass ( 2.16.840.1.113719.1.203.6.11 
324
	NAME 'dhcpLog' 
325
	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.' 
326
	SUP top 
327
	MUST ( cn ) 
328
	MAY ( dhcpAddressState $ dhcpExpirationTime $ dhcpStartTimeOfState $ 
329
		dhcpLastTransactionTime $ dhcpBootpFlag $ dhcpDomainName $ 
330
		dhcpDnsStatus $ dhcpRequestedHostName $ dhcpAssignedHostName $ 
331
		dhcpReservedForClient $ dhcpAssignedToClient $ 
332
		dhcpRelayAgentInfo $ dhcpHWAddress $ dhcpErrorLog) 
333
	X-NDS_CONTAINMENT ('dhcpLeases' 'dhcpPool' 'dhcpSubnet' 
334
					'dhcpSharedNetwork' 'dhcpService' ) )
335
336
objectclass ( 2.16.840.1.113719.1.203.6.12 
337
	NAME 'dhcpServer' 
338
	DESC 'DHCP Server Object' 
339
	SUP top 
340
	MUST (cn $ dhcpServiceDN) 
341
	MAY (dhcpVersion $ dhcpImplementation $ dhcpHashBucketAssignment $ dhcpDelayedServiceParameter $ dhcpMaxClientLeadTime $ dhcpFailOverEndpointState $ dhcpStatements)
342
	X-NDS_CONTAINMENT ('o' 'ou' 'dc') )
343
(-)dhcp-3.0.1/debian/changelog (+25 lines)
Line 0 Link Here
1
dhcp3-server-ldap (3.0.1rc14-1) unstable; urgency=low
2
3
  * See ChangeLog-LDAP for changes in this release
4
5
 -- Brian Masney <masneyb@gftp.org>  Tue, 22 Jun 2004 15:29:07 -0400
6
7
dhcp3-server-ldap (3.0.1rc13-1) unstable; urgency=low
8
9
  * See ChangeLog-LDAP for changes in this release
10
11
 -- Brian Masney <masneyb@gftp.org>  Wed, 05 May 2004 07:20:13 -0400
12
13
dhcp3-server-ldap (3.0.1rc12-1) unstable; urgency=low
14
15
  * Updated patch to work against ISC DHCPD 3.0.1rc12
16
17
 -- Brian Masney <masneyb@gftp.org>  Mon, 08 Sep 2003 16:34:00 -0400
18
19
dhcp3-server-ldap (3.0.1rc11-2) unstable; urgency=low
20
21
  * Added these Debian files. They are mostly from the existing dhcp3-server
22
    package in Debian.
23
24
 -- Brian Masney <masneyb@gftp.org>  Mon, 04 Aug 2003 13:34:00 -0400
25
(-)dhcp-3.0.1/debian/control (+12 lines)
Line 0 Link Here
1
Source: dhcp3-server-ldap
2
Section: net
3
Priority: optional
4
Maintainer: Brian Masney <masneyb@gftp.org>
5
Build-Depends: debhelper (>= 2.1.18), dpkg-dev (>= 1.7.0), groff, libldap2-dev
6
Standards-Version: 2.4.0.0
7
8
Package: dhcp3-server-ldap
9
Architecture: any
10
Depends: ${shlibs:Depends}, debconf, debianutils (>= 1.7), dhcp3-server (>= 3.0+3.0.1rc9)
11
Conflicts: dhcp, dhcp3-ldap-ntelos
12
Description: This is the DHCP server with LDAP patches applied to it
(-)dhcp-3.0.1/debian/copyright (+30 lines)
Line 0 Link Here
1
/*
2
 * Copyright (c) 1996, 1997 The Internet Software Consortium.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 *
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 * 3. Neither the name of The Internet Software Consortium nor the names of its
15
 *    contributors may be used to endorse or promote products derived
16
 *    from this software without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
19
 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
20
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
22
 * THE INTERNET SOFTWARE CONSORTIUM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29
 * OF THE POSSIBILITY OF SUCH DAMAGE.
30
 */
(-)dhcp-3.0.1/debian/dhcp3-server-ldap.files (+1 lines)
Line 0 Link Here
1
usr/sbin/dhcpd3
(-)dhcp-3.0.1/debian/dhcp3-server-ldap.postinst (+13 lines)
Line 0 Link Here
1
#!/bin/sh
2
3
set -e 
4
5
# Removes the left over diversions of the old package
6
7
if [ "$1" = remove -o "$1" = upgrade ]; then
8
	for v in `list_versions`; do
9
	        dpkg-divert --package dhcp3-server-ldap --remove \
10
			--rename --divert /usr/sbin/dhcpd3-noldap \
11
			/usr/sbin/dhcpd3
12
	done
13
fi
(-)dhcp-3.0.1/debian/dhcp3-server-ldap.postrm (+8 lines)
Line 0 Link Here
1
#!/bin/sh
2
3
set -e 
4
5
if [ "$1" = remove ]; then
6
	dpkg-divert --package dhcp3-server-ldap --remove --rename \
7
		--divert /usr/sbin/dhcpd3-noldap /usr/sbin/dhcpd3
8
fi
(-)dhcp-3.0.1/debian/dhcp3-server-ldap.preinst (+14 lines)
Line 0 Link Here
1
#!/bin/sh
2
3
set -e 
4
5
if [ "$1" = install -o "$1" = upgrade ]; then
6
	if dpkg-divert --list /usr/sbin/dhcpd3 \
7
		| grep -q "by dhcp3-server-ldap";
8
	then
9
		exit 0
10
	fi
11
		
12
	dpkg-divert --package dhcp3-server-ldap --add --rename \
13
		--divert /usr/sbin/dhcpd3-noldap /usr/sbin/dhcpd3
14
fi
(-)dhcp-3.0.1/debian/dhcp3-server-ldap.substvars (+1 lines)
Line 0 Link Here
1
shlibs:Depends=libc6 (>= 2.3.2.ds1-4), libldap2 (>= 2.1.17-1)
(-)dhcp-3.0.1/debian/dirs (+1 lines)
Line 0 Link Here
1
usr/sbin
(-)dhcp-3.0.1/debian/files (+1 lines)
Line 0 Link Here
1
dhcp3-server-ldap_3.0.1rc13-1_i386.deb net optional
(-)dhcp-3.0.1/debian/rules (+87 lines)
Line 0 Link Here
1
#!/usr/bin/make -f
2
# Made with the iad of dh_make, by Craig Small
3
# Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess.
4
# Also some stuff taken from debmake scripts, by Cristopt Lameter.
5
6
# Uncomment this to turn on verbose mode.
7
#export DH_VERBOSE=1
8
9
export DH_COMPAT=3
10
11
DESTDIR = `pwd`/debian/tmp
12
13
IVARS = DESTDIR=$(DESTDIR)
14
15
BVARS = PREDEFINES='-D_PATH_DHCPD_DB=\"/var/lib/dhcp3/dhcpd.leases\" \
16
	-D_PATH_DHCLIENT_DB=\"/var/lib/dhcp3/dhclient.leases\" \
17
	-D_PATH_DHCLIENT_SCRIPT=\"/etc/dhcp3/dhclient-script\" \
18
	-D_PATH_DHCPD_CONF=\"/etc/dhcp3/dhcpd.conf\" \
19
        -D_PATH_DHCLIENT_CONF=\"/etc/dhcp3/dhclient.conf\"'
20
21
build: build-stamp
22
build-stamp:
23
	dh_testdir
24
25
	./configure
26
	$(MAKE) $(BVARS)
27
28
	touch build-stamp
29
30
clean: 
31
	dh_testdir
32
	rm -f build-stamp install-stamp
33
34
	# Add here commands to clean up after the build process.
35
	-$(MAKE) distclean
36
37
	# Remove leftover junk...
38
	rm -Rf work.linux-2.2/
39
40
	dh_clean
41
42
install: install-stamp
43
install-stamp: build-stamp
44
	dh_testdir
45
	dh_testroot
46
	dh_clean -k
47
	dh_installdirs
48
49
	# Add here commands to install the package into debian/tmp.
50
	$(MAKE) install $(IVARS)
51
52
	mv $(DESTDIR)/usr/sbin/dhcpd $(DESTDIR)/usr/sbin/dhcpd3
53
54
	dh_movefiles
55
56
	# Remove unwanted directories that dh_movefiles leaves around
57
	rmdir $(DESTDIR)/etc
58
	rm -Rf $(DESTDIR)/sbin/
59
	rm -Rf $(DESTDIR)/usr/bin/
60
	rm -Rf $(DESTDIR)/usr/include/
61
	rm -Rf $(DESTDIR)/usr/lib/
62
	rm -Rf $(DESTDIR)/usr/local/
63
	rm -Rf $(DESTDIR)/usr/man/
64
	rm -Rf $(DESTDIR)/var/
65
	rm -f $(DESTDIR)/usr/sbin/dhcrelay
66
67
	touch install-stamp
68
69
# Build architecture-dependent files here (this package does not contain
70
#	architecture-independent files).
71
binary-arch: build install
72
	dh_testdir -a
73
	dh_testroot -a
74
	dh_strip -a
75
	dh_compress -a
76
	dh_fixperms -a
77
	dh_installdeb -a
78
	dh_shlibdeps -a
79
	dh_gencontrol -a
80
	dh_md5sums -a
81
	dh_builddeb -a
82
83
source diff:                                                                  
84
	@echo >&2 'source and diff are obsolete - use dpkg-source -b'; false
85
86
binary: binary-arch
87
.PHONY: build clean binary-indep binary-arch binary
(-)dhcp-3.0.1/doc/draft-ietf-dhc-ldap-schema-01.txt (+1089 lines)
Line 0 Link Here
1
2
3
4
5
6
Network Working Group                                  M. Meredith,
7
Internet Draft                                         V. Nanjundaswamy,
8
Document: <draft-ietf-dhc-ldap-schema-00.txt>          M. Hinckley
9
Category: Proposed Standard                            Novell Inc.
10
Expires: 15th December 2001                            16th June 2001
11
12
13
                          LDAP Schema for DHCP
14
15
Status of this Memo
16
17
This document is an Internet-Draft and is in full conformance with all
18
provisions of Section 10 of RFC2026 [ ].
19
20
Internet-Drafts are working documents of the Internet Engineering Task
21
Force (IETF), its areas, and its working groups.  Note that other groups
22
may also distribute working documents as Internet-Drafts. Internet-
23
Drafts are draft documents valid for a maximum of six months and may be
24
updated, replaced, or obsolete by other documents at any time.  It is
25
inappropriate to use Internet-Drafts as reference material or to cite
26
them other than as "work in progress."  The list of current Internet-
27
Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt The
28
list of Internet-Draft Shadow Directories can be accessed at
29
http://www.ietf.org/shadow.html.
30
31
1. Abstract
32
33
This document defines a schema for representing DHCP configuration in an
34
LDAP directory. It can be used to represent the DHCP Service
35
configuration(s) for an entire enterprise network, a subset of the
36
network, or even a single server. Representing DHCP configuration in an
37
LDAP directory enables centralized management of DHCP services offered
38
by one or more DHCP Servers within the enterprise.
39
40
2. Conventions used in this document
41
42
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
43
"SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and "OPTIONAL" in this
44
document are to be interpreted as described in RFC-2119 [ ].
45
46
In places where different sets of terminology are commonly used to
47
represent similar DHCP concepts, this schema uses the terminology of the
48
Internet Software Consortium's DHCP server reference implementation.
49
For more information see www.isc.org.
50
51
3. Design Considerations
52
53
The DHCP LDAP schema is designed to be a simple multi-server schema. The
54
55
56
57
M. Meredith et al.        Expires December 2001                 [Page 1]
58
59
60
61
62
63
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
64
65
66
intent of this schema is to provide a basic framework for representing
67
the most common elements used in the configuration of DHCP Server.  This
68
should allow other network services to obtain and use basic DHCP
69
configuration information in a server-independent but knowledgeable way.
70
71
It is expected that some implementations may need to extend the schema
72
objects, in order to implement all of their features or needs. It is
73
recommended that you use the schema defined in this draft to represent
74
DHCP configuration information in an LDAP directory.  Conforming to a
75
standard schema improves interoperability between DHCP implementations
76
from different vendors.
77
78
Some implementations may choose not to support all of the objects
79
defined here.
80
81
Two decisions are explicitly left up to each implementation:
82
83
First, implementations may choose not to store the lease information in
84
the directory, so those objects would not be used.
85
86
Second, implementations may choose not to implement the auditing
87
information.
88
89
It is up to the implementation to determine if the data in the directory
90
is considered "authoritative", or if it is simply a copy of data from an
91
authoritative source. Validity of the information if used as a copy is
92
to be ensured by the implementation.
93
94
Primarily two types of applications will use the information in this
95
schema: 1. DHCP servers (for loading their configuration) 2. Management
96
Interfaces (for defining/editing configurations).
97
98
The schema should be efficient for the needs of both types of
99
applications.  The schema is designed to allow objects managed by DHCP
100
(such as computers, subnets, etc) to be present anywhere in a directory
101
hierarchy (to allow those objects to be placed in the directory for
102
managing administrative control and access to the objects).
103
104
The schema uses a few naming conventions - all object classes and
105
attributes are prefixed with "dhcp" to decrease the chance that object
106
classes and attributes will have the same name.  The schema also uses
107
standard naming attributes ("cn", "ou", etc) for all objects.
108
109
4. Common DHCP Configuration Attributes
110
111
Although DHCP manages several different types of objects, the
112
configuration of those objects is often similar.  Consequently, most of
113
these objects have a common set of attributes, which are defined below.
114
115
116
117
M. Meredith et al.        Expires December 2001                 [Page 2]
118
119
120
121
122
123
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
124
125
126
4.1. Attributes Definitions
127
128
The schema definitions listed below are for readability.  The LDIF
129
layout for this schema will follow in section 8.
130
131
Name: dhcpPrimaryDN Description: The Distinguished Name of the
132
dhcpServer object, which is the primary server for the configuration.
133
Syntax: DN Flags: SINGLE-VALUE
134
135
Named: dhcpSecondaryDN Description: The Distinguished Name(s) of the
136
dhcpServer object(s), which are secondary servers for the configuration.
137
Syntax: DN
138
139
Name: dhcpStatements Description: Flexible storage for representing any
140
specific data depending on the object to which it is attached. Examples
141
include conditional statements, Server parameters, etc.  This also
142
serves as a 'catch-all' attribute that allows the standard to evolve
143
without needing to update the schema.  Syntax: IA5String
144
145
Name: dhcpRange Description: The starting and ending IP Addresses in the
146
range (inclusive), separated by a hyphen; if the range only contains one
147
address, then just the address can be specified with no hyphen.  Each
148
range is defined as a separate value.  Syntax: IA5String
149
150
Name: dhcpPermitList Description: This attribute contains the permit
151
lists associated with a pool. Each permit list is defined as a separate
152
value.  Syntax: IA5String
153
154
Name: dhcpNetMask Description: The subnet mask length for the subnet.
155
The mask can be easily computed from this length.  Syntax: Integer
156
Flags: SINGLE-VALUE
157
158
Name: dhcpOption Description: Encoded option values to be sent to
159
clients.  Each value represents a single option and contains (OptionTag,
160
Length, OptionData) encoded in the format used by DHCP.  For more
161
information see [DHCPOPT].  Syntax: OctetString
162
163
Name: dhcpClassData Description: Encoded text string or list of bytes
164
expressed in hexadecimal, separated by colons. Clients match subclasses
165
based on matching the class data with the results of a 'match' or 'spawn
166
with' statement in the class name declarations.  Syntax: IA5String
167
Flags: SINGLE-VALUE
168
169
Name: dhcpSubclassesDN Description: List of subclasses, these are the
170
actual DN of each subclass object.  Syntax: DN
171
172
Name: dhcpClassesDN Description: List of classes, these are the actual
173
DN of each class object.  Syntax: DN
174
175
176
177
M. Meredith et al.        Expires December 2001                 [Page 3]
178
179
180
181
182
183
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
184
185
186
Name: dhcpSubnetDN Description: List of subnets, these are the actual DN
187
of each subnet object.  Syntax: DN
188
189
Name: dhcpPoolDN Description: List of pools, these are the actual DN of
190
each Pool object.  Syntax: DN
191
192
Name: dhcpOptionsDN Description: List of options, these are the actual
193
DN of each Options object.  Syntax: DN
194
195
Name: dhcpHostDN Description: List of hosts, these are the actual DN of
196
each host object.  Syntax: DN
197
198
Name: dhcpSharedNetworkDN Description: List of shared networks, these
199
are the actual DN of each shared network object.  Syntax: DN
200
201
Name: dhcpGroupDN Description: List of groups, these are the actual DN
202
of each Group object.  Syntax: DN
203
204
Name: dhcpLeaseDN Description: Single Lease DN. A dhcpHost configuration
205
uses this attribute to identify a static IP address assignment.  Syntax:
206
DN Flags: SINGLE-VALUE
207
208
Name: dhcpLeasesDN Description: List of leases, these are the actual DN
209
of each lease object.  Syntax: DN
210
211
Name: dhcpServiceDN Description: The DN of dhcpService object(s)which
212
contain the configuration information. Each dhcpServer object has this
213
attribute identifying the DHCP configuration(s) that the server is
214
associated with.  Syntax: DN
215
216
Name: dhcpHWAddress Description: The hardware address of the client
217
associated with a lease Syntax: OctetString Flags: SINGLE-VALUE
218
219
Name: dhcpVersion Description: This is the version identified for the
220
object that this attribute is part of. In case of the dhcpServer object,
221
this represents the DHCP software version.  Syntax: IA5String Flags:
222
SINGLE-VALUE
223
224
Name: dhcpImplementation Description: DHCP Server implementation
225
description e.g. DHCP Vendor information.  Syntax: IA5String Flags:
226
SINGLE-VALUE
227
228
Name: dhcpHashBucketAssignment Description: HashBucketAssignment bit map
229
for the DHCP Server, as defined in DHC Load Balancing Algorithm [RFC
230
3074].  Syntax: Octet String Flags: SINGLE-VALUE
231
232
Name: dhcpDelayedServiceParameter Description: Delay in seconds
233
corresponding to Delayed Service Parameter configuration, as defined in
234
235
236
237
M. Meredith et al.        Expires December 2001                 [Page 4]
238
239
240
241
242
243
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
244
245
246
DHC Load Balancing Algorithm [RFC 3074].  Syntax: Integer Flags: SINGLE-
247
VALUE
248
249
Name: dhcpMaxClientLeadTime Description: Maximum Client Lead Time
250
configuration in seconds, as defined in DHCP Failover Protocol [FAILOVR]
251
Syntax: Integer Flags: SINGLE-VALUE
252
253
Name: dhcpFailOverEndpointState Description: Server (Failover Endpoint)
254
state, as defined in DHCP Failover Protocol [FAILOVR] Syntax: IA5String
255
Flags: SINGLE-VALUE
256
257
5. Configurations and Services
258
259
The schema definitions below are for readability the LDIF layout for
260
this schema will follow in section 8.
261
262
The DHC working group is currently considering several proposals for
263
fail-over and redundancy of DHCP servers.  These may require sharing of
264
configuration information between servers.  This schema provides a
265
generalized mechanism for supporting any of these proposals, by
266
separating the definition of a server from the definition of
267
configuration service provided by the server.
268
269
Separating the DHCP Server (dhcpServer) and the DHCP Configuration
270
(dhcpService) representations allows a configuration service to be
271
provided by one or more servers. Similarly, a server may provide one or
272
more configurations. The schema allows a server to be configured as
273
either a primary or secondary provider of a DHCP configuration.
274
275
Configurations are also defined so that one configuration can include
276
some of the objects that are defined in another configuration.  This
277
allows for sharing and/or a hierarchy of related configuration items.
278
279
Name: dhcpService Description:  Service object that represents the
280
actual DHCP Service configuration. This will be a container with the
281
following attributes.  Must: cn, dhcpPrimaryDN May: dhcpSecondaryDN,
282
dhcpSharedNetworkDN, dhcpSubnetDN, dhcpGroupDN, dhcpHostDN,
283
dhcpClassesDN, dhcpOptionsDN, dhcpStatements
284
285
The following objects could exist inside the dhcpService container:
286
dhcpSharedNetwork, dhcpSubnet, dhcpGroup, dhcpHost, dhcpClass,
287
dhcpOptions, dhcpLog
288
289
Name: dhcpServer Description:  Server object that the DHCP server will
290
login as.  The configuration information is in the dhcpService container
291
that the dhcpServiceDN points to.  Must: cn, dhcpServiceDN May:
292
dhcpVersion, dhcpImplementation, dhcpHashBucketAssignment,
293
dhcpDelayedServiceParameter, dhcpMaxClientLeadTime, 
294
295
296
297
M. Meredith et al.        Expires December 2001                 [Page 5]
298
299
300
301
302
303
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
304
dhcpFailOverEndpointState, dhcpStatements
305
306
5.1. DHCP Declaration related classes:
307
308
Name: dhcpSharedNetwork Description: Shared Network class will list what
309
pools and subnets are in this network.
310
311
This will be a container with the following attributes.  Must: cn May:
312
dhcpSubnetDN, dhcpPoolDN, dhcpOptionsDN, dhcpStatements
313
314
The following objects can exist within a dhcpSharedNetwork container:
315
dhcpSubnet, dhcpPool, dhcpOptions, dhcpLog
316
317
Name: dhcpSubnet Description: Subnet object will include configuration
318
information associated with a subnet, including a range and a net mask.
319
320
This will be a container with the following attributes.  Must: cn
321
(Subnet address), dhcpNetMask May: dhcpRange, dhcpPoolDN, dhcpGroupDN,
322
dhcpHostDN, dhcpClassesDN, dhcpLeasesDN, dhcpOptionsDN, dhcpStatements
323
324
The following objects can exist within a dhcpSubnet container: dhcpPool,
325
dhcpGroup, dhcpHost, dhcpClass, dhcpOptions, dhcpLease, dhcpLog
326
327
Name: dhcpGroup Description: Group object will have configuration
328
information associated with a group.
329
330
This will be a container with the following attributes.  Must: cn May:
331
dhcpHostDN, dhcpOptionsDN, dhcpStatements
332
333
The following objects can exist within a dhcpGroup container: dhcpHost,
334
dhcpOptions
335
336
Name: dhcpHost Description: The host object includes DHCP host
337
declarations to assign a static IP address or declare the client as
338
known or specify statements for a specific client.  Must: cn May:
339
dhcpLeaseDN, dhcpHWAddress, dhcpOptionsDN, dhcpStatements
340
341
The following objects can exist within a dhcpHost container: dhcpLease,
342
dhcpOptions
343
344
Name: dhcpOptions Description: The options class is for option space
345
declarations, it contains a list of options.  Must: cn, dhcpOption
346
347
Name: dhcpClass Description: This is a class to group clients together
348
based on matching rules.
349
350
This will be a container with the following attributes.  Must: cn May:
351
dhcpSubClassesDN, dhcpOptionsDN, dhcpStatements
352
353
The following object can exist within a dhcpClass container:
354
dhcpSubclass, dhcpOptions
355
356
357
358
M. Meredith et al.        Expires December 2001                 [Page 6]
359
360
361
362
363
364
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
365
366
367
Name: dhcpSubClass Description: This includes configuration information
368
for a subclass associated with a class. The dhcpSubClass object will
369
always be contained within the corresponding class container object.
370
Must: cn May:  dhcpClassData, dhcpOptionsDN, dhcpStatements
371
372
Name: dhcpPool Description: This contains configuration for a pool that
373
will have the range of addresses, permit lists and point to classes and
374
leases that are members of this pool.
375
376
This will be a container that could be contained by dhcpSubnet or a
377
dhcpSharedNetwork.  Must: cn, dhcpRange May: dhcpClassesDN,
378
dhcpPermitList, dhcpLeasesDN, dhcpOptionsDN, dhcpStatements
379
380
The following objects can exist within a dhcpPool container: dhcpClass,
381
dhcpOptions, dhcpLease, dhcpLog
382
383
6. Tracking Address Assignments
384
385
The behavior of a DHCP server is influenced by two factors - it's
386
configuration and the current state of the addresses that have been
387
assigned to clients. This schema defines a set of objects for
388
representing the DHCP configuration associated with a server. The
389
following object classes provide the ability to record how addresses are
390
used including maintaining history (audit log) on individual leases.
391
Recording lease information in a directory could result in a significant
392
performance impact and is therefore optional. Implementations supporting
393
logging of leases need to consider the performance impact.
394
395
6.1. dhcpLeases Attribute Definitions
396
397
The schema definitions below are for readability the LDIF layout for
398
this schema will follow in section 8.
399
400
Name: dhcpAddressState Description: This stores information about the
401
current binding-status of an address.  For dynamic addresses managed by
402
DHCP, the values should be restricted to the states defined in the DHCP
403
Failover Protocol draft [FAILOVR]: 'FREE', 'ACTIVE', 'EXPIRED',
404
'RELEASED', 'RESET', 'ABANDONED', 'BACKUP'.  For more information on
405
these states see [FAILOVR].  For other addresses, it SHOULD be one of
406
the following: 'UNKNOWN', 'RESERVED' (an address that is managed by DHCP
407
that is reserved for a specific client), 'RESERVED-ACTIVE' (same as
408
reserved, but address is currently in use),  'ASSIGNED' (assigned
409
manually or by some other mechanism), 'UNASSIGNED', 'NOTASSIGNABLE'.
410
Syntax: IA5String Flags: SINGLE-VALUE
411
412
Name: dhcpExpirationTime Description: This is the time the current lease
413
for an address expires.  Syntax: DateTime Flags: SINGLE-VALUE
414
415
416
417
418
M. Meredith et al.        Expires December 2001                 [Page 7]
419
420
421
422
423
424
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
425
426
427
Name: dhcpStartTimeOfState Description: This is the time of the last
428
state change for a leased address.  Syntax: DateTime Flags: SINGLE-VALUE
429
430
Name: dhcpLastTransactionTime Description: This is the last time a valid
431
DHCP packet was received from the client.  Syntax: DateTime Flags:
432
SINGLE-VALUE
433
434
Name: dhcpBootpFlag Description: This indicates whether the address was
435
assigned via BOOTP Syntax: Boolean Flags: SINGLE-VALUE
436
437
Name: dhcpDomainName Description: This is the name of the domain sent to
438
the client by the server.  It is essentially the same as the value for
439
DHCP option 15 sent to the client, and represents only the domain - not
440
the full FQDN.  To obtain the full FQDN assigned to the client you must
441
prepend the "dhcpAssignedHostName" to this value with a ".".  Syntax:
442
IA5String Flags: SINGLE-VALUE
443
444
Name: dhcpDnsStatus Description: This indicates the status of updating
445
DNS resource records on behalf of the client by the DHCP server for this
446
address.  The value is a 16-bit bitmask that has the same values as
447
specified by the Failover-DDNS option (see [FAILOVR]).  Syntax: Integer
448
Flags: SINGLE-VALUE
449
450
Name: dhcpRequestedHostName Description: This is the hostname that was
451
requested by the client.  Syntax: IA5String Flags: SINGLE-VALUE
452
453
Name: dhcpAssignedHostName Description: This is the actual hostname that
454
was assigned to a client. It may not be the name that was requested by
455
the client.  The fully qualified domain name can be determined by
456
appending the value of "dhcpDomainName" (with a dot separator) to this
457
name.  Syntax: IA5String Flags: SINGLE-VALUE
458
459
Name: dhcpReservedForClient Description: This is the distinguished name
460
of the "dhcpHost" that an address is reserved for.  This may not be the
461
same as the "dhcpAssignedToClient" attribute if the address is being
462
reassigned but the current lease has not yet expired.  Syntax: DN Flags:
463
SINGLE-VALUE
464
465
Name: dhcpAssignedToClient Description: This is the distinguished name
466
of a "dhcpHost" that an address is currently assigned to.  This
467
attribute is only present in the class when the address is leased.
468
Syntax: DN Flags: SINGLE-VALUE
469
470
Name: dhcpRelayAgentInfo Description: If the client request was received
471
via a relay agent, this contains information about the relay agent that
472
was available from the DHCP request.  This is a hex-encoded option
473
value.  Syntax: OctetString Flags: SINGLE-VALUE
474
475
Name: dhcpErrorLog Description: Generic error log attribute that allows
476
logging error conditions within a dhcpService or a dhcpSubnet, like no IP 
477
addresses available for lease. Syntax: IA5String 
478
479
M. Meredith et al.        Expires December 2001                 [Page 8]
480
481
482
483
484
485
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
486
487
488
6.2.  dhcpLeases Object Class
489
490
This class represents an IP address.  It may or may not be leaseable,
491
and the object may exist even though a lease is not currently active for
492
the associated IP address.
493
494
It is recommended that all Lease objects for a single DHCP Service be
495
centrally located within a single container. This ensures that the lease
496
objects and the corresponding logs do not have to be relocated, when
497
address ranges allocated to individual DHCP subnets and/or pools change.
498
499
The schema definitions below are for readability the LDIF layout for
500
this schema will follow in section 8.
501
502
Name: dhcpLeases Description: This is the object that holds state
503
information about an IP address. The cn (which is the IP address), and
504
the current address-state are mandatory attributes. If the address is
505
assigned then, some of the optional attributes will have valid data.
506
Must: cn, dhcpAddressState May: dhcpExpirationTime,
507
dhcpStartTimeOfState, dhcpLastTransactionTime, dhcpBootpFlag,
508
dhcpDomainName, dhcpDnsStatus, dhcpRequestedHostName,
509
dhcpAssignedHostName, dhcpReservedForClient, dhcpAssignedToClient,
510
dhcpRelayAgentInfo, dhcpHWAddress
511
512
6.3 Audit Log Information
513
514
A dhcpLog object is created whenever a lease is assigned or released.
515
This object is intended to be created under the corresponding dhcpLeases
516
container, or dhcpPool, dhcpSubnet, dhcpSharedNetwork or dhcpService
517
containers.
518
519
The log information under the dhcpLeases container would be for
520
addresses matching that lease information. The log information in the
521
other containers could be used for errors, i.e. when a pool or subnet is
522
out our addresses or if a server is not able to assign any more
523
addresses for a particular dhcpService.
524
525
Name: dhcpLog Description: This is the object that holds past
526
information about an IP address. The cn is the time/date stamp when the
527
address was assigned or released, the address state at the time, if the
528
address was assigned or released.  Must: cn May: dhcpAddressState,
529
dhcpExpirationTime, dhcpStartTimeOfState, dhcpLastTransactionTime,
530
dhcpBootpFlag, dhcpDomainName, dhcpDnsStatus, dhcpRequestedHostName,
531
dhcpAssignedHostName, dhcpReservedForClient, dhcpAssignedToClient,
532
dhcpRelayAgentInfo, dhcpHWAddress, dhcpErrorLog
533
534
535
536
537
538
539
M. Meredith et al.        Expires December 2001                 [Page 9]
540
541
542
543
544
545
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
546
547
548
7. Determining settings
549
550
The dhcpStatements attribute is the key to DHC enhancements that may
551
come along, and the different key words that a particular server
552
implementation may use. This attribute can be used to hold conditional
553
DHCP Statements and DHCP server parameters. Having a generic settings
554
attribute that is just a string, allows this schema to be extensible and
555
easy to configure.
556
557
All of the attributes that end with DN are references to the class that
558
precedes the DN e.g. the dhcpPrimaryDN and dhcpSecondaryDN attributes
559
hold the Distinguished Names of the dhcpServer objects that are
560
associated with the dhcpService object.
561
562
8. LDIF format for attributes and classes.
563
564
# Attributes
565
566
( 2.16.840.1.113719.1.203.4.1 NAME 'dhcpPrimaryDN' DESC
567
'The DN of the dhcpServer which is the primary server for the
568
configuration.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
569
570
( 2.16.840.1.113719.1.203.4.2 NAME 'dhcpSecondaryDN' DESC 'The DN of
571
dhcpServer(s) which provide backup service for the configuration.'
572
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
573
574
( 2.16.840.1.113719.1.203.4.3 NAME 'dhcpStatements' DESC 'Flexible
575
storage for specific data depending on what object this exists in. Like
576
conditional statements, server parameters, etc. This allows the standard
577
to evolve without needing to adjust the schema.' SYNTAX
578
1.3.6.1.4.1.1466.115.121.1.26 )
579
580
( 2.16.840.1.113719.1.203.4.4 NAME 'dhcpRange' DESC 'The starting &
581
ending IP Addresses in the range (inclusive), separated by a hyphen; if
582
the range only contains one address, then just the address can be
583
specified with no hyphen.  Each range is defined as a separate value.'
584
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
585
586
( 2.16.840.1.113719.1.203.4.5 NAME 'dhcpPermitList' DESC 'This attribute
587
contains the permit lists associated with a pool. Each permit list is
588
defined as a separate value.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
589
590
( 2.16.840.1.113719.1.203.4.6 NAME 'dhcpNetMask' DESC 'The subnet mask
591
length for the subnet.  The mask can be easily computed from this
592
length.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
593
594
( 2.16.840.1.113719.1.203.4.7 NAME 'dhcpOption' DESC 'Encoded option
595
values to be sent to clients.  Each value represents a single option and
596
contains (OptionTag, Length, OptionValue) encoded in the format used by
597
DHCP.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
598
599
M. Meredith et al.        Expires December 2001                [Page 10]
600
601
602
603
604
605
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
606
607
608
( 2.16.840.1.113719.1.203.4.8 NAME 'dhcpClassData' DESC 'Encoded text
609
string or list of bytes expressed in hexadecimal, separated by colons.
610
Clients match subclasses based on matching the class data with the
611
results of match or spawn with statements in the class name
612
declarations.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
613
614
( 2.16.840.1.113719.1.203.4.9 NAME 'dhcpOptionsDN' DESC 'The
615
distinguished name(s) of the dhcpOption objects containing the
616
configuration options provided by the server.' SYNTAX
617
1.3.6.1.4.1.1466.115.121.1.12 )
618
619
( 2.16.840.1.113719.1.203.4.10 NAME 'dhcpHostDN' DESC 'the distinguished
620
name(s) of the dhcpHost objects.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
621
622
( 2.16.840.1.113719.1.203.4.11 NAME 'dhcpPoolDN' DESC 'The distinguished
623
name(s) of pools.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
624
625
( 2.16.840.1.113719.1.203.4.12 NAME 'dhcpGroupDN' DESC 'The
626
distinguished name(s)   of the groups.' SYNTAX
627
1.3.6.1.4.1.1466.115.121.1.12 )
628
629
( 2.16.840.1.113719.1.203.4.13 NAME 'dhcpSubnetDN' DESC 'The
630
distinguished name(s) of the subnets.' SYNTAX
631
1.3.6.1.4.1.1466.115.121.1.12 )
632
633
( 2.16.840.1.113719.1.203.4.14 NAME 'dhcpLeaseDN' DESC 'The
634
distinguished name of a client address.' SYNTAX
635
1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE)
636
637
( 2.16.840.1.113719.1.203.4.15 NAME 'dhcpLeasesDN' DESC 'The
638
distinguished name(s) client addresses.' SYNTAX
639
1.3.6.1.4.1.1466.115.121.1.12 )
640
641
( 2.16.840.1.113719.1.203.4.16 NAME 'dhcpClassesDN' DESC 'The
642
distinguished name(s) of a class(es) in a subclass.' SYNTAX
643
1.3.6.1.4.1.1466.115.121.1.12 )
644
645
( 2.16.840.1.113719.1.203.4.17 NAME 'dhcpSubclassesDN' DESC 'The
646
distinguished name(s) of subclass(es).' SYNTAX
647
1.3.6.1.4.1.1466.115.121.1.12 )
648
649
( 2.16.840.1.113719.1.203.4.18 NAME 'dhcpSharedNetworkDN' DESC 'The
650
distinguished name(s) of sharedNetworks.' SYNTAX
651
1.3.6.1.4.1.1466.115.121.1.12 )
652
653
( 2.16.840.1.113719.1.203.4.19 NAME 'dhcpServiceDN' DESC 'The DN of
654
dhcpService object(s)which contain the configuration information. Each
655
dhcpServer object has this attribute identifying the DHCP
656
657
658
659
M. Meredith et al.        Expires December 2001                [Page 11]
660
661
662
663
664
665
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
666
667
668
configuration(s) that the server is associated with.' SYNTAX
669
1.3.6.1.4.1.1466.115.121.1.12 )
670
671
( 2.16.840.1.113719.1.203.4.20 NAME 'dhcpVersion' DESC 'The version
672
attribute of this object.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-
673
VALUE )
674
675
( 2.16.840.1.113719.1.203.4.21 NAME 'dhcpImplementation' DESC
676
'Description of the DHCP Server implementation e.g. DHCP Server's
677
vendor.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
678
679
( 2.16.840.1.113719.1.203.4.22 NAME 'dhcpAddressState' DESC 'This stores
680
information about the current binding-status of an address.  For dynamic
681
addresses managed by DHCP, the values should be restricted to the
682
following: "FREE", "ACTIVE", "EXPIRED", "RELEASED", "RESET",
683
"ABANDONED", "BACKUP".  For other addresses, it SHOULD be one of the
684
following: "UNKNOWN", "RESERVED" (an address that is managed by DHCP
685
that is reserved for a specific client), "RESERVED-ACTIVE" (same as
686
reserved, but address is currently in use), "ASSIGNED" (assigned
687
manually or by some other mechanism), "UNASSIGNED", "NOTASSIGNABLE".'
688
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
689
690
( 2.16.840.1.113719.1.203.4.23 NAME 'dhcpExpirationTime' DESC 'This is
691
the time the current lease for an address expires.' SYNTAX
692
1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
693
694
( 2.16.840.1.113719.1.203.4.24 NAME 'dhcpStartTimeOfState' DESC 'This is
695
the time of the last state change for a leased address.' SYNTAX
696
1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
697
698
( 2.16.840.1.113719.1.203.4.25 NAME 'dhcpLastTransactionTime' DESC 'This
699
is the last time a valid DHCP packet was received from the client.'
700
SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
701
702
( 2.16.840.1.113719.1.203.4.26 NAME 'dhcpBootpFlag' DESC 'This indicates
703
whether the address was assigned via BOOTP.' SYNTAX
704
1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
705
706
( 2.16.840.1.113719.1.203.4.27 NAME 'dhcpDomainName' DESC 'This is the
707
name of the domain sent to the client by the server.  It is essentially
708
the same as the value for DHCP option 15 sent to the client, and
709
represents only the domain - not the full FQDN.  To obtain the full FQDN
710
assigned to the client you must prepend the "dhcpAssignedHostName" to
711
this value with a ".".' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-
712
VALUE )
713
714
( 2.16.840.1.113719.1.203.4.28 NAME 'dhcpDnsStatus' DESC 'This indicates
715
the status of updating DNS resource records on behalf of the client by
716
717
718
719
M. Meredith et al.        Expires December 2001                [Page 12]
720
721
722
723
724
725
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
726
727
728
the DHCP server for this address.  The value is a 16-bit bitmask.'
729
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
730
731
( 2.16.840.1.113719.1.203.4.29 NAME 'dhcpRequestedHostName' DESC 'This
732
is the hostname that was requested by the client.' SYNTAX
733
1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
734
735
( 2.16.840.1.113719.1.203.4.30 NAME 'dhcpAssignedHostName' DESC 'This is
736
the actual hostname that was assigned to a client. It may not be the
737
name that was requested by the client.  The fully qualified domain name
738
can be determined by appending the value of "dhcpDomainName" (with a dot
739
separator) to this name.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-
740
VALUE )
741
742
( 2.16.840.1.113719.1.203.4.31 NAME 'dhcpReservedForClient' DESC 'The
743
distinguished name of a "dhcpClient" that an address is reserved for.
744
This may not be the same as the "dhcpAssignedToClient" attribute if the
745
address is being reassigned but the current lease has not yet expired.'
746
SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
747
748
( 2.16.840.1.113719.1.203.4.32 NAME 'dhcpAssignedToClient' DESC 'This is
749
the distinguished name of a "dhcpClient" that an address is currently
750
assigned to.  This attribute is only present in the class when the
751
address is leased.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
752
753
( 2.16.840.1.113719.1.203.4.33 NAME 'dhcpRelayAgentInfo' DESC 'If the
754
client request was received via a relay agent, this contains information
755
about the relay agent that was available from the DHCP request.  This is
756
a hex-encoded option value.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
757
SINGLE-VALUE )
758
759
( 2.16.840.1.113719.1.203.4.34 NAME 'dhcpHWAddress' DESC 'The clients
760
hardware address that requested this IP address.' SYNTAX
761
1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
762
763
( 2.16.840.1.113719.1.203.4.35 NAME 'dhcpHashBucketAssignment' DESC
764
'HashBucketAssignment bit map for the DHCP Server, as defined in DHC
765
Load Balancing Algorithm [RFC 3074].' SYNTAX
766
1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
767
768
( 2.16.840.1.113719.1.203.4.36 NAME 'dhcpDelayedServiceParameter' DESC
769
'Delay in seconds corresponding to Delayed Service Parameter
770
configuration, as defined in  DHC Load Balancing Algorithm [RFC 3074]. '
771
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
772
773
( 2.16.840.1.113719.1.203.4.37 NAME 'dhcpMaxClientLeadTime' DESC
774
'Maximum Client Lead Time configuration in seconds, as defined in DHCP
775
Failover Protocol [FAILOVR]' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
776
777
778
779
M. Meredith et al.        Expires December 2001                [Page 13]
780
781
782
783
784
785
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
786
787
788
SINGLE-VALUE )
789
790
( 2.16.840.1.113719.1.203.4.38 NAME 'dhcpFailOverEndpointState' DESC
791
'Server (Failover Endpoint) state, as defined in DHCP Failover Protocol
792
[FAILOVR]' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
793
794
( 2.16.840.1.113719.1.203.4.39 NAME 'dhcpErrorLog' DESC
795
Generic error log attribute that allows logging error conditions within a 
796
dhcpService or a dhcpSubnet, like no IP addresses available for lease. 
797
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
798
799
#Classes
800
801
( 2.16.840.1.113719.1.203.6.1 NAME 'dhcpService' DESC ' Service object
802
that represents the actual DHCP Service configuration. This is a
803
container object.' SUP top MUST (cn $ dhcpPrimaryDN) MAY
804
(dhcpSecondaryDN $ dhcpSharedNetworkDN $ dhcpSubnetDN $ dhcpGroupDN $
805
dhcpHostDN $  dhcpClassesDN $ dhcpOptionsDN $ dhcpStatements ) )
806
807
( 2.16.840.1.113719.1.203.6.2 NAME 'dhcpSharedNetwork' DESC 'This stores
808
configuration information for a shared network.' SUP top MUST  cn MAY
809
(dhcpSubnetDN $ dhcpPoolDN $ dhcpOptionsDN $ dhcpStatements) X-
810
NDS_CONTAINMENT ('dhcpService' ) )
811
812
( 2.16.840.1.113719.1.203.6.3 NAME 'dhcpSubnet' DESC 'This class defines
813
a subnet. This is a container object.' SUP top MUST ( cn $ dhcpNetMask )
814
MAY (dhcpRange $ dhcpPoolDN $ dhcpGroupDN $ dhcpHostDN $ dhcpClassesDN $
815
dhcpLeasesDN $ dhcpOptionsDN $ dhcpStatements) X-NDS_CONTAINMENT
816
('dhcpService' 'dhcpSharedNetwork') )
817
818
( 2.16.840.1.113719.1.203.6.4 NAME 'dhcpPool' DESC 'This stores
819
configuration information about a pool.' SUP top MUST ( cn $ dhcpRange )
820
MAY (dhcpClassesDN $ dhcpPermitList $ dhcpLeasesDN $ dhcpOptionsDN $
821
dhcpStatements) X-NDS_CONTAINMENT ('dhcpSubnet' 'dhcpSharedNetwork') )
822
823
( 2.16.840.1.113719.1.203.6.5 NAME 'dhcpGroup' DESC 'Group object that
824
lists host DNs and parameters. This is a container object.' SUP top MUST
825
cn MAY ( dhcpHostDN $ dhcpOptionsDN $ dhcpStatements ) X-NDS_CONTAINMENT
826
('dhcpSubnet' 'dhcpService' ) )
827
828
( 2.16.840.1.113719.1.203.6.6 NAME 'dhcpHost' DESC 'This represents
829
information about a particular client' SUP top MUST cn MAY  (dhcpLeaseDN
830
$ dhcpHWAddress $ dhcpOptionsDN $ dhcpStatements) X-NDS_CONTAINMENT
831
('dhcpService' 'dhcpSubnet' 'dhcpGroup') )
832
833
( 2.16.840.1.113719.1.203.6.7 NAME 'dhcpClass' DESC 'Represents
834
information about a collection of related clients.' SUP top MUST cn MAY
835
(dhcpSubClassesDN $ dhcpOptionsDN $ dhcpStatements) X-NDS_CONTAINMENT
836
('dhcpService' 'dhcpSubnet' ) )
837
838
( 2.16.840.1.113719.1.203.6.8 NAME 'dhcpSubClass' DESC 'Represents
839
information about a collection of related classes.' SUP top MUST cn MAY
840
(dhcpClassData $ dhcpOptionsDN $ dhcpStatements) X-NDS_CONTAINMENT
841
842
843
844
M. Meredith et al.        Expires December 2001                [Page 14]
845
846
847
848
849
850
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
851
852
853
'dhcpClass' )
854
855
( 2.16.840.1.113719.1.203.6.9 NAME 'dhcpOptions' DESC 'Represents
856
information about a collection of options defined.' SUP top MUST cn MAY
857
( dhcpOption ) X-NDS_CONTAINMENT  ('dhcpService' 'dhcpSharedNetwork'
858
'dhcpSubnet' 'dhcpPool' 'dhcpGroup' 'dhcpHost' 'dhcpClass' )
859
860
( 2.16.840.1.113719.1.203.6.10 NAME 'dhcpLeases' DESC 'This class
861
represents an IP Address, which may or may not have been leased.' SUP
862
top MUST ( cn $ dhcpAddressState ) MAY ( dhcpExpirationTime $
863
dhcpStartTimeOfState $ dhcpLastTransactionTime $ dhcpBootpFlag $
864
dhcpDomainName $ dhcpDnsStatus $ dhcpRequestedHostName $
865
dhcpAssignedHostName $ dhcpReservedForClient $ dhcpAssignedToClient $
866
dhcpRelayAgentInfo $ dhcpHWAddress ) X-NDS_CONTAINMENT ( 'dhcpService'
867
'dhcpSubnet' 'dhcpPool') )
868
869
( 2.16.840.1.113719.1.203.6.11 NAME 'dhcpLog' DESC 'This is the object
870
that holds past information about the IP address. The cn is the
871
time/date stamp when the address was assigned or released, the address
872
state at the time, if the address was assigned or released.' SUP top
873
MUST ( cn ) MAY ( dhcpAddressState $ dhcpExpirationTime $
874
dhcpStartTimeOfState $ dhcpLastTransactionTime $ dhcpBootpFlag $
875
dhcpDomainName $ dhcpDnsStatus $ dhcpRequestedHostName $
876
dhcpAssignedHostName $ dhcpReservedForClient $ dhcpAssignedToClient $
877
dhcpRelayAgentInfo $ dhcpHWAddress $ dhcpErrorLog) X-NDS_CONTAINMENT 
878
('dhcpLeases' 'dhcpPool' 'dhcpSubnet' 'dhcpSharedNetwork' 'dhcpService' ) )
879
880
( 2.16.840.1.113719.1.203.6.12 NAME 'dhcpServer' DESC 'DHCP Server
881
Object' SUP top MUST (cn, dhcpServiceDN) MAY (dhcpVersion $
882
dhcpImplementation $ dhcpHashBucketAssignment $
883
dhcpDelayedServiceParameter $ dhcpMaxClientLeadTime $
884
dhcpFailOverEndpointState $ dhcpStatements) X-NDS_CONTAINMENT ('O' 'OU' 
885
'dc') )
886
887
9. Security Considerations
888
889
Since the DHCP Configuration information is stored in a directory, the
890
security of the information is limited to the security offered by the
891
directory including the security of the objects within that directory.
892
893
10.  Intellectual Property Rights Notices
894
895
The IETF takes no position regarding the validity or scope of any
896
intellectual property or other rights that might be claimed to pertain
897
to the implementation or use of the technology described in this
898
document or the extent to which any license under such rights might or
899
might not be available; neither does it represent that it has made any
900
effort to identify any such rights.  Information on the IETF's
901
procedures with respect to rights in standards-track and standards-
902
903
904
905
M. Meredith et al.        Expires December 2001                [Page 15]
906
907
908
909
910
911
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
912
913
914
related documentation can be found in BCP-11.  Copies of claims of
915
rights made available for publication and any assurances of licenses to
916
be made available, or the result of an attempt made to obtain a general
917
license or permission for the use of such proprietary rights by
918
implementors or users of this specification can be obtained from the
919
IETF Secretariat.
920
921
The IETF invites any interested party to bring to its attention any
922
copyrights, patents or patent applications, or other proprietary rights
923
which may cover technology that may be required to practice this
924
standard.  Please address the information to the IETF Executive
925
Director.
926
927
11.  Full Copyright Statement
928
929
Copyright (C) The Internet Society (2001).  All Rights Reserved.
930
931
This document and translations of it may be copied and furnished to
932
others, and derivative works that comment on or otherwise explain it or
933
assist in its implementation may be prepared, copied, published and
934
distributed, in whole or in part, without restriction of any kind,
935
provided that the above copyright notice and this paragraph are included
936
on all such copies and derivative works.  However, this document itself
937
may not be modified in any way, such as by removing the copyright notice
938
or references to the Internet Society or other Internet organizations,
939
except as needed for the purpose of developing Internet standards in
940
which case the procedures for copyrights defined in the Internet
941
Standards process must be followed, or as required to translate it into
942
languages other than English.
943
944
The limited permissions granted above are perpetual and will not be
945
revoked by the Internet Society or its successors or assigns.
946
947
This document and the information contained herein is provided on an "AS
948
IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK
949
FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
950
LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT
951
INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR
952
FITNESS FOR A PARTICULAR PURPOSE.
953
954
12. References
955
956
[RFC2131] Droms, R., "Dynamic Host Configuration Protocol", RFC 2131,
957
March 1997.
958
959
[RFC2132] Alexander, S., Droms, R., "DHCP Options and BOOTP Vendor
960
Extensions", RFC 2132, March 1997.
961
962
963
964
965
M. Meredith et al.        Expires December 2001                [Page 16]
966
967
968
969
970
971
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
972
973
974
[MSDHCP]  Gu, Y., Vyaghrapuri, R., "An LDAP Schema for Dynamic Host
975
Configuration Protocol Service", Internet Draft <draft-gu-dhcp-ldap-
976
schema-00.txt>, August 1998.
977
978
[NOVDHCP] Miller, T., Patel, A., Rao, P., "Lightweight Directory Access
979
Protocol (v3): Schema for Dynamic Host Configuration Protocol (DHCP)",
980
Internet Draft <draft-miller-dhcp-ldap-schema-00.txt>, June 1998.
981
982
[FAILOVR] Droms, R., Rabil, G., Dooley, M., Kapur, A., Gonczi, S., Volz,
983
B., "DHCP Failover Protocol", Internet Draft <draft-ietf-dhc-
984
failover-08.txt>, July 2000.
985
986
[RFC 3074] Volz B., Gonczi S., Lemon T., Stevens R., "DHC Load Balancing
987
Algorithm", February 2001
988
989
[AGENT]   Patrick, M., "DHCP Relay Agent Information Option", Internet
990
Draft <draft-ietf-dhc-agent-options-09.txt>, March 2000.
991
992
[DHCPOPT] Carney, M., "New Option Review Guidelines and Additional
993
Option Namespace", Internet Draft <draft-ietf-dhc-
994
option_review_and_namespace-01.txt>, October 1999.
995
996
[POLICY]  Strassner, J., Elleson, E., Moore, B., "Policy Framework LDAP
997
Core Schema", Internet Draft <draft-ietf-policy-core-schema-06.txt>,
998
November 1999.
999
1000
[RFC2251] Wahl, M., Howes, T., Kille, S., "Lightweight Directory Access
1001
Protocol (v3)", RFC 2251, December 1997.
1002
1003
[RFC2252] Wahl, M., Coulbeck, A., Howes, T., Kille, S., "Lightweight
1004
Directory Access Protocol (v3) Attribute Syntax Definitions", RFC 2252,
1005
December 1997.
1006
1007
[RFC2255] Howes, T., Smith, M., "The LDAP URL Format", RFC 2255,
1008
December 1997.
1009
1010
[RFC951]  Croft, B., Gilmore, J., "Bootstrap Protocol (BOOTP)", RFC 951,
1011
September 1985.
1012
1013
[RFC2119] Bradner, S. "Key words for use in RFCs to Indicate Requirement
1014
Levels", RFC 2119, March 1997.
1015
1016
13. Acknowledgments
1017
1018
This work is partially based on a previous draft draft-ietf-dhc-
1019
schema-02.doc.
1020
1021
1022
1023
1024
1025
M. Meredith et al.        Expires December 2001                [Page 17]
1026
1027
1028
1029
1030
1031
INTERNET-DRAFT            LDAP Schema for DHCP              16 June 2001
1032
1033
1034
14. Author's Addresses
1035
1036
Comments regarding this draft may be sent to the authors at the
1037
following address:
1038
1039
Mark Meredith
1040
Mark Hinckley
1041
Novell Inc.
1042
1800 S. Novell Place
1043
Provo, Utah 84606
1044
1045
Vijay K. Nanjundaswamy
1046
Novell Software Development (I) Ltd
1047
49/1 & 49/3, Garvebhavi Palya,
1048
7th Mile, Hosur Road
1049
Bangalore 560068
1050
1051
email: mark_meredith@novell.com
1052
email: knvijay@novell.com
1053
email: mhinckley@novell.com
1054
1055
This Internet Draft expires December 16, 2001.
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
M. Meredith et al.        Expires December 2001                [Page 18]
1086
1087
1088
1089
(-)dhcp-3.0.1/includes/dhcpd.h (-1 / +49 lines)
Lines 79-84 Link Here
79
#include <isc-dhcp/result.h>
79
#include <isc-dhcp/result.h>
80
#include <omapip/omapip_p.h>
80
#include <omapip/omapip_p.h>
81
81
82
#if defined(LDAP_CONFIGURATION)
83
# include <ldap.h>
84
# include <sys/utsname.h> /* for uname() */
85
#endif
86
82
#if !defined (OPTION_HASH_SIZE)
87
#if !defined (OPTION_HASH_SIZE)
83
# define OPTION_HASH_SIZE 17
88
# define OPTION_HASH_SIZE 17
84
# define OPTION_HASH_PTWO 32	/* Next power of two above option hash. */
89
# define OPTION_HASH_PTWO 32	/* Next power of two above option hash. */
Lines 139-144 Link Here
139
	char *inbuf;
144
	char *inbuf;
140
	unsigned bufix, buflen;
145
	unsigned bufix, buflen;
141
	unsigned bufsiz;
146
	unsigned bufsiz;
147
148
	char (*read_function) (struct parse *);
142
};
149
};
143
150
144
/* Variable-length array of data. */
151
/* Variable-length array of data. */
Lines 241-246 Link Here
241
	u_int8_t hbuf [17];
248
	u_int8_t hbuf [17];
242
};
249
};
243
250
251
#if defined(LDAP_CONFIGURATION)
252
# define LDAP_BUFFER_SIZE		8192
253
# define LDAP_METHOD_STATIC		0
254
# define LDAP_METHOD_DYNAMIC		1
255
256
/* This is a tree of the current configuration we are building from LDAP */
257
258
struct ldap_config_stack {
259
	LDAPMessage * res; 	/* Pointer returned from ldap_search */
260
	LDAPMessage * ldent; 	/* Current item in LDAP that we're processing 
261
				   in res */
262
	int close_brace;	/* Put a closing } after we're through with
263
				   this item */
264
	int processed; 		/* We set this flag if this base item has been
265
				   processed. After this base item is processed,
266
				   we can start processing the children */
267
	struct ldap_config_stack *next;
268
};
269
#endif
270
244
typedef enum {
271
typedef enum {
245
	server_startup = 0,
272
	server_startup = 0,
246
	server_running = 1,
273
	server_running = 1,
Lines 417-422 Link Here
417
# define DEFAULT_PING_TIMEOUT 1
444
# define DEFAULT_PING_TIMEOUT 1
418
#endif
445
#endif
419
446
447
#if defined(LDAP_CONFIGURATION)
448
# define SV_LDAP_SERVER  		47
449
# define SV_LDAP_PORT  			48
450
# define SV_LDAP_USERNAME  		49
451
# define SV_LDAP_PASSWORD  		50
452
# define SV_LDAP_BASE_DN 		51
453
# define SV_LDAP_METHOD			52
454
# define SV_LDAP_DEBUG_FILE		53
455
#endif
456
420
#if !defined (DEFAULT_DEFAULT_LEASE_TIME)
457
#if !defined (DEFAULT_DEFAULT_LEASE_TIME)
421
# define DEFAULT_DEFAULT_LEASE_TIME 43200
458
# define DEFAULT_DEFAULT_LEASE_TIME 43200
422
#endif
459
#endif
Lines 1520-1526 Link Here
1520
char *quotify_string (const char *, const char *, int);
1557
char *quotify_string (const char *, const char *, int);
1521
char *quotify_buf (const unsigned char *, unsigned, const char *, int);
1558
char *quotify_buf (const unsigned char *, unsigned, const char *, int);
1522
char *print_base64 (const unsigned char *, unsigned, const char *, int);
1559
char *print_base64 (const unsigned char *, unsigned, const char *, int);
1523
char *print_hw_addr PROTO ((int, int, unsigned char *));
1560
char *print_hw_addr PROTO ((const int, const int, const unsigned char *));
1524
void print_lease PROTO ((struct lease *));
1561
void print_lease PROTO ((struct lease *));
1525
void dump_raw PROTO ((const unsigned char *, unsigned));
1562
void dump_raw PROTO ((const unsigned char *, unsigned));
1526
void dump_packet_option (struct option_cache *, struct packet *,
1563
void dump_packet_option (struct option_cache *, struct packet *,
Lines 2622-2624 Link Here
2622
#endif /* FAILOVER_PROTOCOL */
2659
#endif /* FAILOVER_PROTOCOL */
2623
2660
2624
const char *binding_state_print (enum failover_state);
2661
const char *binding_state_print (enum failover_state);
2662
2663
/* ldap.c */
2664
#if defined(LDAP_CONFIGURATION)
2665
extern struct enumeration ldap_methods;
2666
isc_result_t ldap_read_config (void);
2667
int find_haddr_in_ldap (struct host_decl **, int, unsigned,
2668
                        const unsigned char *, const char *, int);
2669
int find_subclass_in_ldap (struct class *, struct class **, 
2670
			   struct data_string *);
2671
#endif
2672
(-)dhcp-3.0.1/includes/site.h (+10 lines)
Lines 177-179 Link Here
177
   traces. */
177
   traces. */
178
178
179
#define TRACING
179
#define TRACING
180
181
/* Define this if you want to read your config from LDAP. Read README.ldap
182
   about how to set this up */
183
184
#define LDAP_CONFIGURATION
185
186
/* Define this if you want to enable LDAP over a SSL connection. You will need
187
   to add -lcrypto -lssl to the LIBS= line of server/Makefile */
188
189
/* #define USE_SSL */
(-)dhcp-3.0.1/README.ldap (+165 lines)
Line 0 Link Here
1
LDAP Support in DHCP
2
Brian Masney <masneyb@ntelos.net>
3
Last updated 3/23/2003
4
5
This document describes setting up the DHCP server to read it's configuration 
6
from LDAP. This work is based on the IETF document 
7
draft-ietf-dhc-ldap-schema-01.txt included in the doc directory. For the latest
8
version of this document, please see http://home.ntelos.net/~masneyb.
9
10
First question on most people's mind is "Why do I want to store my 
11
configuration in LDAP?" If you run a small DHCP server, and the configuration
12
on it rarely changes, then you won't need to store your configuration in LDAP.
13
But, if you have several DHCP servers, and you want an easy way to manage your 
14
configuration, this can be a solution. 
15
16
The first step will be to setup your LDAP server. I am using OpenLDAP from
17
www.openldap.org. Building and installing OpenLDAP is beyond the scope of this 
18
document. There is plenty of documentation out there about this. Once you have 
19
OpenLDAP installed, you will have to edit your slapd.conf file. I added the 
20
following 2 lines to my configuration file:
21
22
include         /etc/ldap/schema/dhcp.schema
23
index           dhcpHWAddress 	eq
24
index           dhcpClassData	eq
25
26
The first line tells it to include the dhcp schema file. You will find this 
27
file under the contrib directory in this distribution. You will need to copy 
28
this file to where your other schema files are (maybe
29
/usr/local/openldap/etc/openldap/schema/). The second line sets up
30
an index for the dhcpHWAddress parameter. The third parameter is for reading 
31
subclasses from LDAP every time a DHCP request comes in. Make sure you run the 
32
slapindex command and restart slapd to have these changes to into effect.
33
34
Now that you have LDAP setup, you should be able to use gq (http://biot.com/gq/)
35
to verify that the dhcp schema file is loaded into LDAP. Pull up gq, and click
36
on the Schema tab. Go under objectClasses, and you should see at least the 
37
following object classes listed: dhcpClass, dhcpGroup, dhcpHost, dhcpOptions, 
38
dhcpPool, dhcpServer, dhcpService, dhcpSharedNetwork, dhcpSubClass, and 
39
dhcpSubnet. If you do not see these, you need to check over your LDAP 
40
configuration before you go any further.
41
42
You should now be ready to build DHCP. If you would like to enable LDAP over
43
SSL, edit the includes/site.h file and uncomment the USE_SSL line.  Now run
44
configure in the base source directory. If you chose to enable LDAP over SSL,
45
you must append -lcrypto -lssl to the LIBS= line in the file
46
work.os/server/Makefile (replace os with your operating system, linux-2.2 on
47
my machine).  You should now be able to type make to build your DHCP server.
48
49
Once you have DHCP installed, you will need to setup your initial plaintext 
50
config file. In my /etc/dhcpd.conf file, I have:
51
52
ldap-server "localhost";
53
ldap-port 389;
54
ldap-username "cn=DHCP User, dc=ntelos, dc=net";
55
ldap-password "blah";
56
ldap-base-dn "dc=ntelos, dc=net";
57
ldap-method dynamic;
58
ldap-debug-file "/var/log/dhcp-ldap-startup.log";
59
60
All of these parameters should be self explanatory except for the ldap-method.
61
You can set this to static or dynamic. If you set it to static, the 
62
configuration is read once on startup, and LDAP isn't used anymore. But, if you
63
set this to dynamic, the configuration is read once on startup, and the 
64
hosts that are stored in LDAP are looked up every time a DHCP request comes in.
65
66
When the optional statement ldap-debug-file is specified, on startup the DHCP
67
server will write out the configuration that it generated from LDAP. If you are
68
getting errors about your LDAP configuration, this is a good place to start
69
looking.
70
71
The next step is to set up your LDAP tree. Here is an example config that will
72
give a 10.100.0.x address to machines that have a host entry in LDAP. 
73
Otherwise, it will give a 10.200.0.x address to them. (NOTE: replace 
74
dc=ntelos, dc=net with your base dn). If you would like to convert your 
75
existing dhcpd.conf file to LDIF format, there is a script 
76
contrib/dhcpd-conf-to-ldap.pl that will convert it for you. Type
77
dhcpd-conf-to-ldap.pl --help to see the usage information for this script.
78
79
# You must specify the server's host name in LDAP that you are going to run
80
# DHCP on and point it to which config tree you want to use. Whenever DHCP 
81
# first starts up, it will do a search for this entry to find out which 
82
# config to use
83
dn: cn=brian.ntelos.net, dc=ntelos, dc=net
84
objectClass: top
85
objectClass: dhcpServer
86
cn: brian.ntelos.net
87
dhcpServiceDN: cn=DHCP Service Config, dc=ntelos, dc=net
88
89
# Here is the config tree that brian.ntelos.net points to. 
90
dn: cn=DHCP Service Config, dc=ntelos, dc=net
91
cn: DHCP Service Config
92
objectClass: top
93
objectClass: dhcpService
94
dhcpPrimaryDN: dc=ntelos, dc=net
95
dhcpStatements: ddns-update-style none
96
dhcpStatements: default-lease-time 600
97
dhcpStatements: max-lease-time 7200
98
99
# Set up a shared network segment
100
dn: cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
101
cn: WV
102
objectClass: top
103
objectClass: dhcpSharedNetwork
104
105
# Set up a subnet declaration with a pool statement. Also note that we have
106
# a dhcpOptions object with this entry
107
dn: cn=10.100.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
108
cn: 10.100.0.0
109
objectClass: top
110
objectClass: dhcpSubnet
111
objectClass: dhcpOptions
112
dhcpOption: domain-name-servers 10.100.0.2
113
dhcpOption: routers 10.100.0.1
114
dhcpOption: subnet-mask 255.255.255.0
115
dhcpOption: broadcast-address 10.100.0.255
116
dhcpNetMask: 24
117
118
# Set up a pool for this subnet. Only known hosts will get these IPs
119
dn: cn=Known Pool, cn=10.100.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
120
cn: Known Pool
121
objectClass: top
122
objectClass: dhcpPool
123
dhcpRange: 10.100.0.3 10.100.0.254
124
dhcpPermitList: deny unknown-clients
125
126
# Set up another subnet declaration with a pool statement
127
dn: cn=10.200.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
128
cn: 10.200.0.0
129
objectClass: top
130
objectClass: dhcpSubnet
131
objectClass: dhcpOptions
132
dhcpOption: domain-name-servers 10.200.0.2
133
dhcpOption: routers 10.200.0.1
134
dhcpOption: subnet-mask 255.255.255.0
135
dhcpOption: broadcast-address 10.200.0.255
136
dhcpNetMask: 24
137
138
# Set up a pool for this subnet. Only unknown hosts will get these IPs
139
dn: cn=Known Pool, cn=10.200.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
140
cn: Known Pool
141
objectClass: top
142
objectClass: dhcpPool
143
dhcpRange: 10.200.0.3 10.200.0.254
144
dhcpPermitList: deny known clients
145
146
# Set aside a group for all of our known MAC addresses
147
dn: cn=Customers, cn=DHCP Service Config, dc=ntelos, dc=net
148
objectClass: top
149
objectClass: dhcpGroup
150
cn: Customers
151
152
# Host entry for my laptop
153
dn: cn=brianlaptop, cn=Customers, cn=DHCP Service Config, dc=ntelos, dc=net
154
objectClass: top
155
objectClass: dhcpHost
156
cn: brianlaptop
157
dhcpHWAddress: ethernet 00:00:00:00:00:00
158
159
You can use the command slapadd to load all of these entries into your LDAP 
160
server. After you load this, you should be able to start up DHCP. If you run
161
into problems reading the configuration, try running dhcpd with the -d flag. 
162
If you still have problems, edit the site.conf file in the DHCP source and
163
add the line: COPTS= -DDEBUG_LDAP and recompile DHCP. (make sure you run make 
164
clean and rerun configure before you rebuild).
165
(-)dhcp-3.0.1/server/class.c (-3 / +14 lines)
Lines 90-95 Link Here
90
	int matched = 0;
90
	int matched = 0;
91
	int status;
91
	int status;
92
	int ignorep;
92
	int ignorep;
93
	int classfound;
93
94
94
	for (class = collection -> classes; class; class = class -> nic) {
95
	for (class = collection -> classes; class; class = class -> nic) {
95
#if defined (DEBUG_CLASS_MATCHING)
96
#if defined (DEBUG_CLASS_MATCHING)
Lines 135-143 Link Here
135
				   class -> submatch, MDL));
136
				   class -> submatch, MDL));
136
			if (status && data.len) {
137
			if (status && data.len) {
137
				nc = (struct class *)0;
138
				nc = (struct class *)0;
138
				if (class_hash_lookup (&nc, class -> hash,
139
                                classfound = class_hash_lookup (&nc, 
139
						       (const char *)data.data,
140
						class -> hash, 
140
						       data.len, MDL)) {
141
						(const char *)data.data,
142
						data.len, MDL);
143
144
#ifdef LDAP_CONFIGURATION
145
                                if (!classfound && 
146
						find_subclass_in_ldap (class, 
147
								&nc, &data)) 
148
					classfound = 1;
149
#endif
150
151
				if (classfound) {
141
#if defined (DEBUG_CLASS_MATCHING)
152
#if defined (DEBUG_CLASS_MATCHING)
142
					log_info ("matches subclass %s.",
153
					log_info ("matches subclass %s.",
143
					      print_hex_1 (data.len,
154
					      print_hex_1 (data.len,
(-)dhcp-3.0.1/server/confpars.c (-1 / +11 lines)
Lines 62-68 Link Here
62
62
63
isc_result_t readconf ()
63
isc_result_t readconf ()
64
{
64
{
65
	return read_conf_file (path_dhcpd_conf, root_group, ROOT_GROUP, 0);
65
	isc_result_t res;
66
67
	res = read_conf_file (path_dhcpd_conf, root_group, ROOT_GROUP, 0);
68
#if defined(LDAP_CONFIGURATION)
69
	if (res != ISC_R_SUCCESS)
70
		return (res);
71
72
	return ldap_read_config ();
73
#else
74
	return (res);
75
#endif
66
}
76
}
67
77
68
isc_result_t read_conf_file (const char *filename, struct group *group,
78
isc_result_t read_conf_file (const char *filename, struct group *group,
(-)dhcp-3.0.1/server/dhcpd.c (+3 lines)
Lines 432-437 Link Here
432
	/* Add the ddns update style enumeration prior to parsing. */
432
	/* Add the ddns update style enumeration prior to parsing. */
433
	add_enumeration (&ddns_styles);
433
	add_enumeration (&ddns_styles);
434
	add_enumeration (&syslog_enum);
434
	add_enumeration (&syslog_enum);
435
#if defined (LDAP_CONFIGURATION)
436
	add_enumeration (&ldap_methods);
437
#endif
435
438
436
	if (!group_allocate (&root_group, MDL))
439
	if (!group_allocate (&root_group, MDL))
437
		log_fatal ("Can't allocate root group!");
440
		log_fatal ("Can't allocate root group!");
(-)dhcp-3.0.1/server/ldap.c (+1505 lines)
Line 0 Link Here
1
/* ldap.c
2
3
   Routines for reading the configuration from LDAP */
4
5
/*
6
 * Copyright (c) 2003-2004 Ntelos, Inc.
7
 * All rights reserved.
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 *
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in the
17
 *    documentation and/or other materials provided with the distribution.
18
 * 3. Neither the name of The Internet Software Consortium nor the names
19
 *    of its contributors may be used to endorse or promote products derived
20
 *    from this software without specific prior written permission.
21
 *
22
 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23
 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26
 * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34
 * SUCH DAMAGE.
35
 *
36
 * This LDAP module was written by Brian Masney <masneyb@ntelos.net>. It's
37
 * development was sponsored by Ntelos, Inc. (www.ntelos.com).
38
 */
39
40
#include "dhcpd.h"
41
42
#if defined(LDAP_CONFIGURATION)
43
44
static LDAP * ld = NULL;
45
static char *ldap_server = NULL, 
46
            *ldap_username = NULL, 
47
            *ldap_password = NULL,
48
            *ldap_base_dn = NULL,
49
            *ldap_debug_file = NULL;
50
static int ldap_port = LDAP_PORT,
51
           ldap_method = LDAP_METHOD_DYNAMIC,
52
           ldap_debug_fd = -1;
53
static struct ldap_config_stack *ldap_stack = NULL;
54
55
typedef struct ldap_dn_node {
56
    struct ldap_dn_node *next;
57
    size_t refs;
58
    char *dn;
59
} ldap_dn_node;
60
61
static ldap_dn_node *ldap_service_dn_head = NULL;
62
static ldap_dn_node *ldap_service_dn_tail = NULL;
63
64
65
static void
66
ldap_parse_class (struct ldap_config_stack *item, struct parse *cfile)
67
{
68
  char **tempstr;
69
70
  if ((tempstr = ldap_get_values (ld, item->ldent, "cn")) == NULL ||
71
      tempstr[0] == NULL)
72
    {
73
      if (tempstr != NULL)
74
        ldap_value_free (tempstr);
75
76
      return;
77
    }
78
79
  strncat (cfile->inbuf, "class \"", LDAP_BUFFER_SIZE);
80
  strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
81
  strncat (cfile->inbuf, "\" {\n", LDAP_BUFFER_SIZE);
82
83
  item->close_brace = 1;
84
  ldap_value_free (tempstr);
85
}
86
87
88
static void
89
ldap_parse_subclass (struct ldap_config_stack *item, struct parse *cfile)
90
{
91
  char **tempstr, **classdata;
92
93
  if ((tempstr = ldap_get_values (ld, item->ldent, "cn")) == NULL ||
94
      tempstr[0] == NULL)
95
    {
96
      if (tempstr != NULL)
97
        ldap_value_free (tempstr);
98
99
      return;
100
    }
101
102
  if ((classdata = ldap_get_values (ld, item->ldent, 
103
                                  "dhcpClassData")) == NULL || 
104
      classdata[0] == NULL)
105
    {
106
      if (classdata != NULL)
107
        ldap_value_free (classdata);
108
      ldap_value_free (tempstr);
109
110
      return;
111
    }
112
113
  strncat (cfile->inbuf, "subclass ", LDAP_BUFFER_SIZE);
114
  strncat (cfile->inbuf, classdata[0], LDAP_BUFFER_SIZE);
115
  strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
116
  strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
117
  strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
118
119
  item->close_brace = 1;
120
  ldap_value_free (tempstr);
121
  ldap_value_free (classdata);
122
}
123
124
125
static void
126
ldap_parse_host (struct ldap_config_stack *item, struct parse *cfile)
127
{
128
  char **tempstr, **hwaddr;
129
130
  if ((tempstr = ldap_get_values (ld, item->ldent, "cn")) == NULL ||
131
      tempstr[0] == NULL)
132
    {
133
      if (tempstr != NULL)
134
        ldap_value_free (tempstr);
135
136
      return;
137
    }
138
139
  if ((hwaddr = ldap_get_values (ld, item->ldent, 
140
                                 "dhcpHWAddress")) == NULL || 
141
      hwaddr[0] == NULL)
142
    {
143
      if (hwaddr != NULL)
144
        ldap_value_free (hwaddr);
145
146
      ldap_value_free (tempstr);
147
      return;
148
    }
149
150
  strncat (cfile->inbuf, "host ", LDAP_BUFFER_SIZE);
151
  strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
152
  strncat (cfile->inbuf, " {\nhardware ", LDAP_BUFFER_SIZE);
153
  strncat (cfile->inbuf, hwaddr[0], LDAP_BUFFER_SIZE);
154
  strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
155
156
  item->close_brace = 1;
157
  ldap_value_free (tempstr);
158
  ldap_value_free (hwaddr);
159
}
160
161
162
static void
163
ldap_parse_shared_network (struct ldap_config_stack *item, struct parse *cfile)
164
{
165
  char **tempstr;
166
167
168
  if ((tempstr = ldap_get_values (ld, item->ldent, "cn")) == NULL ||
169
      tempstr[0] == NULL)
170
    {
171
      if (tempstr != NULL)
172
        ldap_value_free (tempstr);
173
174
      return;
175
    }
176
177
  strncat (cfile->inbuf, "shared-network \"", LDAP_BUFFER_SIZE);
178
  strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
179
  strncat (cfile->inbuf, "\" {\n", LDAP_BUFFER_SIZE);
180
181
  item->close_brace = 1;
182
  ldap_value_free (tempstr);
183
}
184
185
186
static void
187
parse_netmask (int netmask, char *netmaskbuf)
188
{
189
  unsigned long nm;
190
  int i;
191
192
  nm = 0;
193
  for (i=1; i <= netmask; i++)
194
    {
195
      nm |= 1 << (32 - i);
196
    }
197
198
  sprintf (netmaskbuf, "%d.%d.%d.%d", (int) (nm >> 24) & 0xff, 
199
                                      (int) (nm >> 16) & 0xff, 
200
                                      (int) (nm >> 8) & 0xff, 
201
                                      (int) nm & 0xff);
202
}
203
204
static void
205
ldap_parse_subnet (struct ldap_config_stack *item, struct parse *cfile)
206
{
207
  char **tempstr, **netmaskstr, netmaskbuf[16];
208
  int i;
209
210
  if ((tempstr = ldap_get_values (ld, item->ldent, "cn")) == NULL ||
211
      tempstr[0] == NULL)
212
    {
213
      if (tempstr != NULL)
214
        ldap_value_free (tempstr);
215
216
      return;
217
    }
218
219
  if ((netmaskstr = ldap_get_values (ld, item->ldent, 
220
                                     "dhcpNetmask")) == NULL || 
221
      netmaskstr[0] == NULL)
222
    {
223
      if (netmaskstr != NULL)
224
        ldap_value_free (netmaskstr);
225
      ldap_value_free (tempstr);
226
227
      return;
228
    }
229
230
  strncat (cfile->inbuf, "subnet ", LDAP_BUFFER_SIZE);
231
  strncat (cfile->inbuf, tempstr[0], LDAP_BUFFER_SIZE);
232
233
  strncat (cfile->inbuf, " netmask ", LDAP_BUFFER_SIZE);
234
  parse_netmask (strtol (netmaskstr[0], NULL, 10), netmaskbuf);
235
  strncat (cfile->inbuf, netmaskbuf, LDAP_BUFFER_SIZE);
236
237
  strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
238
239
  ldap_value_free (tempstr);
240
  ldap_value_free (netmaskstr);
241
242
  if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpRange")) != NULL)
243
    {
244
      for (i=0; tempstr[i] != NULL; i++)
245
        {
246
          strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE);
247
          strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
248
          strncat (cfile->inbuf, tempstr[i], LDAP_BUFFER_SIZE);
249
          strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
250
        }
251
      ldap_value_free (tempstr);
252
    }
253
254
  item->close_brace = 1;
255
}
256
257
258
static void
259
ldap_parse_pool (struct ldap_config_stack *item, struct parse *cfile)
260
{
261
  char **tempstr;
262
  int i;
263
264
  strncat (cfile->inbuf, "pool {\n", LDAP_BUFFER_SIZE);
265
266
  if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpRange")) != NULL)
267
    {
268
      strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE);
269
      for (i=0; tempstr[i] != NULL; i++)
270
        {
271
          strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
272
          strncat (cfile->inbuf, tempstr[i], LDAP_BUFFER_SIZE);
273
        }
274
      strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
275
      ldap_value_free (tempstr);
276
    }
277
278
  if ((tempstr = ldap_get_values (ld, item->ldent, "dhcpPermitList")) != NULL)
279
    {
280
      for (i=0; tempstr[i] != NULL; i++)
281
        {
282
          strncat (cfile->inbuf, tempstr[i], LDAP_BUFFER_SIZE);
283
          strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
284
        }
285
      ldap_value_free (tempstr);
286
    }
287
288
  item->close_brace = 1;
289
}
290
291
292
static void
293
ldap_parse_group (struct ldap_config_stack *item, struct parse *cfile)
294
{
295
  strncat (cfile->inbuf, "group {\n", LDAP_BUFFER_SIZE);
296
  item->close_brace = 1;
297
}
298
299
300
static void
301
add_to_config_stack (LDAPMessage * res, LDAPMessage * ent)
302
{
303
  struct ldap_config_stack *ns;
304
305
  ns = dmalloc (sizeof (*ns), MDL);
306
  ns->res = res;
307
  ns->ldent = ent;
308
  ns->close_brace = 0;
309
  ns->processed = 0;
310
  ns->next = ldap_stack;
311
  ldap_stack = ns;
312
}
313
314
315
static void
316
ldap_start (void)
317
{
318
  struct option_state *options;
319
  struct option_cache *oc;
320
  struct data_string db;
321
  int ret, version;
322
323
  if (ld != NULL)
324
    return;
325
326
  if (ldap_server == NULL)
327
    {
328
      options = NULL;
329
      option_state_allocate (&options, MDL);
330
331
      execute_statements_in_scope ((struct binding_value **) NULL,
332
                 (struct packet *) NULL, (struct lease *) NULL,
333
                 (struct client_state *) NULL, (struct option_state *) NULL,
334
                 options, &global_scope, root_group, (struct group *) NULL);
335
336
      memset (&db, 0, sizeof (db));
337
      oc = lookup_option (&server_universe, options, SV_LDAP_SERVER);
338
      if (oc &&
339
          evaluate_option_cache (&db,  (struct packet*) NULL,
340
                (struct lease *) NULL, (struct client_state *) NULL,
341
                options, (struct option_state *) NULL, &global_scope, oc, MDL))
342
        {
343
          ldap_server = dmalloc (db.len + 1, MDL);
344
          if (!ldap_server)
345
            log_fatal ("no memory for ldap server");
346
          memcpy (ldap_server, db.data, db.len);
347
          ldap_server[db.len] = 0;
348
          data_string_forget (&db, MDL);
349
        }
350
351
      oc = lookup_option (&server_universe, options, SV_LDAP_USERNAME);
352
      if (oc &&
353
          evaluate_option_cache (&db,  (struct packet*) NULL,
354
                (struct lease *) NULL, (struct client_state *) NULL,
355
                options, (struct option_state *) NULL, &global_scope, oc, MDL))
356
        {
357
          ldap_username = dmalloc (db.len + 1, MDL);
358
          if (!ldap_username)
359
            log_fatal ("no memory for ldap username");
360
          memcpy (ldap_username, db.data, db.len);
361
          ldap_username[db.len] = 0;
362
          data_string_forget (&db, MDL);
363
        }
364
365
      oc = lookup_option (&server_universe, options, SV_LDAP_PASSWORD);
366
      if (oc &&
367
          evaluate_option_cache (&db,  (struct packet*) NULL,
368
                (struct lease *) NULL, (struct client_state *) NULL,
369
                options, (struct option_state *) NULL, &global_scope, oc, MDL))
370
        {
371
          ldap_password = dmalloc (db.len + 1, MDL);
372
          if (!ldap_password)
373
            log_fatal ("no memory for ldap password");
374
          memcpy (ldap_password, db.data, db.len);
375
          ldap_password[db.len] = 0;
376
          data_string_forget (&db, MDL);
377
        }
378
379
      oc = lookup_option (&server_universe, options, SV_LDAP_BASE_DN);
380
      if (oc &&
381
          evaluate_option_cache (&db,  (struct packet*) NULL,
382
                (struct lease *) NULL, (struct client_state *) NULL,
383
                options, (struct option_state *) NULL, &global_scope, oc, MDL))
384
        {
385
          ldap_base_dn = dmalloc (db.len + 1, MDL);
386
          if (!ldap_base_dn)
387
            log_fatal ("no memory for ldap base dn");
388
          memcpy (ldap_base_dn, db.data, db.len);
389
          ldap_base_dn[db.len] = 0;
390
          data_string_forget (&db, MDL);
391
        }
392
393
      oc = lookup_option (&server_universe, options, SV_LDAP_METHOD);
394
      if (oc &&
395
          evaluate_option_cache (&db,  (struct packet*) NULL,
396
                (struct lease *) NULL, (struct client_state *) NULL,
397
                options, (struct option_state *) NULL, &global_scope, oc, MDL))
398
        {
399
400
          if (db.len == 1) 
401
            ldap_method = db.data [0];
402
          else
403
            log_fatal ("invalid ldap method type");
404
          data_string_forget (&db, MDL);
405
        }
406
407
      oc = lookup_option (&server_universe, options, SV_LDAP_DEBUG_FILE);
408
      if (oc &&
409
          evaluate_option_cache (&db,  (struct packet*) NULL,
410
                (struct lease *) NULL, (struct client_state *) NULL,
411
                options, (struct option_state *) NULL, &global_scope, oc, MDL))
412
        {
413
          ldap_debug_file = dmalloc (db.len + 1, MDL);
414
          if (!ldap_debug_file)
415
            log_fatal ("no memory for ldap debug file");
416
          memcpy (ldap_debug_file, db.data, db.len);
417
          ldap_debug_file[db.len] = 0;
418
          data_string_forget (&db, MDL);
419
        }
420
421
      option_state_dereference (&options, MDL);
422
    }
423
424
  if (ldap_server == NULL || ldap_base_dn == NULL)
425
    {
426
      log_info ("Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not specified in the config file");
427
      ldap_method = LDAP_METHOD_STATIC;
428
      return;
429
    }
430
431
  if (ldap_debug_file != NULL && ldap_debug_fd == -1)
432
    {
433
      if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY,
434
                                 S_IRUSR | S_IWUSR)) < 0)
435
        log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file,
436
                   strerror (errno));
437
    }
438
439
#if defined (DEBUG_LDAP)
440
  log_info ("Connecting to LDAP server %s:%d", ldap_server, ldap_port);
441
#endif
442
443
  if ((ld = ldap_init (ldap_server, ldap_port)) == NULL)
444
    {
445
      log_error ("Cannot init ldap session to %s", ldap_server);
446
      return;
447
    }
448
449
  version = LDAP_VERSION3;
450
  if ((ret = ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version)) != LDAP_OPT_SUCCESS)
451
    {
452
      log_error ("Cannot set LDAP version to %d: %s", version,
453
                 ldap_err2string (ret));
454
    }
455
456
#if defined (USE_SSL)
457
  if ((ret = ldap_start_tls_s (ld, NULL, NULL)) != LDAP_SUCCESS)
458
    log_error ("Warning: Cannot start TLS session to %s: %s",
459
               ldap_server, ldap_err2string (ret));
460
  else
461
    log_info ("TLS session successfully started to %s", ldap_server);
462
#endif
463
464
  if (ldap_username != NULL && *ldap_username != '\0')
465
    {
466
      if ((ret = ldap_simple_bind_s (ld, ldap_username,
467
                                     ldap_password)) != LDAP_SUCCESS)
468
        {
469
          log_error ("Error: Cannot login into ldap server %s: %s", ldap_server,
470
                     ldap_err2string (ret));
471
          ldap_unbind (ld);
472
          ld = NULL;
473
          return;
474
        }
475
    }
476
477
#if defined (DEBUG_LDAP)
478
  log_info ("Successfully logged into LDAP server %s", ldap_server);
479
#endif
480
}
481
482
483
static void
484
parse_external_dns (LDAPMessage * ent)
485
{
486
  char *search[] = {"dhcpOptionsDN", "dhcpSharedNetworkDN", "dhcpSubnetDN",
487
                    "dhcpGroupDN", "dhcpHostDN", "dhcpClassesDN",
488
                    "dhcpPoolDN", NULL};
489
  LDAPMessage * newres, * newent;
490
  struct ldap_config_stack *ns;
491
  char **tempstr;
492
  int i, j, ret;
493
#if defined (DEBUG_LDAP)
494
  char *dn;
495
496
  dn = ldap_get_dn (ld, ent);
497
  if (dn != NULL)
498
    {
499
      log_info ("Parsing external DNs for '%s'", dn);
500
      ldap_memfree (dn);
501
    }
502
#endif
503
504
  if (ld == NULL)
505
    ldap_start ();
506
  if (ld == NULL)
507
    return;
508
509
  for (i=0; search[i] != NULL; i++)
510
    {
511
      if ((tempstr = ldap_get_values (ld, ent, search[i])) == NULL)
512
        continue;
513
514
      for (j=0; tempstr[j] != NULL; j++)
515
        {
516
          if (*tempstr[j] == '\0')
517
            continue;
518
519
          if ((ret = ldap_search_s (ld, tempstr[j], LDAP_SCOPE_BASE, 
520
                                    "objectClass=*", NULL, 0, 
521
                                    &newres)) != LDAP_SUCCESS)
522
            {
523
              ldap_value_free (tempstr);
524
              ldap_unbind (ld);
525
              ld = NULL;
526
              return;
527
            }
528
    
529
#if defined (DEBUG_LDAP)
530
          log_info ("Adding contents of subtree '%s' to config stack from '%s' reference", tempstr[j], search[i]);
531
#endif
532
          for (newent = ldap_first_entry (ld, newres);
533
               newent != NULL;
534
               newent = ldap_next_entry (ld, newent))
535
            {
536
#if defined (DEBUG_LDAP)
537
              dn = ldap_get_dn (ld, newent);
538
              if (dn != NULL)
539
                {
540
                  log_info ("Adding LDAP result set starting with '%s' to config stack", dn);
541
                  ldap_memfree (dn);
542
                }
543
#endif
544
545
              add_to_config_stack (newres, newent);
546
              /* don't free newres here */
547
            }
548
        }
549
550
      ldap_value_free (tempstr);
551
    }
552
}
553
554
555
static void
556
free_stack_entry (struct ldap_config_stack *item)
557
{
558
  struct ldap_config_stack *look_ahead_pointer = item;
559
  int may_free_msg = 1;
560
561
  while (look_ahead_pointer->next != NULL)
562
    {
563
      look_ahead_pointer = look_ahead_pointer->next;
564
      if (look_ahead_pointer->res == item->res)
565
        {
566
          may_free_msg = 0;
567
          break;
568
        }
569
    }
570
571
  if (may_free_msg) 
572
    ldap_msgfree (item->res);
573
574
  dfree (item, MDL);
575
}
576
577
578
static void
579
next_ldap_entry (struct parse *cfile)
580
{
581
  struct ldap_config_stack *temp_stack;
582
583
  if (ldap_stack != NULL && ldap_stack->close_brace)
584
    {
585
      strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
586
      ldap_stack->close_brace = 0;
587
    }
588
589
  while (ldap_stack != NULL && 
590
         (ldap_stack->ldent == NULL ||
591
          (ldap_stack->ldent = ldap_next_entry (ld, ldap_stack->ldent)) == NULL))
592
    {
593
      if (ldap_stack->close_brace)
594
        {
595
          strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
596
          ldap_stack->close_brace = 0;
597
        }
598
599
      temp_stack = ldap_stack;
600
      ldap_stack = ldap_stack->next;
601
      free_stack_entry (temp_stack);
602
    }
603
604
  if (ldap_stack != NULL && ldap_stack->close_brace)
605
    {
606
      strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
607
      ldap_stack->close_brace = 0;
608
    }
609
}
610
611
612
static char
613
check_statement_end (const char *statement)
614
{
615
  char *ptr;
616
617
  if (statement == NULL || *statement == '\0')
618
    return ('\0');
619
620
  /*
621
  ** check if it ends with "}", e.g.:
622
  **   "zone my.domain. { ... }"
623
  ** optionally followed by spaces
624
  */
625
  ptr = strrchr (statement, '}');
626
  if (ptr != NULL)
627
    {
628
      /* skip following white-spaces */
629
      for (++ptr; isspace ((int)*ptr); ptr++);
630
631
      /* check if we reached the end */
632
      if (*ptr == '\0')
633
        return ('}'); /* yes, block end */
634
      else
635
        return (*ptr);
636
    }
637
638
  /*
639
  ** this should not happen, but...
640
  ** check if it ends with ";", e.g.:
641
  **   "authoritative;"
642
  ** optionally followed by spaces
643
  */
644
  ptr = strrchr (statement, ';');
645
  if (ptr != NULL)
646
    {
647
      /* skip following white-spaces */
648
      for (++ptr; isspace ((int)*ptr); ptr++);
649
650
      /* check if we reached the end */
651
      if (*ptr == '\0')
652
        return (';'); /* ends with a ; */
653
      else
654
        return (*ptr);
655
    }
656
657
  return ('\0');
658
}
659
660
661
static isc_result_t
662
ldap_parse_entry_options (LDAPMessage *ent, char *buffer, size_t size,
663
                          int *lease_limit)
664
{
665
  char **tempstr;
666
  int i;
667
668
  if (ent == NULL || buffer == NULL || size == 0)
669
    return (ISC_R_FAILURE);
670
671
  if ((tempstr = ldap_get_values (ld, ent, "dhcpStatements")) != NULL)
672
    {
673
      for (i=0; tempstr[i] != NULL; i++)
674
        {
675
          if (lease_limit != NULL &&
676
              strncasecmp ("lease limit ", tempstr[i], 12) == 0)
677
            {
678
              *lease_limit = (int) strtol ((tempstr[i]) + 12, NULL, 10);
679
              continue;
680
            }
681
682
          strncat (buffer, tempstr[i], size);
683
684
          switch((int) check_statement_end (tempstr[i]))
685
            {
686
              case '}':
687
              case ';':
688
                strncat (buffer, "\n", size);
689
                break;
690
              default:
691
                strncat (buffer, ";\n", size);
692
                break;
693
            }
694
        }
695
      ldap_value_free (tempstr);
696
    }
697
698
  if ((tempstr = ldap_get_values (ld, ent, "dhcpOption")) != NULL)
699
    {
700
      for (i=0; tempstr[i] != NULL; i++)
701
        {
702
          strncat (buffer, "option ", size);
703
          strncat (buffer, tempstr[i], size);
704
          switch ((int) check_statement_end (tempstr[i]))
705
            {
706
              case ';':
707
                strncat (buffer, "\n", size);
708
                break;
709
              default:
710
                strncat (buffer, ";\n", size);
711
                break;
712
            }
713
        }
714
      ldap_value_free (tempstr);
715
    }
716
717
  return (ISC_R_SUCCESS);
718
}
719
720
721
static void
722
ldap_generate_config_string (struct parse *cfile)
723
{
724
  char **objectClass, *dn;
725
  struct ldap_config_stack *entry;
726
  LDAPMessage * ent, * res;
727
  int i, j, ignore, found;
728
  int ret;
729
730
  if (ld == NULL)
731
    ldap_start ();
732
  if (ld == NULL)
733
    return;
734
735
  entry = ldap_stack;
736
  if ((objectClass = ldap_get_values (ld, entry->ldent, 
737
                                      "objectClass")) == NULL)
738
    return;
739
    
740
  ignore = 0;
741
  found = 1;
742
  for (i=0; objectClass[i] != NULL; i++)
743
    {
744
      if (strcmp (objectClass[i], "dhcpSharedNetwork") == 0)
745
        ldap_parse_shared_network (entry, cfile);
746
      else if (strcmp (objectClass[i], "dhcpClass") == 0)
747
        ldap_parse_class (entry, cfile);
748
      else if (strcmp (objectClass[i], "dhcpSubnet") == 0)
749
        ldap_parse_subnet (entry, cfile);
750
      else if (strcmp (objectClass[i], "dhcpPool") == 0)
751
        ldap_parse_pool (entry, cfile);
752
      else if (strcmp (objectClass[i], "dhcpGroup") == 0)
753
        ldap_parse_group (entry, cfile);
754
      else if (strcmp (objectClass[i], "dhcpHost") == 0)
755
        {
756
          if (ldap_method == LDAP_METHOD_STATIC)
757
            ldap_parse_host (entry, cfile);
758
          else
759
            {
760
              ignore = 1;
761
              break;
762
            }
763
        }
764
      else if (strcmp (objectClass[i], "dhcpSubClass") == 0)
765
        {
766
          if (ldap_method == LDAP_METHOD_STATIC)
767
            ldap_parse_subclass (entry, cfile);
768
          else
769
            {
770
              ignore = 1;
771
              break;
772
            }
773
        }
774
      else
775
        found = 0;
776
777
      if (found && cfile->inbuf[0] == '\0')
778
        {
779
          ignore = 1;
780
          break;
781
        }
782
    }
783
784
  ldap_value_free (objectClass);
785
786
  if (ignore)
787
    {
788
      next_ldap_entry (cfile);
789
      return;
790
    }
791
792
  ldap_parse_entry_options(entry->ldent, cfile->inbuf,
793
                           LDAP_BUFFER_SIZE-1, NULL);
794
795
  dn = ldap_get_dn (ld, entry->ldent);
796
797
#if defined(DEBUG_LDAP)
798
  if (dn != NULL)
799
    log_info ("Found LDAP entry '%s'", dn);
800
#endif
801
802
  if (dn == NULL ||
803
      (ret = ldap_search_s (ld, dn, LDAP_SCOPE_ONELEVEL, "objectClass=*", 
804
                            NULL, 0, &res)) != LDAP_SUCCESS)
805
    {
806
      if (dn)
807
        ldap_memfree (dn);
808
809
      ldap_unbind (ld);
810
      ld = NULL;
811
      return;
812
    }
813
814
  ldap_memfree (dn);
815
816
  if ((ent = ldap_first_entry (ld, res)) != NULL)
817
    {
818
      add_to_config_stack (res, ent);
819
      parse_external_dns (entry->ldent);
820
    }
821
  else
822
    {
823
      ldap_msgfree (res);
824
      parse_external_dns (entry->ldent);
825
      next_ldap_entry (cfile);
826
    }
827
}
828
829
830
static void
831
ldap_close_debug_fd()
832
{
833
  if (ldap_debug_fd != -1)
834
    {
835
      close (ldap_debug_fd);
836
      ldap_debug_fd = -1;
837
    }
838
}
839
840
841
static void
842
ldap_write_debug (const void *buff, size_t size)
843
{
844
  if (ldap_debug_fd != -1)
845
    {
846
      if (write (ldap_debug_fd, buff, size) < 0)
847
        {
848
          log_error ("Error writing to LDAP debug file %s: %s."
849
                     " Disabling log file.", ldap_debug_file,
850
                     strerror (errno));
851
          ldap_close_debug_fd();
852
        }
853
    }
854
}
855
856
static char
857
ldap_read_function (struct parse *cfile)
858
{
859
  char eofstring[2] = {EOF, '\0'};
860
 
861
  cfile->inbuf[0] = '\0';
862
  cfile->buflen = 0;
863
864
  while (ldap_stack != NULL && *cfile->inbuf == '\0')
865
    ldap_generate_config_string (cfile);
866
867
  cfile->buflen = strlen (cfile->inbuf);
868
  if (cfile->buflen > 0)
869
    ldap_write_debug (cfile->inbuf, cfile->buflen);
870
871
#if defined (DEBUG_LDAP)
872
  log_info ("Sending config line '%s'", cfile->inbuf);
873
#endif
874
875
  if (ldap_stack == NULL)
876
    strncat (cfile->inbuf, eofstring, LDAP_BUFFER_SIZE);
877
878
  cfile->buflen = strlen (cfile->inbuf);
879
  cfile->bufix = 1;
880
881
  return (cfile->inbuf[0]);
882
}
883
884
885
static char *
886
ldap_get_host_name (LDAPMessage * ent)
887
{
888
  char **name, *ret;
889
890
  ret = NULL;
891
  if ((name = ldap_get_values (ld, ent, "cn")) == NULL || name[0] == NULL)
892
    {
893
      if (name != NULL)
894
        ldap_value_free (name);
895
896
#if defined (DEBUG_LDAP)
897
      ret = ldap_get_dn (ld, ent);
898
      if (ret != NULL)
899
        {
900
          log_info ("Cannot get cn attribute for LDAP entry %s", ret);
901
          ldap_memfree(ret);
902
        }
903
#endif
904
      return (NULL);
905
    }
906
907
  ret = dmalloc (strlen (name[0]) + 1, MDL);
908
  strcpy (ret, name[0]);
909
  ldap_value_free (name);
910
911
  return (ret);
912
}
913
914
915
static int
916
getfqhostname(char *fqhost, size_t size)
917
{
918
#if defined(MAXHOSTNAMELEN)
919
  char   hname[MAXHOSTNAMELEN];
920
#else
921
  char   hname[65];
922
#endif
923
  struct hostent *hp;
924
925
  if(NULL == fqhost || 1 >= size)
926
    return -1;
927
928
  memset(hname, 0, sizeof(hname));
929
  if( gethostname(hname, sizeof(hname)-1))
930
    return -1;
931
932
  if(NULL == (hp = gethostbyname(hname)))
933
    return -1;
934
935
  strncpy(fqhost, hp->h_name, size-1);
936
  fqhost[size-1] = '\0';
937
  return 0;
938
}
939
940
941
isc_result_t
942
ldap_read_config (void)
943
{
944
  LDAPMessage * ldres, * hostres, * ent, * hostent;
945
  char hfilter[1024], sfilter[1024], fqdn[257];
946
  char *buffer, **tempstr = NULL, *hostdn;
947
  ldap_dn_node *curr = NULL;
948
  struct parse *cfile;
949
  struct utsname unme;
950
  isc_result_t res;
951
  size_t length;
952
  int ret, cnt;
953
954
  if (ld == NULL)
955
    ldap_start ();
956
  if (ld == NULL)
957
    return (ldap_server == NULL ? ISC_R_SUCCESS : ISC_R_FAILURE);
958
 
959
  buffer = dmalloc (LDAP_BUFFER_SIZE+1, MDL);
960
  if (buffer == NULL)
961
    return (ISC_R_FAILURE);
962
963
  cfile = (struct parse *) NULL;
964
  res = new_parse (&cfile, -1, buffer, LDAP_BUFFER_SIZE, "LDAP", 0);
965
  if (res != ISC_R_SUCCESS)
966
    return (res);
967
 
968
  uname (&unme);
969
  if(0 == getfqhostname(fqdn, sizeof(fqdn)))
970
    {
971
      snprintf (hfilter, sizeof (hfilter),
972
                "(&(objectClass=dhcpServer)(|(cn=%s)(cn=%s)))", 
973
                unme.nodename, fqdn);
974
    }
975
  else
976
    {
977
      snprintf (hfilter, sizeof (hfilter),
978
                "(&(objectClass=dhcpServer)(cn=%s))", unme.nodename);
979
    }
980
981
  hostres = NULL;
982
  if ((ret = ldap_search_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE,
983
                            hfilter, NULL, 0, &hostres)) != LDAP_SUCCESS)
984
    {
985
      log_error ("Cannot find host LDAP entry %s %s",
986
                 unme.nodename, hfilter);
987
      if(NULL != hostres)
988
        ldap_msgfree (hostres);
989
      ldap_unbind (ld);
990
      ld = NULL;
991
      return (ISC_R_FAILURE);
992
    }
993
994
  if ((hostent = ldap_first_entry (ld, hostres)) == NULL)
995
    {
996
      log_error ("Error: Cannot find LDAP entry matching %s", hfilter);
997
      ldap_msgfree (hostres);
998
      ldap_unbind (ld);
999
      ld = NULL;
1000
      return (ISC_R_FAILURE);
1001
    }
1002
1003
  hostdn = ldap_get_dn (ld, hostent);
1004
#if defined(DEBUG_LDAP)
1005
  if (hostdn != NULL)
1006
    log_info ("Found dhcpServer LDAP entry '%s'", hostdn);
1007
#endif
1008
1009
  if (hostdn == NULL ||
1010
      (tempstr = ldap_get_values (ld, hostent, "dhcpServiceDN")) == NULL ||
1011
      tempstr[0] == NULL)
1012
    {
1013
      log_error ("Error: Cannot find LDAP entry matching %s", hfilter);
1014
1015
      if (tempstr != NULL)
1016
        ldap_value_free (tempstr);
1017
1018
      if (hostdn)
1019
        ldap_memfree (hostdn);
1020
      ldap_msgfree (hostres);
1021
      ldap_unbind (ld);
1022
      ld = NULL;
1023
      return (ISC_R_FAILURE);
1024
    }
1025
1026
#if defined(DEBUG_LDAP)
1027
  log_info ("LDAP: Parsing dhcpServer options '%s' ...", hostdn);
1028
#endif
1029
1030
  cfile->inbuf[0] = '\0';
1031
  ldap_parse_entry_options(hostent, cfile->inbuf, LDAP_BUFFER_SIZE, NULL);
1032
  cfile->buflen = strlen (cfile->inbuf);
1033
  if(cfile->buflen > 0)
1034
    {
1035
      ldap_write_debug (cfile->inbuf, cfile->buflen);
1036
1037
      res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
1038
      if (res != ISC_R_SUCCESS)
1039
        {
1040
          log_error ("LDAP: cannot parse dhcpServer entry '%s'", hostdn);
1041
          ldap_memfree (hostdn);
1042
          ldap_unbind (ld);
1043
          ld = NULL;
1044
          return res;
1045
        }
1046
      cfile->inbuf[0] = '\0';
1047
    }
1048
  ldap_msgfree (hostres);
1049
1050
  /*
1051
  ** attach ldap (tree) read function now
1052
  */
1053
  cfile->bufix = cfile->buflen = 0;
1054
  cfile->read_function = ldap_read_function;
1055
1056
  res = ISC_R_SUCCESS;
1057
  for (cnt=0; tempstr[cnt] != NULL; cnt++)
1058
    {
1059
      snprintf(sfilter, sizeof(sfilter), "(&(objectClass=dhcpService)"
1060
                        "(|(dhcpPrimaryDN=%s)(dhcpSecondaryDN=%s)))",
1061
                        hostdn, hostdn);
1062
      ldres = NULL;
1063
      if ((ret = ldap_search_s (ld, tempstr[cnt], LDAP_SCOPE_BASE,
1064
                                sfilter, NULL, 0, &ldres)) != LDAP_SUCCESS)
1065
        {
1066
          log_error ("Error searching for dhcpServiceDN '%s': %s. Please update the LDAP entry '%s'",
1067
                     tempstr[cnt], ldap_err2string (ret), hostdn);
1068
          if(NULL != ldres)
1069
            ldap_msgfree(ldres);
1070
          res = ISC_R_FAILURE;
1071
          break;
1072
        }
1073
1074
      if ((ent = ldap_first_entry (ld, ldres)) == NULL)
1075
        {
1076
          log_error ("Error: Cannot find dhcpService DN '%s' with primary or secondary server reference. Please update the LDAP server entry '%s'",
1077
                     tempstr[cnt], hostdn);
1078
1079
          ldap_msgfree(ldres);
1080
          res = ISC_R_FAILURE;
1081
          break;
1082
        }
1083
1084
      /*
1085
      ** FIXME: how to free the remembered dn's on exit?
1086
      **        This should be OK if dmalloc registers the
1087
      **        memory it allocated and frees it on exit..
1088
      */
1089
1090
      curr = dmalloc (sizeof (*curr), MDL);
1091
      if (curr != NULL)
1092
        {
1093
          length = strlen (tempstr[cnt]);
1094
          curr->dn = dmalloc (length + 1, MDL);
1095
          if (curr->dn == NULL)
1096
            {
1097
              dfree (curr, MDL);
1098
              curr = NULL;
1099
            }
1100
          else
1101
            strcpy (curr->dn, tempstr[cnt]);
1102
        }
1103
1104
      if (curr != NULL)
1105
        {
1106
          curr->refs++;
1107
1108
          /* append to service-dn list */
1109
          if (ldap_service_dn_tail != NULL)
1110
            ldap_service_dn_tail->next = curr;
1111
          else
1112
            ldap_service_dn_head = curr;
1113
1114
          ldap_service_dn_tail = curr;
1115
        }
1116
      else
1117
        log_fatal ("no memory to remember ldap service dn");
1118
1119
#if defined (DEBUG_LDAP)
1120
      log_info ("LDAP: Parsing dhcpService DN '%s' ...", tempstr[cnt]);
1121
#endif
1122
      add_to_config_stack (ldres, ent);
1123
      res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
1124
      if (res != ISC_R_SUCCESS)
1125
        {
1126
          log_error ("LDAP: cannot parse dhcpService entry '%s'", tempstr[cnt]);
1127
          break;
1128
        }
1129
    }
1130
1131
  end_parse (&cfile);
1132
  ldap_close_debug_fd();
1133
1134
  ldap_memfree (hostdn);
1135
  ldap_value_free (tempstr);
1136
1137
  if (res != ISC_R_SUCCESS)
1138
    {
1139
      struct ldap_config_stack *temp_stack;
1140
1141
      while ((curr = ldap_service_dn_head) != NULL)
1142
        {
1143
          ldap_service_dn_head = curr->next;
1144
          dfree (curr->dn, MDL);
1145
          dfree (curr, MDL);
1146
        }
1147
1148
      ldap_service_dn_tail = NULL;
1149
1150
      while ((temp_stack = ldap_stack) != NULL)
1151
        {
1152
          ldap_stack = temp_stack->next;
1153
          free_stack_entry (temp_stack);
1154
        }
1155
1156
      ldap_unbind (ld);
1157
      ld = NULL;
1158
    }
1159
1160
  return (res);
1161
}
1162
1163
1164
/* This function will parse the dhcpOption and dhcpStatements field in the LDAP
1165
   entry if it exists. Right now, type will be either HOST_DECL or CLASS_DECL.
1166
   If we are parsing a HOST_DECL, this always returns 0. If we are parsing a 
1167
   CLASS_DECL, this will return what the current lease limit is in LDAP. If
1168
   there is no lease limit specified, we return 0 */
1169
1170
static int
1171
ldap_parse_options (LDAPMessage * ent, struct group *group,
1172
                         int type, struct host_decl *host,
1173
                         struct class **class)
1174
{
1175
  int i, declaration, lease_limit;
1176
  char option_buffer[8192];
1177
  enum dhcp_token token;
1178
  struct parse *cfile;
1179
  isc_result_t res;
1180
  const char *val;
1181
1182
  lease_limit = 0;
1183
  *option_buffer = '\0';
1184
  res = ldap_parse_entry_options (ent, option_buffer, sizeof(option_buffer) - 1,
1185
                                  &lease_limit);
1186
  if (res != ISC_R_SUCCESS)
1187
    return (lease_limit);
1188
1189
  option_buffer[sizeof(option_buffer) - 1] = '\0';
1190
  if (*option_buffer == '\0')
1191
    return (lease_limit);
1192
1193
  cfile = (struct parse *) NULL;
1194
  res = new_parse (&cfile, -1, option_buffer, strlen (option_buffer), 
1195
                   type == HOST_DECL ? "LDAP-HOST" : "LDAP-SUBCLASS", 0);
1196
  if (res != ISC_R_SUCCESS)
1197
    return (lease_limit);
1198
1199
#if defined (DEBUG_LDAP)
1200
  log_info ("Sending the following options: '%s'", option_buffer);
1201
#endif
1202
1203
  declaration = 0;
1204
  do
1205
    {
1206
      token = peek_token (&val, NULL, cfile);
1207
      if (token == END_OF_FILE)
1208
        break;
1209
       declaration = parse_statement (cfile, group, type, host, declaration);
1210
    } while (1);
1211
1212
  end_parse (&cfile);
1213
1214
  return (lease_limit);
1215
}
1216
1217
1218
1219
int
1220
find_haddr_in_ldap (struct host_decl **hp, int htype, unsigned hlen,
1221
                    const unsigned char *haddr, const char *file, int line)
1222
{
1223
  char buf[128], *type_str, **tempstr, *addr_str;
1224
  LDAPMessage * res, *ent;
1225
  struct host_decl * host;
1226
  isc_result_t status;
1227
  ldap_dn_node *curr;
1228
  int ret;
1229
1230
  if (ldap_method == LDAP_METHOD_STATIC)
1231
    return (0);
1232
1233
  if (ld == NULL)
1234
    ldap_start ();
1235
  if (ld == NULL)
1236
    return (0);
1237
1238
  switch (htype)
1239
    {
1240
      case HTYPE_ETHER:
1241
        type_str = "ethernet";
1242
        break;
1243
      case HTYPE_IEEE802:
1244
        type_str = "token-ring";
1245
        break;
1246
      case HTYPE_FDDI:
1247
        type_str = "fddi";
1248
        break;
1249
      default:
1250
        log_info ("Ignoring unknown type %d", htype);
1251
        return (0);
1252
    }
1253
1254
  /*
1255
  ** FIXME: dhcpHWAddress attribute uses octetStringMatch
1256
  **        (what means exact octet match, case sensitive)!
1257
  **
1258
  **        it is not guaranted, that ldap contains _exactly_
1259
  **        "type addr" with one space between!
1260
  **        AFAIK print_hw_addr() produces a lower case string.
1261
  */
1262
  snprintf (buf, sizeof (buf),
1263
            "(&(objectClass=dhcpHost)(dhcpHWAddress=%s %s))",
1264
           type_str, print_hw_addr (htype, hlen, haddr));
1265
1266
  res = ent = NULL;
1267
  for (curr = ldap_service_dn_head;
1268
       curr != NULL && *curr->dn != '\0';
1269
       curr = curr->next)
1270
    {
1271
#if defined (DEBUG_LDAP)
1272
      log_info ("Searching for %s in LDAP tree %s", buf, curr->dn);
1273
#endif
1274
      ret = ldap_search_s (ld, curr->dn, LDAP_SCOPE_SUBTREE,
1275
                           buf, NULL, 0, &res);
1276
      if (ret == LDAP_SUCCESS)
1277
        {
1278
          if( (ent = ldap_first_entry (ld, res)) != NULL)
1279
            break; /* search OK and have entry */
1280
1281
#if defined (DEBUG_LDAP)
1282
          log_info ("No host entry for %s in LDAP tree %s",
1283
                    buf, curr->dn);
1284
#endif
1285
          if(res)
1286
            {
1287
              ldap_msgfree (res);
1288
              res = NULL;
1289
            }
1290
        }
1291
      else
1292
        {
1293
          if(res)
1294
            {
1295
              ldap_msgfree (res);
1296
              res = NULL;
1297
            }
1298
1299
          if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
1300
            {
1301
              log_error ("Cannot search for %s in LDAP tree %s: %s", buf, 
1302
                         curr->dn, ldap_err2string (ret));
1303
              ldap_unbind (ld);
1304
              ld = NULL;
1305
              return (0);
1306
            }
1307
#if defined (DEBUG_LDAP)
1308
          else
1309
            {
1310
              log_info ("ldap_search_s returned %s when searching for %s in %s",
1311
                        ldap_err2string (ret), buf, curr->dn);
1312
            }
1313
#endif
1314
        }
1315
    }
1316
1317
  if (res && ent)
1318
    {
1319
#if defined (DEBUG_LDAP)
1320
      char *dn = ldap_get_dn (ld, ent);
1321
      if (dn != NULL)
1322
        {
1323
          log_info ("Found dhcpHWAddress LDAP entry %s", dn);
1324
          ldap_memfree(dn);
1325
        }
1326
#endif
1327
1328
      host = (struct host_decl *)0;
1329
      status = host_allocate (&host, MDL);
1330
      if (status != ISC_R_SUCCESS)
1331
        {
1332
          log_fatal ("can't allocate host decl struct: %s", 
1333
                     isc_result_totext (status)); 
1334
          ldap_msgfree (res);
1335
          return (0);
1336
        }
1337
1338
      host->name = ldap_get_host_name (ent);
1339
      if (host->name == NULL)
1340
        {
1341
          host_dereference (&host, MDL);
1342
          ldap_msgfree (res);
1343
          return (0);
1344
        }
1345
1346
      if (!clone_group (&host->group, root_group, MDL))
1347
        {
1348
          log_fatal ("can't clone group for host %s", host->name);
1349
          host_dereference (&host, MDL);
1350
          ldap_msgfree (res);
1351
          return (0);
1352
        }
1353
1354
      /*
1355
      ** PROBLEM: since dhcpd uses no unique names for groups,
1356
      **          it seems to be not possible to find the right
1357
      **          one, our host may belong to.
1358
      **
1359
      ** PERHAPS: Check if parent DN is a dhcpGroup or the host-dn
1360
      **          is referenced via dhcpHostDN in a dhcpGroup.
1361
      **          If found, we may fetch and apply group options
1362
      **          and statements to above host->group ?
1363
      */
1364
      ldap_parse_options (ent, host->group, HOST_DECL, host, NULL);
1365
1366
      *hp = host;
1367
      ldap_msgfree (res);
1368
      return (1);
1369
    }
1370
1371
1372
  if(res) ldap_msgfree (res);
1373
  return (0);
1374
}
1375
1376
1377
int
1378
find_subclass_in_ldap (struct class *class, struct class **newclass, 
1379
                       struct data_string *data)
1380
{
1381
  LDAPMessage * res, * ent;
1382
  int i, ret, lease_limit;
1383
  isc_result_t status;
1384
  ldap_dn_node *curr;
1385
  char buf[1024];
1386
1387
  if (ldap_method == LDAP_METHOD_STATIC)
1388
    return (0);
1389
1390
  if (ld == NULL)
1391
    ldap_start ();
1392
  if (ld == NULL)
1393
    return (0);
1394
1395
  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));
1396
#if defined (DEBUG_LDAP)
1397
  log_info ("Searching LDAP for %s", buf);
1398
#endif
1399
1400
  res = ent = NULL;
1401
  for (curr = ldap_service_dn_head;
1402
       curr != NULL && *curr->dn != '\0';
1403
       curr = curr->next)
1404
    {
1405
#if defined (DEBUG_LDAP)
1406
      log_info ("Searching for %s in LDAP tree %s", buf, curr->dn);
1407
#endif
1408
      ret = ldap_search_s (ld, curr->dn, LDAP_SCOPE_SUBTREE,
1409
                           buf, NULL, 0, &res);
1410
      if (ret == LDAP_SUCCESS)
1411
        {
1412
          if( (ent = ldap_first_entry (ld, res)) != NULL)
1413
            break; /* search OK and have entry */
1414
1415
#if defined (DEBUG_LDAP)
1416
          log_info ("No subclass entry for %s in LDAP tree %s",
1417
                    buf, curr->dn);
1418
#endif
1419
          if(res)
1420
            {
1421
              ldap_msgfree (res);
1422
              res = NULL;
1423
            }
1424
        }
1425
      else
1426
        {
1427
          if(res)
1428
            {
1429
              ldap_msgfree (res);
1430
              res = NULL;
1431
            }
1432
1433
          if (ret != LDAP_NO_SUCH_OBJECT && ret != LDAP_SUCCESS)
1434
            {
1435
              log_error ("Cannot search for %s in LDAP tree %s: %s", buf, 
1436
                         curr->dn, ldap_err2string (ret));
1437
              ldap_unbind (ld);
1438
              ld = NULL;
1439
              return (0);
1440
            }
1441
#if defined (DEBUG_LDAP)
1442
          else
1443
            {
1444
              log_info ("ldap_search_s returned %s when searching for %s in %s",
1445
                        ldap_err2string (ret), buf, curr->dn);
1446
            }
1447
#endif
1448
        }
1449
    }
1450
1451
  if (res && ent)
1452
    {
1453
#if defined (DEBUG_LDAP)
1454
      char *dn = ldap_get_dn (ld, ent);
1455
      if (dn != NULL)
1456
        {
1457
          log_info ("Found subclass LDAP entry %s", dn);
1458
          ldap_memfree(dn);
1459
        }
1460
#endif
1461
1462
      status = class_allocate (newclass, MDL);
1463
      if (status != ISC_R_SUCCESS)
1464
        {
1465
          log_error ("Cannot allocate memory for a new class");
1466
          ldap_msgfree (res);
1467
          return (0);
1468
        }
1469
1470
      group_reference (&(*newclass)->group, class->group, MDL);
1471
      class_reference (&(*newclass)->superclass, class, MDL);
1472
      lease_limit = ldap_parse_options (ent, (*newclass)->group, 
1473
                                        CLASS_DECL, NULL, newclass);
1474
      if (lease_limit == 0)
1475
        (*newclass)->lease_limit = class->lease_limit; 
1476
      else
1477
        class->lease_limit = lease_limit;
1478
1479
      if ((*newclass)->lease_limit) 
1480
        {
1481
          (*newclass)->billed_leases = 
1482
              dmalloc ((*newclass)->lease_limit * sizeof (struct lease *), MDL);
1483
          if (!(*newclass)->billed_leases) 
1484
            {
1485
              log_error ("no memory for billing");
1486
              class_dereference (newclass, MDL);
1487
              ldap_msgfree (res);
1488
              return (0);
1489
            }
1490
          memset ((*newclass)->billed_leases, 0, 
1491
                ((*newclass)->lease_limit * sizeof (*newclass)->billed_leases));
1492
        }
1493
1494
      data_string_copy (&(*newclass)->hash_string, data, MDL);
1495
1496
      ldap_msgfree (res);
1497
      return (1);
1498
    }
1499
1500
  if(res) ldap_msgfree (res);
1501
  return (0);
1502
}
1503
1504
#endif
1505
(-)dhcp-3.0.1/server/Makefile.dist (-2 / +2 lines)
Lines 25-33 Link Here
25
CATMANPAGES = dhcpd.cat8 dhcpd.conf.cat5 dhcpd.leases.cat5
25
CATMANPAGES = dhcpd.cat8 dhcpd.conf.cat5 dhcpd.leases.cat5
26
SEDMANPAGES = dhcpd.man8 dhcpd.conf.man5 dhcpd.leases.man5
26
SEDMANPAGES = dhcpd.man8 dhcpd.conf.man5 dhcpd.leases.man5
27
SRCS   = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \
27
SRCS   = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \
28
	 omapi.c mdb.c stables.c salloc.c ddns.c
28
	 ldap.c omapi.c mdb.c stables.c salloc.c ddns.c
29
OBJS   = dhcpd.o dhcp.o bootp.o confpars.o db.o class.o failover.o \
29
OBJS   = dhcpd.o dhcp.o bootp.o confpars.o db.o class.o failover.o \
30
	 omapi.o mdb.o stables.o salloc.o ddns.o
30
	 ldap.o omapi.o mdb.o stables.o salloc.o ddns.o
31
PROG   = dhcpd
31
PROG   = dhcpd
32
MAN    = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5
32
MAN    = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5
33
33
(-)dhcp-3.0.1/server/mdb.c (+6 lines)
Lines 375-380 Link Here
375
{
375
{
376
	struct host_decl *foo;
376
	struct host_decl *foo;
377
	struct hardware h;
377
	struct hardware h;
378
	int ret;
379
380
#if defined(LDAP_CONFIGURATION)
381
	if ((ret = find_haddr_in_ldap (hp, htype, hlen, haddr, file, line)))
382
		return ret;
383
#endif
378
384
379
	h.hlen = hlen + 1;
385
	h.hlen = hlen + 1;
380
	h.hbuf [0] = htype;
386
	h.hbuf [0] = htype;
(-)dhcp-3.0.1/server/stables.c (+24 lines)
Lines 483-488 Link Here
483
	{ "log-facility", "Nsyslog-facilities.",	&server_universe, 44 },
483
	{ "log-facility", "Nsyslog-facilities.",	&server_universe, 44 },
484
	{ "do-forward-updates", "f",			&server_universe, 45 },
484
	{ "do-forward-updates", "f",			&server_universe, 45 },
485
	{ "ping-timeout", "T",				&server_universe, 46 },
485
	{ "ping-timeout", "T",				&server_universe, 46 },
486
#if defined(LDAP_CONFIGURATION)
487
	{ "ldap-server", "t",				&server_universe, 47 },
488
	{ "ldap-port", "d",				&server_universe, 48 },
489
	{ "ldap-username", "t",				&server_universe, 49 },
490
	{ "ldap-password", "t",				&server_universe, 50 },
491
	{ "ldap-base-dn", "t",				&server_universe, 51 },
492
	{ "ldap-method", "Nldap-methods.",		&server_universe, 52 },
493
	{ "ldap-debug-file", "t",			&server_universe, 53 },
494
#else
486
	{ "unknown-47", "X",				&server_universe, 47 },
495
	{ "unknown-47", "X",				&server_universe, 47 },
487
	{ "unknown-48", "X",				&server_universe, 48 },
496
	{ "unknown-48", "X",				&server_universe, 48 },
488
	{ "unknown-49", "X",				&server_universe, 49 },
497
	{ "unknown-49", "X",				&server_universe, 49 },
Lines 490-495 Link Here
490
	{ "unknown-51", "X",				&server_universe, 51 },
499
	{ "unknown-51", "X",				&server_universe, 51 },
491
	{ "unknown-52", "X",				&server_universe, 52 },
500
	{ "unknown-52", "X",				&server_universe, 52 },
492
	{ "unknown-53", "X",				&server_universe, 53 },
501
	{ "unknown-53", "X",				&server_universe, 53 },
502
#endif
493
	{ "unknown-54", "X",				&server_universe, 54 },
503
	{ "unknown-54", "X",				&server_universe, 54 },
494
	{ "unknown-55", "X",				&server_universe, 55 },
504
	{ "unknown-55", "X",				&server_universe, 55 },
495
	{ "unknown-56", "X",				&server_universe, 56 },
505
	{ "unknown-56", "X",				&server_universe, 56 },
Lines 694-699 Link Here
694
	{ "option-end", "e",				&server_universe, 255 },
704
	{ "option-end", "e",				&server_universe, 255 },
695
};
705
};
696
706
707
#if defined(LDAP_CONFIGURATION)
708
struct enumeration_value ldap_values [] = {
709
	{ "static", LDAP_METHOD_STATIC },
710
	{ "dynamic", LDAP_METHOD_DYNAMIC },
711
	{ (char *) 0, 0 }
712
};
713
714
struct enumeration ldap_methods = {
715
	(struct enumeration *)0,
716
	"ldap-methods",
717
	ldap_values
718
};
719
#endif
720
697
struct enumeration_value ddns_styles_values [] = {
721
struct enumeration_value ddns_styles_values [] = {
698
	{ "none", 0 },
722
	{ "none", 0 },
699
	{ "ad-hoc", 1 },
723
	{ "ad-hoc", 1 },
(-)dhcp-3.0.1/site.conf (+1 lines)
Lines 1-2 Link Here
1
# Put local site configuration stuff here to override the default
1
# Put local site configuration stuff here to override the default
2
# settings in Makefile.conf
2
# settings in Makefile.conf
3
#COPTS = -DDEBUG_LDAP -DDEBUG_CLASS_MATCHING -Wall -O -Wno-unused

Return to bug 72355