3274 lines
103 KiB
Diff
3274 lines
103 KiB
Diff
|
--- dhcp-3.0.5/common/conflex.c.ldapconf 2007-01-31 20:39:38.000000000 -0500
|
||
|
+++ dhcp-3.0.5/common/conflex.c 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -47,6 +47,7 @@
|
||
|
static enum dhcp_token read_number PROTO ((int, struct parse *));
|
||
|
static enum dhcp_token read_num_or_name PROTO ((int, struct parse *));
|
||
|
static enum dhcp_token intern PROTO ((char *, enum dhcp_token));
|
||
|
+static char read_function PROTO ((struct parse *));
|
||
|
|
||
|
isc_result_t new_parse (cfile, file, inbuf, buflen, name, eolp)
|
||
|
struct parse **cfile;
|
||
|
@@ -74,6 +75,10 @@
|
||
|
tmp -> file = file;
|
||
|
tmp -> eol_token = eolp;
|
||
|
|
||
|
+ if (file != -1) {
|
||
|
+ tmp -> read_function = read_function;;
|
||
|
+ }
|
||
|
+
|
||
|
tmp -> bufix = 0;
|
||
|
tmp -> buflen = buflen;
|
||
|
if (inbuf) {
|
||
|
@@ -113,22 +118,11 @@
|
||
|
int c;
|
||
|
|
||
|
if (cfile -> bufix == cfile -> buflen) {
|
||
|
- if (cfile -> file != -1) {
|
||
|
- cfile -> buflen =
|
||
|
- read (cfile -> file,
|
||
|
- cfile -> inbuf, cfile -> bufsiz);
|
||
|
- if (cfile -> buflen == 0) {
|
||
|
- c = EOF;
|
||
|
- cfile -> bufix = 0;
|
||
|
- } else if (cfile -> buflen < 0) {
|
||
|
- c = EOF;
|
||
|
- cfile -> bufix = cfile -> buflen = 0;
|
||
|
- } else {
|
||
|
- c = cfile -> inbuf [0];
|
||
|
- cfile -> bufix = 1;
|
||
|
- }
|
||
|
- } else
|
||
|
+ if (cfile -> read_function) {
|
||
|
+ c = cfile -> read_function (cfile);
|
||
|
+ } else {
|
||
|
c = EOF;
|
||
|
+ }
|
||
|
} else {
|
||
|
c = cfile -> inbuf [cfile -> bufix];
|
||
|
cfile -> bufix++;
|
||
|
@@ -1130,3 +1124,25 @@
|
||
|
}
|
||
|
return dfv;
|
||
|
}
|
||
|
+
|
||
|
+
|
||
|
+static char
|
||
|
+read_function (struct parse * cfile)
|
||
|
+{
|
||
|
+ char c;
|
||
|
+
|
||
|
+ cfile -> buflen = read (cfile -> file, cfile -> inbuf, cfile -> bufsiz);
|
||
|
+ if (cfile -> buflen == 0) {
|
||
|
+ c = EOF;
|
||
|
+ cfile -> bufix = 0;
|
||
|
+ } else if (cfile -> buflen < 0) {
|
||
|
+ c = EOF;
|
||
|
+ cfile -> bufix = cfile -> buflen = 0;
|
||
|
+ } else {
|
||
|
+ c = cfile -> inbuf [0];
|
||
|
+ cfile -> bufix = 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ return c;
|
||
|
+}
|
||
|
+
|
||
|
--- dhcp-3.0.5/common/print.c.ldapconf 2007-01-31 20:39:38.000000000 -0500
|
||
|
+++ dhcp-3.0.5/common/print.c 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -166,9 +166,9 @@
|
||
|
}
|
||
|
|
||
|
char *print_hw_addr (htype, hlen, data)
|
||
|
- int htype;
|
||
|
- int hlen;
|
||
|
- unsigned char *data;
|
||
|
+ const int htype;
|
||
|
+ const int hlen;
|
||
|
+ const unsigned char *data;
|
||
|
{
|
||
|
static char habuf [49];
|
||
|
char *s;
|
||
|
--- /dev/null 2007-01-31 10:24:38.956568237 -0500
|
||
|
+++ dhcp-3.0.5/contrib/dhcpd-conf-to-ldap.pl 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -0,0 +1,517 @@
|
||
|
+#!/usr/bin/perl -w
|
||
|
+
|
||
|
+# Brian Masney <masneyb@ntelos.net>
|
||
|
+# To use this script, set your base DN below. Then run
|
||
|
+# ./dhcpd-conf-to-ldap.pl < /path-to-dhcpd-conf/dhcpd.conf > output-file
|
||
|
+# The output of this script will generate entries in LDIF format. You can use
|
||
|
+# the slapadd command to add these entries into your LDAP server. You will
|
||
|
+# definately want to double check that your LDAP entries are correct before
|
||
|
+# you load them into LDAP.
|
||
|
+
|
||
|
+# This script does not do much error checking. Make sure before you run this
|
||
|
+# that the DHCP server doesn't give any errors about your config file
|
||
|
+
|
||
|
+use Sys::Hostname;
|
||
|
+
|
||
|
+my $basedn = "dc=ntelos, dc=net";
|
||
|
+
|
||
|
+sub next_token
|
||
|
+{
|
||
|
+ local ($lowercase) = @_;
|
||
|
+ local ($token, $newline);
|
||
|
+
|
||
|
+ do
|
||
|
+ {
|
||
|
+ if (!defined ($line) || length ($line) == 0)
|
||
|
+ {
|
||
|
+ $line = <>;
|
||
|
+ return undef if !defined ($line);
|
||
|
+ chop $line;
|
||
|
+ $line_number++;
|
||
|
+ $token_number = 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ $line =~ s/#.*//;
|
||
|
+ $line =~ s/^\s+//;
|
||
|
+ $line =~ s/\s+$//;
|
||
|
+ }
|
||
|
+ while (length ($line) == 0);
|
||
|
+
|
||
|
+ if (($token, $newline) = $line =~ /^(.*?)\s+(.*)/)
|
||
|
+ {
|
||
|
+ $line = $newline;
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ $token = $line;
|
||
|
+ $line = '';
|
||
|
+ }
|
||
|
+ $token_number++;
|
||
|
+
|
||
|
+ $token =~ y/[A-Z]/[a-z]/ if $lowercase;
|
||
|
+
|
||
|
+ return ($token);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub remaining_line
|
||
|
+{
|
||
|
+ local ($tmp, $str);
|
||
|
+
|
||
|
+ $str = "";
|
||
|
+ while (($tmp = next_token (0)))
|
||
|
+ {
|
||
|
+ $str .= ' ' if !($str eq "");
|
||
|
+ $str .= $tmp;
|
||
|
+ last if $tmp =~ /;\s*$/;
|
||
|
+ }
|
||
|
+
|
||
|
+ $str =~ s/;$//;
|
||
|
+ return ($str);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub
|
||
|
+add_dn_to_stack
|
||
|
+{
|
||
|
+ local ($dn) = @_;
|
||
|
+
|
||
|
+ $current_dn = "$dn, $current_dn";
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub
|
||
|
+remove_dn_from_stack
|
||
|
+{
|
||
|
+ $current_dn =~ s/^.*?,\s*//;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub
|
||
|
+parse_error
|
||
|
+{
|
||
|
+ print "Parse error on line number $line_number at token number $token_number\n";
|
||
|
+ exit (1);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub
|
||
|
+print_entry
|
||
|
+{
|
||
|
+ return if (scalar keys %curentry == 0);
|
||
|
+
|
||
|
+ if (!defined ($curentry{'type'}))
|
||
|
+ {
|
||
|
+ $host = hostname ();
|
||
|
+ $hostdn = "cn=$host, $basedn";
|
||
|
+ print "dn: $hostdn\n";
|
||
|
+ print "objectClass: top\n";
|
||
|
+ print "objectClass: dhcpServer\n";
|
||
|
+ print "cn: $host\n";
|
||
|
+ print "dhcpServiceDN: $current_dn\n\n";
|
||
|
+
|
||
|
+ print "dn: $current_dn\n";
|
||
|
+ print "cn: DHCP Config\n";
|
||
|
+ print "objectClass: top\n";
|
||
|
+ print "objectClass: dhcpService\n";
|
||
|
+ if (defined ($curentry{'options'}))
|
||
|
+ {
|
||
|
+ print "objectClass: dhcpOptions\n";
|
||
|
+ }
|
||
|
+ print "dhcpPrimaryDN: $hostdn\n";
|
||
|
+ }
|
||
|
+ elsif ($curentry{'type'} eq 'subnet')
|
||
|
+ {
|
||
|
+ print "dn: $current_dn\n";
|
||
|
+ print "cn: " . $curentry{'ip'} . "\n";
|
||
|
+ print "objectClass: top\n";
|
||
|
+ print "objectClass: dhcpSubnet\n";
|
||
|
+ if (defined ($curentry{'options'}))
|
||
|
+ {
|
||
|
+ print "objectClass: dhcpOptions\n";
|
||
|
+ }
|
||
|
+
|
||
|
+ print "dhcpNetMask: " . $curentry{'netmask'} . "\n";
|
||
|
+ if (defined ($curentry{'range'}))
|
||
|
+ {
|
||
|
+ print "dhcpRange: " . $curentry{'range'} . "\n";
|
||
|
+ }
|
||
|
+ }
|
||
|
+ elsif ($curentry{'type'} eq 'shared-network')
|
||
|
+ {
|
||
|
+ print "dn: $current_dn\n";
|
||
|
+ print "cn: " . $curentry{'descr'} . "\n";
|
||
|
+ print "objectClass: top\n";
|
||
|
+ print "objectClass: dhcpSharedNetwork\n";
|
||
|
+ if (defined ($curentry{'options'}))
|
||
|
+ {
|
||
|
+ print "objectClass: dhcpOptions\n";
|
||
|
+ }
|
||
|
+ }
|
||
|
+ elsif ($curentry{'type'} eq 'group')
|
||
|
+ {
|
||
|
+ print "dn: $current_dn\n";
|
||
|
+ print "cn: group\n";
|
||
|
+ print "objectClass: top\n";
|
||
|
+ print "objectClass: dhcpGroup\n";
|
||
|
+ if (defined ($curentry{'options'}))
|
||
|
+ {
|
||
|
+ print "objectClass: dhcpOptions\n";
|
||
|
+ }
|
||
|
+ }
|
||
|
+ elsif ($curentry{'type'} eq 'host')
|
||
|
+ {
|
||
|
+ print "dn: $current_dn\n";
|
||
|
+ print "cn: " . $curentry{'host'} . "\n";
|
||
|
+ print "objectClass: top\n";
|
||
|
+ print "objectClass: dhcpHost\n";
|
||
|
+ if (defined ($curentry{'options'}))
|
||
|
+ {
|
||
|
+ print "objectClass: dhcpOptions\n";
|
||
|
+ }
|
||
|
+
|
||
|
+ if (defined ($curentry{'hwaddress'}))
|
||
|
+ {
|
||
|
+ print "dhcpHWAddress: " . $curentry{'hwaddress'} . "\n";
|
||
|
+ }
|
||
|
+ }
|
||
|
+ elsif ($curentry{'type'} eq 'pool')
|
||
|
+ {
|
||
|
+ print "dn: $current_dn\n";
|
||
|
+ print "cn: pool\n";
|
||
|
+ print "objectClass: top\n";
|
||
|
+ print "objectClass: dhcpPool\n";
|
||
|
+ if (defined ($curentry{'options'}))
|
||
|
+ {
|
||
|
+ print "objectClass: dhcpOptions\n";
|
||
|
+ }
|
||
|
+
|
||
|
+ if (defined ($curentry{'range'}))
|
||
|
+ {
|
||
|
+ print "dhcpRange: " . $curentry{'range'} . "\n";
|
||
|
+ }
|
||
|
+ }
|
||
|
+ elsif ($curentry{'type'} eq 'class')
|
||
|
+ {
|
||
|
+ print "dn: $current_dn\n";
|
||
|
+ print "cn: " . $curentry{'class'} . "\n";
|
||
|
+ print "objectClass: top\n";
|
||
|
+ print "objectClass: dhcpClass\n";
|
||
|
+ if (defined ($curentry{'options'}))
|
||
|
+ {
|
||
|
+ print "objectClass: dhcpOptions\n";
|
||
|
+ }
|
||
|
+ }
|
||
|
+ elsif ($curentry{'type'} eq 'subclass')
|
||
|
+ {
|
||
|
+ print "dn: $current_dn\n";
|
||
|
+ print "cn: " . $curentry{'subclass'} . "\n";
|
||
|
+ print "objectClass: top\n";
|
||
|
+ print "objectClass: dhcpSubClass\n";
|
||
|
+ if (defined ($curentry{'options'}))
|
||
|
+ {
|
||
|
+ print "objectClass: dhcpOptions\n";
|
||
|
+ }
|
||
|
+ print "dhcpClassData: " . $curentry{'class'} . "\n";
|
||
|
+ }
|
||
|
+
|
||
|
+ if (defined ($curentry{'statements'}))
|
||
|
+ {
|
||
|
+ foreach $statement (@{$curentry{'statements'}})
|
||
|
+ {
|
||
|
+ print "dhcpStatements: $statement\n";
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if (defined ($curentry{'options'}))
|
||
|
+ {
|
||
|
+ foreach $statement (@{$curentry{'options'}})
|
||
|
+ {
|
||
|
+ print "dhcpOption: $statement\n";
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ print "\n";
|
||
|
+ undef (%curentry);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub parse_netmask
|
||
|
+{
|
||
|
+ local ($netmask) = @_;
|
||
|
+ local ($i);
|
||
|
+
|
||
|
+ if ((($a, $b, $c, $d) = $netmask =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) != 4)
|
||
|
+ {
|
||
|
+ parse_error ();
|
||
|
+ }
|
||
|
+
|
||
|
+ $num = (($a & 0xff) << 24) |
|
||
|
+ (($b & 0xff) << 16) |
|
||
|
+ (($c & 0xff) << 8) |
|
||
|
+ ($d & 0xff);
|
||
|
+
|
||
|
+ for ($i=1; $i<=32 && $num & (1 << (32 - $i)); $i++)
|
||
|
+ {
|
||
|
+ }
|
||
|
+ $i--;
|
||
|
+
|
||
|
+ return ($i);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub parse_subnet
|
||
|
+{
|
||
|
+ local ($ip, $tmp, $netmask);
|
||
|
+
|
||
|
+ print_entry () if %curentry;
|
||
|
+
|
||
|
+ $ip = next_token (0);
|
||
|
+ parse_error () if !defined ($ip);
|
||
|
+
|
||
|
+ $tmp = next_token (1);
|
||
|
+ parse_error () if !defined ($tmp);
|
||
|
+ parse_error () if !($tmp eq 'netmask');
|
||
|
+
|
||
|
+ $tmp = next_token (0);
|
||
|
+ parse_error () if !defined ($tmp);
|
||
|
+ $netmask = parse_netmask ($tmp);
|
||
|
+
|
||
|
+ $tmp = next_token (0);
|
||
|
+ parse_error () if !defined ($tmp);
|
||
|
+ parse_error () if !($tmp eq '{');
|
||
|
+
|
||
|
+ add_dn_to_stack ("cn=$ip");
|
||
|
+ $curentry{'type'} = 'subnet';
|
||
|
+ $curentry{'ip'} = $ip;
|
||
|
+ $curentry{'netmask'} = $netmask;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub parse_shared_network
|
||
|
+{
|
||
|
+ local ($descr, $tmp);
|
||
|
+
|
||
|
+ print_entry () if %curentry;
|
||
|
+
|
||
|
+ $descr = next_token (0);
|
||
|
+ parse_error () if !defined ($descr);
|
||
|
+
|
||
|
+ $tmp = next_token (0);
|
||
|
+ parse_error () if !defined ($tmp);
|
||
|
+ parse_error () if !($tmp eq '{');
|
||
|
+
|
||
|
+ add_dn_to_stack ("cn=$descr");
|
||
|
+ $curentry{'type'} = 'shared-network';
|
||
|
+ $curentry{'descr'} = $descr;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub parse_host
|
||
|
+{
|
||
|
+ local ($descr, $tmp);
|
||
|
+
|
||
|
+ print_entry () if %curentry;
|
||
|
+
|
||
|
+ $host = next_token (0);
|
||
|
+ parse_error () if !defined ($host);
|
||
|
+
|
||
|
+ $tmp = next_token (0);
|
||
|
+ parse_error () if !defined ($tmp);
|
||
|
+ parse_error () if !($tmp eq '{');
|
||
|
+
|
||
|
+ add_dn_to_stack ("cn=$host");
|
||
|
+ $curentry{'type'} = 'host';
|
||
|
+ $curentry{'host'} = $host;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub parse_group
|
||
|
+{
|
||
|
+ local ($descr, $tmp);
|
||
|
+
|
||
|
+ print_entry () if %curentry;
|
||
|
+
|
||
|
+ $tmp = next_token (0);
|
||
|
+ parse_error () if !defined ($tmp);
|
||
|
+ parse_error () if !($tmp eq '{');
|
||
|
+
|
||
|
+ add_dn_to_stack ("cn=group");
|
||
|
+ $curentry{'type'} = 'group';
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub parse_pool
|
||
|
+{
|
||
|
+ local ($descr, $tmp);
|
||
|
+
|
||
|
+ print_entry () if %curentry;
|
||
|
+
|
||
|
+ $tmp = next_token (0);
|
||
|
+ parse_error () if !defined ($tmp);
|
||
|
+ parse_error () if !($tmp eq '{');
|
||
|
+
|
||
|
+ add_dn_to_stack ("cn=pool");
|
||
|
+ $curentry{'type'} = 'pool';
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub parse_class
|
||
|
+{
|
||
|
+ local ($descr, $tmp);
|
||
|
+
|
||
|
+ print_entry () if %curentry;
|
||
|
+
|
||
|
+ $class = next_token (0);
|
||
|
+ parse_error () if !defined ($class);
|
||
|
+
|
||
|
+ $tmp = next_token (0);
|
||
|
+ parse_error () if !defined ($tmp);
|
||
|
+ parse_error () if !($tmp eq '{');
|
||
|
+
|
||
|
+ $class =~ s/\"//g;
|
||
|
+ add_dn_to_stack ("cn=$class");
|
||
|
+ $curentry{'type'} = 'class';
|
||
|
+ $curentry{'class'} = $class;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub parse_subclass
|
||
|
+{
|
||
|
+ local ($descr, $tmp);
|
||
|
+
|
||
|
+ print_entry () if %curentry;
|
||
|
+
|
||
|
+ $class = next_token (0);
|
||
|
+ parse_error () if !defined ($class);
|
||
|
+
|
||
|
+ $subclass = next_token (0);
|
||
|
+ parse_error () if !defined ($subclass);
|
||
|
+
|
||
|
+ $tmp = next_token (0);
|
||
|
+ parse_error () if !defined ($tmp);
|
||
|
+ parse_error () if !($tmp eq '{');
|
||
|
+
|
||
|
+ add_dn_to_stack ("cn=$subclass");
|
||
|
+ $curentry{'type'} = 'subclass';
|
||
|
+ $curentry{'class'} = $class;
|
||
|
+ $curentry{'subclass'} = $subclass;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub parse_hwaddress
|
||
|
+{
|
||
|
+ local ($type, $hw, $tmp);
|
||
|
+
|
||
|
+ $type = next_token (0);
|
||
|
+ parse_error () if !defined ($type);
|
||
|
+
|
||
|
+ $hw = next_token (0);
|
||
|
+ parse_error () if !defined ($hw);
|
||
|
+ $hw =~ s/;$//;
|
||
|
+
|
||
|
+ $curentry{'hwaddress'} = "$type $hw";
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub parse_range
|
||
|
+{
|
||
|
+ local ($tmp, $str);
|
||
|
+
|
||
|
+ $str = remaining_line ();
|
||
|
+
|
||
|
+ if (!($str eq ''))
|
||
|
+ {
|
||
|
+ $str =~ s/;$//;
|
||
|
+ $curentry{'range'} = $str;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+sub parse_statement
|
||
|
+{
|
||
|
+ local ($token) = shift;
|
||
|
+ local ($str);
|
||
|
+
|
||
|
+ if ($token eq 'option')
|
||
|
+ {
|
||
|
+ $str = remaining_line ();
|
||
|
+ push (@{$curentry{'options'}}, $str);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ $str = $token . " " . remaining_line ();
|
||
|
+ push (@{$curentry{'statements'}}, $str);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+my $token;
|
||
|
+my $token_number = 0;
|
||
|
+my $line_number = 0;
|
||
|
+my %curentry;
|
||
|
+
|
||
|
+$current_dn = "cn=DHCP Config, $basedn";
|
||
|
+$curentry{'descr'} = 'DHCP Config';
|
||
|
+$line = '';
|
||
|
+
|
||
|
+while (($token = next_token (1)))
|
||
|
+ {
|
||
|
+ if ($token eq '}')
|
||
|
+ {
|
||
|
+ print_entry () if %curentry;
|
||
|
+ remove_dn_from_stack ();
|
||
|
+ }
|
||
|
+ elsif ($token eq 'subnet')
|
||
|
+ {
|
||
|
+ parse_subnet ();
|
||
|
+ next;
|
||
|
+ }
|
||
|
+ elsif ($token eq 'shared-network')
|
||
|
+ {
|
||
|
+ parse_shared_network ();
|
||
|
+ next;
|
||
|
+ }
|
||
|
+ elsif ($token eq 'class')
|
||
|
+ {
|
||
|
+ parse_class ();
|
||
|
+ next;
|
||
|
+ }
|
||
|
+ elsif ($token eq 'subclass')
|
||
|
+ {
|
||
|
+ parse_subclass ();
|
||
|
+ next;
|
||
|
+ }
|
||
|
+ elsif ($token eq 'pool')
|
||
|
+ {
|
||
|
+ parse_pool ();
|
||
|
+ next;
|
||
|
+ }
|
||
|
+ elsif ($token eq 'group')
|
||
|
+ {
|
||
|
+ parse_group ();
|
||
|
+ next;
|
||
|
+ }
|
||
|
+ elsif ($token eq 'host')
|
||
|
+ {
|
||
|
+ parse_host ();
|
||
|
+ next;
|
||
|
+ }
|
||
|
+ elsif ($token eq 'hardware')
|
||
|
+ {
|
||
|
+ parse_hwaddress ();
|
||
|
+ next;
|
||
|
+ }
|
||
|
+ elsif ($token eq 'range')
|
||
|
+ {
|
||
|
+ parse_range ();
|
||
|
+ next;
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ parse_statement ($token);
|
||
|
+ next;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+
|
||
|
--- /dev/null 2007-01-31 10:24:38.956568237 -0500
|
||
|
+++ dhcp-3.0.5/doc/draft-ietf-dhc-ldap-schema-01.txt 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -0,0 +1,1089 @@
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+Network Working Group M. Meredith,
|
||
|
+Internet Draft V. Nanjundaswamy,
|
||
|
+Document: <draft-ietf-dhc-ldap-schema-00.txt> M. Hinckley
|
||
|
+Category: Proposed Standard Novell Inc.
|
||
|
+Expires: 15th December 2001 16th June 2001
|
||
|
+
|
||
|
+
|
||
|
+ LDAP Schema for DHCP
|
||
|
+
|
||
|
+Status of this Memo
|
||
|
+
|
||
|
+This document is an Internet-Draft and is in full conformance with all
|
||
|
+provisions of Section 10 of RFC2026 [ ].
|
||
|
+
|
||
|
+Internet-Drafts are working documents of the Internet Engineering Task
|
||
|
+Force (IETF), its areas, and its working groups. Note that other groups
|
||
|
+may also distribute working documents as Internet-Drafts. Internet-
|
||
|
+Drafts are draft documents valid for a maximum of six months and may be
|
||
|
+updated, replaced, or obsolete by other documents at any time. It is
|
||
|
+inappropriate to use Internet-Drafts as reference material or to cite
|
||
|
+them other than as "work in progress." The list of current Internet-
|
||
|
+Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt The
|
||
|
+list of Internet-Draft Shadow Directories can be accessed at
|
||
|
+http://www.ietf.org/shadow.html.
|
||
|
+
|
||
|
+1. Abstract
|
||
|
+
|
||
|
+This document defines a schema for representing DHCP configuration in an
|
||
|
+LDAP directory. It can be used to represent the DHCP Service
|
||
|
+configuration(s) for an entire enterprise network, a subset of the
|
||
|
+network, or even a single server. Representing DHCP configuration in an
|
||
|
+LDAP directory enables centralized management of DHCP services offered
|
||
|
+by one or more DHCP Servers within the enterprise.
|
||
|
+
|
||
|
+2. Conventions used in this document
|
||
|
+
|
||
|
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
||
|
+"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
||
|
+document are to be interpreted as described in RFC-2119 [ ].
|
||
|
+
|
||
|
+In places where different sets of terminology are commonly used to
|
||
|
+represent similar DHCP concepts, this schema uses the terminology of the
|
||
|
+Internet Software Consortium's DHCP server reference implementation.
|
||
|
+For more information see www.isc.org.
|
||
|
+
|
||
|
+3. Design Considerations
|
||
|
+
|
||
|
+The DHCP LDAP schema is designed to be a simple multi-server schema. The
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 1]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+intent of this schema is to provide a basic framework for representing
|
||
|
+the most common elements used in the configuration of DHCP Server. This
|
||
|
+should allow other network services to obtain and use basic DHCP
|
||
|
+configuration information in a server-independent but knowledgeable way.
|
||
|
+
|
||
|
+It is expected that some implementations may need to extend the schema
|
||
|
+objects, in order to implement all of their features or needs. It is
|
||
|
+recommended that you use the schema defined in this draft to represent
|
||
|
+DHCP configuration information in an LDAP directory. Conforming to a
|
||
|
+standard schema improves interoperability between DHCP implementations
|
||
|
+from different vendors.
|
||
|
+
|
||
|
+Some implementations may choose not to support all of the objects
|
||
|
+defined here.
|
||
|
+
|
||
|
+Two decisions are explicitly left up to each implementation:
|
||
|
+
|
||
|
+First, implementations may choose not to store the lease information in
|
||
|
+the directory, so those objects would not be used.
|
||
|
+
|
||
|
+Second, implementations may choose not to implement the auditing
|
||
|
+information.
|
||
|
+
|
||
|
+It is up to the implementation to determine if the data in the directory
|
||
|
+is considered "authoritative", or if it is simply a copy of data from an
|
||
|
+authoritative source. Validity of the information if used as a copy is
|
||
|
+to be ensured by the implementation.
|
||
|
+
|
||
|
+Primarily two types of applications will use the information in this
|
||
|
+schema: 1. DHCP servers (for loading their configuration) 2. Management
|
||
|
+Interfaces (for defining/editing configurations).
|
||
|
+
|
||
|
+The schema should be efficient for the needs of both types of
|
||
|
+applications. The schema is designed to allow objects managed by DHCP
|
||
|
+(such as computers, subnets, etc) to be present anywhere in a directory
|
||
|
+hierarchy (to allow those objects to be placed in the directory for
|
||
|
+managing administrative control and access to the objects).
|
||
|
+
|
||
|
+The schema uses a few naming conventions - all object classes and
|
||
|
+attributes are prefixed with "dhcp" to decrease the chance that object
|
||
|
+classes and attributes will have the same name. The schema also uses
|
||
|
+standard naming attributes ("cn", "ou", etc) for all objects.
|
||
|
+
|
||
|
+4. Common DHCP Configuration Attributes
|
||
|
+
|
||
|
+Although DHCP manages several different types of objects, the
|
||
|
+configuration of those objects is often similar. Consequently, most of
|
||
|
+these objects have a common set of attributes, which are defined below.
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 2]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+4.1. Attributes Definitions
|
||
|
+
|
||
|
+The schema definitions listed below are for readability. The LDIF
|
||
|
+layout for this schema will follow in section 8.
|
||
|
+
|
||
|
+Name: dhcpPrimaryDN Description: The Distinguished Name of the
|
||
|
+dhcpServer object, which is the primary server for the configuration.
|
||
|
+Syntax: DN Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Named: dhcpSecondaryDN Description: The Distinguished Name(s) of the
|
||
|
+dhcpServer object(s), which are secondary servers for the configuration.
|
||
|
+Syntax: DN
|
||
|
+
|
||
|
+Name: dhcpStatements Description: Flexible storage for representing any
|
||
|
+specific data depending on the object to which it is attached. Examples
|
||
|
+include conditional statements, Server parameters, etc. This also
|
||
|
+serves as a 'catch-all' attribute that allows the standard to evolve
|
||
|
+without needing to update the schema. Syntax: IA5String
|
||
|
+
|
||
|
+Name: dhcpRange Description: The starting and 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. Syntax: IA5String
|
||
|
+
|
||
|
+Name: dhcpPermitList Description: This attribute contains the permit
|
||
|
+lists associated with a pool. Each permit list is defined as a separate
|
||
|
+value. Syntax: IA5String
|
||
|
+
|
||
|
+Name: dhcpNetMask Description: The subnet mask length for the subnet.
|
||
|
+The mask can be easily computed from this length. Syntax: Integer
|
||
|
+Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpOption Description: Encoded option values to be sent to
|
||
|
+clients. Each value represents a single option and contains (OptionTag,
|
||
|
+Length, OptionData) encoded in the format used by DHCP. For more
|
||
|
+information see [DHCPOPT]. Syntax: OctetString
|
||
|
+
|
||
|
+Name: dhcpClassData Description: 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 a 'match' or 'spawn
|
||
|
+with' statement in the class name declarations. Syntax: IA5String
|
||
|
+Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpSubclassesDN Description: List of subclasses, these are the
|
||
|
+actual DN of each subclass object. Syntax: DN
|
||
|
+
|
||
|
+Name: dhcpClassesDN Description: List of classes, these are the actual
|
||
|
+DN of each class object. Syntax: DN
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 3]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+Name: dhcpSubnetDN Description: List of subnets, these are the actual DN
|
||
|
+of each subnet object. Syntax: DN
|
||
|
+
|
||
|
+Name: dhcpPoolDN Description: List of pools, these are the actual DN of
|
||
|
+each Pool object. Syntax: DN
|
||
|
+
|
||
|
+Name: dhcpOptionsDN Description: List of options, these are the actual
|
||
|
+DN of each Options object. Syntax: DN
|
||
|
+
|
||
|
+Name: dhcpHostDN Description: List of hosts, these are the actual DN of
|
||
|
+each host object. Syntax: DN
|
||
|
+
|
||
|
+Name: dhcpSharedNetworkDN Description: List of shared networks, these
|
||
|
+are the actual DN of each shared network object. Syntax: DN
|
||
|
+
|
||
|
+Name: dhcpGroupDN Description: List of groups, these are the actual DN
|
||
|
+of each Group object. Syntax: DN
|
||
|
+
|
||
|
+Name: dhcpLeaseDN Description: Single Lease DN. A dhcpHost configuration
|
||
|
+uses this attribute to identify a static IP address assignment. Syntax:
|
||
|
+DN Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpLeasesDN Description: List of leases, these are the actual DN
|
||
|
+of each lease object. Syntax: DN
|
||
|
+
|
||
|
+Name: dhcpServiceDN Description: 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. Syntax: DN
|
||
|
+
|
||
|
+Name: dhcpHWAddress Description: The hardware address of the client
|
||
|
+associated with a lease Syntax: OctetString Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpVersion Description: This is the version identified for the
|
||
|
+object that this attribute is part of. In case of the dhcpServer object,
|
||
|
+this represents the DHCP software version. Syntax: IA5String Flags:
|
||
|
+SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpImplementation Description: DHCP Server implementation
|
||
|
+description e.g. DHCP Vendor information. Syntax: IA5String Flags:
|
||
|
+SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpHashBucketAssignment Description: HashBucketAssignment bit map
|
||
|
+for the DHCP Server, as defined in DHC Load Balancing Algorithm [RFC
|
||
|
+3074]. Syntax: Octet String Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpDelayedServiceParameter Description: Delay in seconds
|
||
|
+corresponding to Delayed Service Parameter configuration, as defined in
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 4]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+DHC Load Balancing Algorithm [RFC 3074]. Syntax: Integer Flags: SINGLE-
|
||
|
+VALUE
|
||
|
+
|
||
|
+Name: dhcpMaxClientLeadTime Description: Maximum Client Lead Time
|
||
|
+configuration in seconds, as defined in DHCP Failover Protocol [FAILOVR]
|
||
|
+Syntax: Integer Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpFailOverEndpointState Description: Server (Failover Endpoint)
|
||
|
+state, as defined in DHCP Failover Protocol [FAILOVR] Syntax: IA5String
|
||
|
+Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+5. Configurations and Services
|
||
|
+
|
||
|
+The schema definitions below are for readability the LDIF layout for
|
||
|
+this schema will follow in section 8.
|
||
|
+
|
||
|
+The DHC working group is currently considering several proposals for
|
||
|
+fail-over and redundancy of DHCP servers. These may require sharing of
|
||
|
+configuration information between servers. This schema provides a
|
||
|
+generalized mechanism for supporting any of these proposals, by
|
||
|
+separating the definition of a server from the definition of
|
||
|
+configuration service provided by the server.
|
||
|
+
|
||
|
+Separating the DHCP Server (dhcpServer) and the DHCP Configuration
|
||
|
+(dhcpService) representations allows a configuration service to be
|
||
|
+provided by one or more servers. Similarly, a server may provide one or
|
||
|
+more configurations. The schema allows a server to be configured as
|
||
|
+either a primary or secondary provider of a DHCP configuration.
|
||
|
+
|
||
|
+Configurations are also defined so that one configuration can include
|
||
|
+some of the objects that are defined in another configuration. This
|
||
|
+allows for sharing and/or a hierarchy of related configuration items.
|
||
|
+
|
||
|
+Name: dhcpService Description: Service object that represents the
|
||
|
+actual DHCP Service configuration. This will be a container with the
|
||
|
+following attributes. Must: cn, dhcpPrimaryDN May: dhcpSecondaryDN,
|
||
|
+dhcpSharedNetworkDN, dhcpSubnetDN, dhcpGroupDN, dhcpHostDN,
|
||
|
+dhcpClassesDN, dhcpOptionsDN, dhcpStatements
|
||
|
+
|
||
|
+The following objects could exist inside the dhcpService container:
|
||
|
+dhcpSharedNetwork, dhcpSubnet, dhcpGroup, dhcpHost, dhcpClass,
|
||
|
+dhcpOptions, dhcpLog
|
||
|
+
|
||
|
+Name: dhcpServer Description: Server object that the DHCP server will
|
||
|
+login as. The configuration information is in the dhcpService container
|
||
|
+that the dhcpServiceDN points to. Must: cn, dhcpServiceDN May:
|
||
|
+dhcpVersion, dhcpImplementation, dhcpHashBucketAssignment,
|
||
|
+dhcpDelayedServiceParameter, dhcpMaxClientLeadTime,
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 5]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+dhcpFailOverEndpointState, dhcpStatements
|
||
|
+
|
||
|
+5.1. DHCP Declaration related classes:
|
||
|
+
|
||
|
+Name: dhcpSharedNetwork Description: Shared Network class will list what
|
||
|
+pools and subnets are in this network.
|
||
|
+
|
||
|
+This will be a container with the following attributes. Must: cn May:
|
||
|
+dhcpSubnetDN, dhcpPoolDN, dhcpOptionsDN, dhcpStatements
|
||
|
+
|
||
|
+The following objects can exist within a dhcpSharedNetwork container:
|
||
|
+dhcpSubnet, dhcpPool, dhcpOptions, dhcpLog
|
||
|
+
|
||
|
+Name: dhcpSubnet Description: Subnet object will include configuration
|
||
|
+information associated with a subnet, including a range and a net mask.
|
||
|
+
|
||
|
+This will be a container with the following attributes. Must: cn
|
||
|
+(Subnet address), dhcpNetMask May: dhcpRange, dhcpPoolDN, dhcpGroupDN,
|
||
|
+dhcpHostDN, dhcpClassesDN, dhcpLeasesDN, dhcpOptionsDN, dhcpStatements
|
||
|
+
|
||
|
+The following objects can exist within a dhcpSubnet container: dhcpPool,
|
||
|
+dhcpGroup, dhcpHost, dhcpClass, dhcpOptions, dhcpLease, dhcpLog
|
||
|
+
|
||
|
+Name: dhcpGroup Description: Group object will have configuration
|
||
|
+information associated with a group.
|
||
|
+
|
||
|
+This will be a container with the following attributes. Must: cn May:
|
||
|
+dhcpHostDN, dhcpOptionsDN, dhcpStatements
|
||
|
+
|
||
|
+The following objects can exist within a dhcpGroup container: dhcpHost,
|
||
|
+dhcpOptions
|
||
|
+
|
||
|
+Name: dhcpHost Description: The host object includes DHCP host
|
||
|
+declarations to assign a static IP address or declare the client as
|
||
|
+known or specify statements for a specific client. Must: cn May:
|
||
|
+dhcpLeaseDN, dhcpHWAddress, dhcpOptionsDN, dhcpStatements
|
||
|
+
|
||
|
+The following objects can exist within a dhcpHost container: dhcpLease,
|
||
|
+dhcpOptions
|
||
|
+
|
||
|
+Name: dhcpOptions Description: The options class is for option space
|
||
|
+declarations, it contains a list of options. Must: cn, dhcpOption
|
||
|
+
|
||
|
+Name: dhcpClass Description: This is a class to group clients together
|
||
|
+based on matching rules.
|
||
|
+
|
||
|
+This will be a container with the following attributes. Must: cn May:
|
||
|
+dhcpSubClassesDN, dhcpOptionsDN, dhcpStatements
|
||
|
+
|
||
|
+The following object can exist within a dhcpClass container:
|
||
|
+dhcpSubclass, dhcpOptions
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 6]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+Name: dhcpSubClass Description: This includes configuration information
|
||
|
+for a subclass associated with a class. The dhcpSubClass object will
|
||
|
+always be contained within the corresponding class container object.
|
||
|
+Must: cn May: dhcpClassData, dhcpOptionsDN, dhcpStatements
|
||
|
+
|
||
|
+Name: dhcpPool Description: This contains configuration for a pool that
|
||
|
+will have the range of addresses, permit lists and point to classes and
|
||
|
+leases that are members of this pool.
|
||
|
+
|
||
|
+This will be a container that could be contained by dhcpSubnet or a
|
||
|
+dhcpSharedNetwork. Must: cn, dhcpRange May: dhcpClassesDN,
|
||
|
+dhcpPermitList, dhcpLeasesDN, dhcpOptionsDN, dhcpStatements
|
||
|
+
|
||
|
+The following objects can exist within a dhcpPool container: dhcpClass,
|
||
|
+dhcpOptions, dhcpLease, dhcpLog
|
||
|
+
|
||
|
+6. Tracking Address Assignments
|
||
|
+
|
||
|
+The behavior of a DHCP server is influenced by two factors - it's
|
||
|
+configuration and the current state of the addresses that have been
|
||
|
+assigned to clients. This schema defines a set of objects for
|
||
|
+representing the DHCP configuration associated with a server. The
|
||
|
+following object classes provide the ability to record how addresses are
|
||
|
+used including maintaining history (audit log) on individual leases.
|
||
|
+Recording lease information in a directory could result in a significant
|
||
|
+performance impact and is therefore optional. Implementations supporting
|
||
|
+logging of leases need to consider the performance impact.
|
||
|
+
|
||
|
+6.1. dhcpLeases Attribute Definitions
|
||
|
+
|
||
|
+The schema definitions below are for readability the LDIF layout for
|
||
|
+this schema will follow in section 8.
|
||
|
+
|
||
|
+Name: dhcpAddressState Description: This stores information about the
|
||
|
+current binding-status of an address. For dynamic addresses managed by
|
||
|
+DHCP, the values should be restricted to the states defined in the DHCP
|
||
|
+Failover Protocol draft [FAILOVR]: 'FREE', 'ACTIVE', 'EXPIRED',
|
||
|
+'RELEASED', 'RESET', 'ABANDONED', 'BACKUP'. For more information on
|
||
|
+these states see [FAILOVR]. 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'.
|
||
|
+Syntax: IA5String Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpExpirationTime Description: This is the time the current lease
|
||
|
+for an address expires. Syntax: DateTime Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 7]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+Name: dhcpStartTimeOfState Description: This is the time of the last
|
||
|
+state change for a leased address. Syntax: DateTime Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpLastTransactionTime Description: This is the last time a valid
|
||
|
+DHCP packet was received from the client. Syntax: DateTime Flags:
|
||
|
+SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpBootpFlag Description: This indicates whether the address was
|
||
|
+assigned via BOOTP Syntax: Boolean Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpDomainName Description: 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 ".". Syntax:
|
||
|
+IA5String Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpDnsStatus Description: 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 that has the same values as
|
||
|
+specified by the Failover-DDNS option (see [FAILOVR]). Syntax: Integer
|
||
|
+Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpRequestedHostName Description: This is the hostname that was
|
||
|
+requested by the client. Syntax: IA5String Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpAssignedHostName Description: 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. Syntax: IA5String Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpReservedForClient Description: This is the distinguished name
|
||
|
+of the "dhcpHost" 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. Syntax: DN Flags:
|
||
|
+SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpAssignedToClient Description: This is the distinguished name
|
||
|
+of a "dhcpHost" that an address is currently assigned to. This
|
||
|
+attribute is only present in the class when the address is leased.
|
||
|
+Syntax: DN Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpRelayAgentInfo Description: 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. Syntax: OctetString Flags: SINGLE-VALUE
|
||
|
+
|
||
|
+Name: dhcpErrorLog Description: Generic error log attribute that allows
|
||
|
+logging error conditions within a dhcpService or a dhcpSubnet, like no IP
|
||
|
+addresses available for lease. Syntax: IA5String
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 8]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+6.2. dhcpLeases Object Class
|
||
|
+
|
||
|
+This class represents an IP address. It may or may not be leaseable,
|
||
|
+and the object may exist even though a lease is not currently active for
|
||
|
+the associated IP address.
|
||
|
+
|
||
|
+It is recommended that all Lease objects for a single DHCP Service be
|
||
|
+centrally located within a single container. This ensures that the lease
|
||
|
+objects and the corresponding logs do not have to be relocated, when
|
||
|
+address ranges allocated to individual DHCP subnets and/or pools change.
|
||
|
+
|
||
|
+The schema definitions below are for readability the LDIF layout for
|
||
|
+this schema will follow in section 8.
|
||
|
+
|
||
|
+Name: dhcpLeases Description: This is the object that holds state
|
||
|
+information about an IP address. The cn (which is the IP address), and
|
||
|
+the current address-state are mandatory attributes. If the address is
|
||
|
+assigned then, some of the optional attributes will have valid data.
|
||
|
+Must: cn, dhcpAddressState May: dhcpExpirationTime,
|
||
|
+dhcpStartTimeOfState, dhcpLastTransactionTime, dhcpBootpFlag,
|
||
|
+dhcpDomainName, dhcpDnsStatus, dhcpRequestedHostName,
|
||
|
+dhcpAssignedHostName, dhcpReservedForClient, dhcpAssignedToClient,
|
||
|
+dhcpRelayAgentInfo, dhcpHWAddress
|
||
|
+
|
||
|
+6.3 Audit Log Information
|
||
|
+
|
||
|
+A dhcpLog object is created whenever a lease is assigned or released.
|
||
|
+This object is intended to be created under the corresponding dhcpLeases
|
||
|
+container, or dhcpPool, dhcpSubnet, dhcpSharedNetwork or dhcpService
|
||
|
+containers.
|
||
|
+
|
||
|
+The log information under the dhcpLeases container would be for
|
||
|
+addresses matching that lease information. The log information in the
|
||
|
+other containers could be used for errors, i.e. when a pool or subnet is
|
||
|
+out our addresses or if a server is not able to assign any more
|
||
|
+addresses for a particular dhcpService.
|
||
|
+
|
||
|
+Name: dhcpLog Description: This is the object that holds past
|
||
|
+information about an 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. Must: cn May: dhcpAddressState,
|
||
|
+dhcpExpirationTime, dhcpStartTimeOfState, dhcpLastTransactionTime,
|
||
|
+dhcpBootpFlag, dhcpDomainName, dhcpDnsStatus, dhcpRequestedHostName,
|
||
|
+dhcpAssignedHostName, dhcpReservedForClient, dhcpAssignedToClient,
|
||
|
+dhcpRelayAgentInfo, dhcpHWAddress, dhcpErrorLog
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 9]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+7. Determining settings
|
||
|
+
|
||
|
+The dhcpStatements attribute is the key to DHC enhancements that may
|
||
|
+come along, and the different key words that a particular server
|
||
|
+implementation may use. This attribute can be used to hold conditional
|
||
|
+DHCP Statements and DHCP server parameters. Having a generic settings
|
||
|
+attribute that is just a string, allows this schema to be extensible and
|
||
|
+easy to configure.
|
||
|
+
|
||
|
+All of the attributes that end with DN are references to the class that
|
||
|
+precedes the DN e.g. the dhcpPrimaryDN and dhcpSecondaryDN attributes
|
||
|
+hold the Distinguished Names of the dhcpServer objects that are
|
||
|
+associated with the dhcpService object.
|
||
|
+
|
||
|
+8. LDIF format for attributes and classes.
|
||
|
+
|
||
|
+# Attributes
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.1 NAME 'dhcpPrimaryDN' DESC
|
||
|
+'The DN of the dhcpServer which is the primary server for the
|
||
|
+configuration.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.2 NAME 'dhcpSecondaryDN' DESC 'The DN of
|
||
|
+dhcpServer(s) which provide backup service for the configuration.'
|
||
|
+SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.3 NAME 'dhcpStatements' 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.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.26 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.4 NAME 'dhcpRange' 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.'
|
||
|
+SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.5 NAME 'dhcpPermitList' DESC 'This attribute
|
||
|
+contains the permit lists associated with a pool. Each permit list is
|
||
|
+defined as a separate value.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.6 NAME 'dhcpNetMask' DESC 'The subnet mask
|
||
|
+length for the subnet. The mask can be easily computed from this
|
||
|
+length.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.7 NAME 'dhcpOption' 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.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 10]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.8 NAME 'dhcpClassData' 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.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.9 NAME 'dhcpOptionsDN' DESC 'The
|
||
|
+distinguished name(s) of the dhcpOption objects containing the
|
||
|
+configuration options provided by the server.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.12 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.10 NAME 'dhcpHostDN' DESC 'the distinguished
|
||
|
+name(s) of the dhcpHost objects.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.11 NAME 'dhcpPoolDN' DESC 'The distinguished
|
||
|
+name(s) of pools.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.12 NAME 'dhcpGroupDN' DESC 'The
|
||
|
+distinguished name(s) of the groups.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.12 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.13 NAME 'dhcpSubnetDN' DESC 'The
|
||
|
+distinguished name(s) of the subnets.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.12 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.14 NAME 'dhcpLeaseDN' DESC 'The
|
||
|
+distinguished name of a client address.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE)
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.15 NAME 'dhcpLeasesDN' DESC 'The
|
||
|
+distinguished name(s) client addresses.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.12 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.16 NAME 'dhcpClassesDN' DESC 'The
|
||
|
+distinguished name(s) of a class(es) in a subclass.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.12 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.17 NAME 'dhcpSubclassesDN' DESC 'The
|
||
|
+distinguished name(s) of subclass(es).' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.12 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.18 NAME 'dhcpSharedNetworkDN' DESC 'The
|
||
|
+distinguished name(s) of sharedNetworks.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.12 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.19 NAME 'dhcpServiceDN' DESC 'The DN of
|
||
|
+dhcpService object(s)which contain the configuration information. Each
|
||
|
+dhcpServer object has this attribute identifying the DHCP
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 11]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+configuration(s) that the server is associated with.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.12 )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.20 NAME 'dhcpVersion' DESC 'The version
|
||
|
+attribute of this object.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-
|
||
|
+VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.21 NAME 'dhcpImplementation' DESC
|
||
|
+'Description of the DHCP Server implementation e.g. DHCP Server's
|
||
|
+vendor.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.22 NAME 'dhcpAddressState' 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".'
|
||
|
+SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.23 NAME 'dhcpExpirationTime' DESC 'This is
|
||
|
+the time the current lease for an address expires.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.24 NAME 'dhcpStartTimeOfState' DESC 'This is
|
||
|
+the time of the last state change for a leased address.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.25 NAME 'dhcpLastTransactionTime' DESC 'This
|
||
|
+is the last time a valid DHCP packet was received from the client.'
|
||
|
+SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.26 NAME 'dhcpBootpFlag' DESC 'This indicates
|
||
|
+whether the address was assigned via BOOTP.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.27 NAME 'dhcpDomainName' 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 ".".' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-
|
||
|
+VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.28 NAME 'dhcpDnsStatus' DESC 'This indicates
|
||
|
+the status of updating DNS resource records on behalf of the client by
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 12]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+the DHCP server for this address. The value is a 16-bit bitmask.'
|
||
|
+SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.29 NAME 'dhcpRequestedHostName' DESC 'This
|
||
|
+is the hostname that was requested by the client.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.30 NAME 'dhcpAssignedHostName' 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.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-
|
||
|
+VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.31 NAME 'dhcpReservedForClient' 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.'
|
||
|
+SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.32 NAME 'dhcpAssignedToClient' 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.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.33 NAME 'dhcpRelayAgentInfo' 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.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
|
||
|
+SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.34 NAME 'dhcpHWAddress' DESC 'The clients
|
||
|
+hardware address that requested this IP address.' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.35 NAME 'dhcpHashBucketAssignment' DESC
|
||
|
+'HashBucketAssignment bit map for the DHCP Server, as defined in DHC
|
||
|
+Load Balancing Algorithm [RFC 3074].' SYNTAX
|
||
|
+1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.36 NAME 'dhcpDelayedServiceParameter' DESC
|
||
|
+'Delay in seconds corresponding to Delayed Service Parameter
|
||
|
+configuration, as defined in DHC Load Balancing Algorithm [RFC 3074]. '
|
||
|
+SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.37 NAME 'dhcpMaxClientLeadTime' DESC
|
||
|
+'Maximum Client Lead Time configuration in seconds, as defined in DHCP
|
||
|
+Failover Protocol [FAILOVR]' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 13]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.38 NAME 'dhcpFailOverEndpointState' DESC
|
||
|
+'Server (Failover Endpoint) state, as defined in DHCP Failover Protocol
|
||
|
+[FAILOVR]' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.4.39 NAME 'dhcpErrorLog' DESC
|
||
|
+Generic error log attribute that allows logging error conditions within a
|
||
|
+dhcpService or a dhcpSubnet, like no IP addresses available for lease.
|
||
|
+SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
|
||
|
+
|
||
|
+#Classes
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.6.1 NAME 'dhcpService' DESC ' Service object
|
||
|
+that represents the actual DHCP Service configuration. This is a
|
||
|
+container object.' SUP top MUST (cn $ dhcpPrimaryDN) MAY
|
||
|
+(dhcpSecondaryDN $ dhcpSharedNetworkDN $ dhcpSubnetDN $ dhcpGroupDN $
|
||
|
+dhcpHostDN $ dhcpClassesDN $ dhcpOptionsDN $ dhcpStatements ) )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.6.2 NAME 'dhcpSharedNetwork' DESC 'This stores
|
||
|
+configuration information for a shared network.' SUP top MUST cn MAY
|
||
|
+(dhcpSubnetDN $ dhcpPoolDN $ dhcpOptionsDN $ dhcpStatements) X-
|
||
|
+NDS_CONTAINMENT ('dhcpService' ) )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.6.3 NAME 'dhcpSubnet' DESC 'This class defines
|
||
|
+a subnet. This is a container object.' SUP top MUST ( cn $ dhcpNetMask )
|
||
|
+MAY (dhcpRange $ dhcpPoolDN $ dhcpGroupDN $ dhcpHostDN $ dhcpClassesDN $
|
||
|
+dhcpLeasesDN $ dhcpOptionsDN $ dhcpStatements) X-NDS_CONTAINMENT
|
||
|
+('dhcpService' 'dhcpSharedNetwork') )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.6.4 NAME 'dhcpPool' DESC 'This stores
|
||
|
+configuration information about a pool.' SUP top MUST ( cn $ dhcpRange )
|
||
|
+MAY (dhcpClassesDN $ dhcpPermitList $ dhcpLeasesDN $ dhcpOptionsDN $
|
||
|
+dhcpStatements) X-NDS_CONTAINMENT ('dhcpSubnet' 'dhcpSharedNetwork') )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.6.5 NAME 'dhcpGroup' DESC 'Group object that
|
||
|
+lists host DNs and parameters. This is a container object.' SUP top MUST
|
||
|
+cn MAY ( dhcpHostDN $ dhcpOptionsDN $ dhcpStatements ) X-NDS_CONTAINMENT
|
||
|
+('dhcpSubnet' 'dhcpService' ) )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.6.6 NAME 'dhcpHost' DESC 'This represents
|
||
|
+information about a particular client' SUP top MUST cn MAY (dhcpLeaseDN
|
||
|
+$ dhcpHWAddress $ dhcpOptionsDN $ dhcpStatements) X-NDS_CONTAINMENT
|
||
|
+('dhcpService' 'dhcpSubnet' 'dhcpGroup') )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.6.7 NAME 'dhcpClass' DESC 'Represents
|
||
|
+information about a collection of related clients.' SUP top MUST cn MAY
|
||
|
+(dhcpSubClassesDN $ dhcpOptionsDN $ dhcpStatements) X-NDS_CONTAINMENT
|
||
|
+('dhcpService' 'dhcpSubnet' ) )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.6.8 NAME 'dhcpSubClass' DESC 'Represents
|
||
|
+information about a collection of related classes.' SUP top MUST cn MAY
|
||
|
+(dhcpClassData $ dhcpOptionsDN $ dhcpStatements) X-NDS_CONTAINMENT
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 14]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+'dhcpClass' )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.6.9 NAME 'dhcpOptions' DESC 'Represents
|
||
|
+information about a collection of options defined.' SUP top MUST cn MAY
|
||
|
+( dhcpOption ) X-NDS_CONTAINMENT ('dhcpService' 'dhcpSharedNetwork'
|
||
|
+'dhcpSubnet' 'dhcpPool' 'dhcpGroup' 'dhcpHost' 'dhcpClass' )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.6.10 NAME 'dhcpLeases' DESC 'This class
|
||
|
+represents an IP Address, which may or may not have been leased.' SUP
|
||
|
+top MUST ( cn $ dhcpAddressState ) MAY ( dhcpExpirationTime $
|
||
|
+dhcpStartTimeOfState $ dhcpLastTransactionTime $ dhcpBootpFlag $
|
||
|
+dhcpDomainName $ dhcpDnsStatus $ dhcpRequestedHostName $
|
||
|
+dhcpAssignedHostName $ dhcpReservedForClient $ dhcpAssignedToClient $
|
||
|
+dhcpRelayAgentInfo $ dhcpHWAddress ) X-NDS_CONTAINMENT ( 'dhcpService'
|
||
|
+'dhcpSubnet' 'dhcpPool') )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.6.11 NAME 'dhcpLog' 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.' SUP top
|
||
|
+MUST ( cn ) MAY ( dhcpAddressState $ dhcpExpirationTime $
|
||
|
+dhcpStartTimeOfState $ dhcpLastTransactionTime $ dhcpBootpFlag $
|
||
|
+dhcpDomainName $ dhcpDnsStatus $ dhcpRequestedHostName $
|
||
|
+dhcpAssignedHostName $ dhcpReservedForClient $ dhcpAssignedToClient $
|
||
|
+dhcpRelayAgentInfo $ dhcpHWAddress $ dhcpErrorLog) X-NDS_CONTAINMENT
|
||
|
+('dhcpLeases' 'dhcpPool' 'dhcpSubnet' 'dhcpSharedNetwork' 'dhcpService' ) )
|
||
|
+
|
||
|
+( 2.16.840.1.113719.1.203.6.12 NAME 'dhcpServer' DESC 'DHCP Server
|
||
|
+Object' SUP top MUST (cn, dhcpServiceDN) MAY (dhcpVersion $
|
||
|
+dhcpImplementation $ dhcpHashBucketAssignment $
|
||
|
+dhcpDelayedServiceParameter $ dhcpMaxClientLeadTime $
|
||
|
+dhcpFailOverEndpointState $ dhcpStatements) X-NDS_CONTAINMENT ('O' 'OU'
|
||
|
+'dc') )
|
||
|
+
|
||
|
+9. Security Considerations
|
||
|
+
|
||
|
+Since the DHCP Configuration information is stored in a directory, the
|
||
|
+security of the information is limited to the security offered by the
|
||
|
+directory including the security of the objects within that directory.
|
||
|
+
|
||
|
+10. Intellectual Property Rights Notices
|
||
|
+
|
||
|
+The IETF takes no position regarding the validity or scope of any
|
||
|
+intellectual property or other rights that might be claimed to pertain
|
||
|
+to the implementation or use of the technology described in this
|
||
|
+document or the extent to which any license under such rights might or
|
||
|
+might not be available; neither does it represent that it has made any
|
||
|
+effort to identify any such rights. Information on the IETF's
|
||
|
+procedures with respect to rights in standards-track and standards-
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 15]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+related documentation can be found in BCP-11. Copies of claims of
|
||
|
+rights made available for publication and any assurances of licenses to
|
||
|
+be made available, or the result of an attempt made to obtain a general
|
||
|
+license or permission for the use of such proprietary rights by
|
||
|
+implementors or users of this specification can be obtained from the
|
||
|
+IETF Secretariat.
|
||
|
+
|
||
|
+The IETF invites any interested party to bring to its attention any
|
||
|
+copyrights, patents or patent applications, or other proprietary rights
|
||
|
+which may cover technology that may be required to practice this
|
||
|
+standard. Please address the information to the IETF Executive
|
||
|
+Director.
|
||
|
+
|
||
|
+11. Full Copyright Statement
|
||
|
+
|
||
|
+Copyright (C) The Internet Society (2001). All Rights Reserved.
|
||
|
+
|
||
|
+This document and translations of it may be copied and furnished to
|
||
|
+others, and derivative works that comment on or otherwise explain it or
|
||
|
+assist in its implementation may be prepared, copied, published and
|
||
|
+distributed, in whole or in part, without restriction of any kind,
|
||
|
+provided that the above copyright notice and this paragraph are included
|
||
|
+on all such copies and derivative works. However, this document itself
|
||
|
+may not be modified in any way, such as by removing the copyright notice
|
||
|
+or references to the Internet Society or other Internet organizations,
|
||
|
+except as needed for the purpose of developing Internet standards in
|
||
|
+which case the procedures for copyrights defined in the Internet
|
||
|
+Standards process must be followed, or as required to translate it into
|
||
|
+languages other than English.
|
||
|
+
|
||
|
+The limited permissions granted above are perpetual and will not be
|
||
|
+revoked by the Internet Society or its successors or assigns.
|
||
|
+
|
||
|
+This document and the information contained herein is provided on an "AS
|
||
|
+IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK
|
||
|
+FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||
|
+LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT
|
||
|
+INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR
|
||
|
+FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
+
|
||
|
+12. References
|
||
|
+
|
||
|
+[RFC2131] Droms, R., "Dynamic Host Configuration Protocol", RFC 2131,
|
||
|
+March 1997.
|
||
|
+
|
||
|
+[RFC2132] Alexander, S., Droms, R., "DHCP Options and BOOTP Vendor
|
||
|
+Extensions", RFC 2132, March 1997.
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 16]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+[MSDHCP] Gu, Y., Vyaghrapuri, R., "An LDAP Schema for Dynamic Host
|
||
|
+Configuration Protocol Service", Internet Draft <draft-gu-dhcp-ldap-
|
||
|
+schema-00.txt>, August 1998.
|
||
|
+
|
||
|
+[NOVDHCP] Miller, T., Patel, A., Rao, P., "Lightweight Directory Access
|
||
|
+Protocol (v3): Schema for Dynamic Host Configuration Protocol (DHCP)",
|
||
|
+Internet Draft <draft-miller-dhcp-ldap-schema-00.txt>, June 1998.
|
||
|
+
|
||
|
+[FAILOVR] Droms, R., Rabil, G., Dooley, M., Kapur, A., Gonczi, S., Volz,
|
||
|
+B., "DHCP Failover Protocol", Internet Draft <draft-ietf-dhc-
|
||
|
+failover-08.txt>, July 2000.
|
||
|
+
|
||
|
+[RFC 3074] Volz B., Gonczi S., Lemon T., Stevens R., "DHC Load Balancing
|
||
|
+Algorithm", February 2001
|
||
|
+
|
||
|
+[AGENT] Patrick, M., "DHCP Relay Agent Information Option", Internet
|
||
|
+Draft <draft-ietf-dhc-agent-options-09.txt>, March 2000.
|
||
|
+
|
||
|
+[DHCPOPT] Carney, M., "New Option Review Guidelines and Additional
|
||
|
+Option Namespace", Internet Draft <draft-ietf-dhc-
|
||
|
+option_review_and_namespace-01.txt>, October 1999.
|
||
|
+
|
||
|
+[POLICY] Strassner, J., Elleson, E., Moore, B., "Policy Framework LDAP
|
||
|
+Core Schema", Internet Draft <draft-ietf-policy-core-schema-06.txt>,
|
||
|
+November 1999.
|
||
|
+
|
||
|
+[RFC2251] Wahl, M., Howes, T., Kille, S., "Lightweight Directory Access
|
||
|
+Protocol (v3)", RFC 2251, December 1997.
|
||
|
+
|
||
|
+[RFC2252] Wahl, M., Coulbeck, A., Howes, T., Kille, S., "Lightweight
|
||
|
+Directory Access Protocol (v3) Attribute Syntax Definitions", RFC 2252,
|
||
|
+December 1997.
|
||
|
+
|
||
|
+[RFC2255] Howes, T., Smith, M., "The LDAP URL Format", RFC 2255,
|
||
|
+December 1997.
|
||
|
+
|
||
|
+[RFC951] Croft, B., Gilmore, J., "Bootstrap Protocol (BOOTP)", RFC 951,
|
||
|
+September 1985.
|
||
|
+
|
||
|
+[RFC2119] Bradner, S. "Key words for use in RFCs to Indicate Requirement
|
||
|
+Levels", RFC 2119, March 1997.
|
||
|
+
|
||
|
+13. Acknowledgments
|
||
|
+
|
||
|
+This work is partially based on a previous draft draft-ietf-dhc-
|
||
|
+schema-02.doc.
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 17]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+INTERNET-DRAFT LDAP Schema for DHCP 16 June 2001
|
||
|
+
|
||
|
+
|
||
|
+14. Author's Addresses
|
||
|
+
|
||
|
+Comments regarding this draft may be sent to the authors at the
|
||
|
+following address:
|
||
|
+
|
||
|
+Mark Meredith
|
||
|
+Mark Hinckley
|
||
|
+Novell Inc.
|
||
|
+1800 S. Novell Place
|
||
|
+Provo, Utah 84606
|
||
|
+
|
||
|
+Vijay K. Nanjundaswamy
|
||
|
+Novell Software Development (I) Ltd
|
||
|
+49/1 & 49/3, Garvebhavi Palya,
|
||
|
+7th Mile, Hosur Road
|
||
|
+Bangalore 560068
|
||
|
+
|
||
|
+email: mark_meredith@novell.com
|
||
|
+email: knvijay@novell.com
|
||
|
+email: mhinckley@novell.com
|
||
|
+
|
||
|
+This Internet Draft expires December 16, 2001.
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+M. Meredith et al. Expires December 2001 [Page 18]
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
--- dhcp-3.0.5/includes/dhcpd.h.ldapconf 2007-01-31 20:39:38.000000000 -0500
|
||
|
+++ dhcp-3.0.5/includes/dhcpd.h 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -79,6 +79,11 @@
|
||
|
#include <isc-dhcp/result.h>
|
||
|
#include <omapip/omapip_p.h>
|
||
|
|
||
|
+#if defined(LDAP_CONFIGURATION)
|
||
|
+# include <ldap.h>
|
||
|
+# include <sys/utsname.h> /* for uname() */
|
||
|
+#endif
|
||
|
+
|
||
|
#if !defined (OPTION_HASH_SIZE)
|
||
|
# define OPTION_HASH_SIZE 17
|
||
|
# define OPTION_HASH_PTWO 32 /* Next power of two above option hash. */
|
||
|
@@ -139,6 +144,8 @@
|
||
|
char *inbuf;
|
||
|
unsigned bufix, buflen;
|
||
|
unsigned bufsiz;
|
||
|
+
|
||
|
+ char (*read_function) (struct parse *);
|
||
|
};
|
||
|
|
||
|
/* Variable-length array of data. */
|
||
|
@@ -244,6 +251,27 @@
|
||
|
u_int8_t hbuf [17];
|
||
|
};
|
||
|
|
||
|
+#if defined(LDAP_CONFIGURATION)
|
||
|
+# define LDAP_BUFFER_SIZE 8192
|
||
|
+# define LDAP_METHOD_STATIC 0
|
||
|
+# define LDAP_METHOD_DYNAMIC 1
|
||
|
+
|
||
|
+/* This is a tree of the current configuration we are building from LDAP */
|
||
|
+
|
||
|
+struct ldap_config_stack {
|
||
|
+ LDAPMessage * res; /* Pointer returned from ldap_search */
|
||
|
+ LDAPMessage * ldent; /* Current item in LDAP that we're processing
|
||
|
+ in res */
|
||
|
+ int close_brace; /* Put a closing } after we're through with
|
||
|
+ this item */
|
||
|
+ int processed; /* We set this flag if this base item has been
|
||
|
+ processed. After this base item is processed,
|
||
|
+ we can start processing the children */
|
||
|
+ struct ldap_config_stack *children;
|
||
|
+ struct ldap_config_stack *next;
|
||
|
+};
|
||
|
+#endif
|
||
|
+
|
||
|
typedef enum {
|
||
|
server_startup = 0,
|
||
|
server_running = 1,
|
||
|
@@ -426,6 +454,15 @@
|
||
|
# define DEFAULT_PING_TIMEOUT 1
|
||
|
#endif
|
||
|
|
||
|
+#if defined(LDAP_CONFIGURATION)
|
||
|
+# define SV_LDAP_SERVER 46
|
||
|
+# define SV_LDAP_PORT 47
|
||
|
+# define SV_LDAP_USERNAME 48
|
||
|
+# define SV_LDAP_PASSWORD 49
|
||
|
+# define SV_LDAP_BASE_DN 50
|
||
|
+# define SV_LDAP_METHOD 51
|
||
|
+#endif
|
||
|
+
|
||
|
#if !defined (DEFAULT_DEFAULT_LEASE_TIME)
|
||
|
# define DEFAULT_DEFAULT_LEASE_TIME 43200
|
||
|
#endif
|
||
|
@@ -1526,7 +1563,7 @@
|
||
|
char *quotify_string (const char *, const char *, int);
|
||
|
char *quotify_buf (const unsigned char *, unsigned, const char *, int);
|
||
|
char *print_base64 (const unsigned char *, unsigned, const char *, int);
|
||
|
-char *print_hw_addr PROTO ((int, int, unsigned char *));
|
||
|
+char *print_hw_addr PROTO ((const int, const int, const unsigned char *));
|
||
|
void print_lease PROTO ((struct lease *));
|
||
|
void dump_raw PROTO ((const unsigned char *, unsigned));
|
||
|
void dump_packet_option (struct option_cache *, struct packet *,
|
||
|
@@ -2640,3 +2677,14 @@
|
||
|
#endif /* FAILOVER_PROTOCOL */
|
||
|
|
||
|
const char *binding_state_print (enum failover_state);
|
||
|
+
|
||
|
+/* ldap.c */
|
||
|
+#if defined(LDAP_CONFIGURATION)
|
||
|
+extern struct enumeration ldap_methods;
|
||
|
+isc_result_t ldap_read_config (void);
|
||
|
+int find_haddr_in_ldap (struct host_decl **, int, unsigned,
|
||
|
+ const unsigned char *, const char *, int);
|
||
|
+int find_subclass_in_ldap (struct class *, struct class **,
|
||
|
+ struct data_string *);
|
||
|
+#endif
|
||
|
+
|
||
|
--- dhcp-3.0.5/includes/site.h.ldapconf 2002-03-12 13:33:39.000000000 -0500
|
||
|
+++ dhcp-3.0.5/includes/site.h 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -177,3 +177,13 @@
|
||
|
traces. */
|
||
|
|
||
|
#define TRACING
|
||
|
+
|
||
|
+/* Define this if you want to read your config from LDAP. Read README.ldap
|
||
|
+ about how to set this up */
|
||
|
+
|
||
|
+#define LDAP_CONFIGURATION
|
||
|
+
|
||
|
+#define _PATH_DHCPD_DB "/var/lib/dhcpd/dhcpd.leases"
|
||
|
+#define _PATH_DHCLIENT_DB "/var/lib/dhclient/dhclient.leases"
|
||
|
+#define _PATH_DHCPD_DB "/var/lib/dhcpd/dhcpd.leases"
|
||
|
+#define _PATH_DHCLIENT_DB "/var/lib/dhclient/dhclient.leases"
|
||
|
--- dhcp-3.0.5/server/Makefile.dist.ldapconf 2007-01-31 20:39:38.000000000 -0500
|
||
|
+++ dhcp-3.0.5/server/Makefile.dist 2007-01-31 21:00:06.000000000 -0500
|
||
|
@@ -25,9 +25,9 @@
|
||
|
CATMANPAGES = dhcpd.cat8 dhcpd.conf.cat5 dhcpd.leases.cat5
|
||
|
SEDMANPAGES = dhcpd.man8 dhcpd.conf.man5 dhcpd.leases.man5
|
||
|
SRCS = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \
|
||
|
- omapi.c mdb.c stables.c salloc.c ddns.c
|
||
|
+ omapi.c mdb.c stables.c salloc.c ddns.c ldap.c
|
||
|
OBJS = dhcpd.o dhcp.o bootp.o confpars.o db.o class.o failover.o \
|
||
|
- omapi.o mdb.o stables.o salloc.o ddns.o
|
||
|
+ omapi.o mdb.o stables.o salloc.o ddns.o ldap.o
|
||
|
PROG = dhcpd
|
||
|
MAN = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5
|
||
|
|
||
|
@@ -103,6 +103,6 @@
|
||
|
-e "s#RUNDIR#$(VARRUN)#g" < dhcpd.leases.5 >dhcpd.leases.man5
|
||
|
|
||
|
dhcpd: $(OBJS) $(COBJ) $(DHCPLIB)
|
||
|
- $(CC) $(LFLAGS) -pie $(RPM_OPT_FLAGS) -Wl,-z,relro,-z,now,-z,noexecstack,-z,nodlopen -o dhcpd $(OBJS) $(DHCPLIB) $(LIBS)
|
||
|
+ $(CC) $(LFLAGS) -pie $(RPM_OPT_FLAGS) -Wl,-z,relro,-z,now,-z,noexecstack,-z,nodlopen -o dhcpd $(OBJS) $(DHCPLIB) $(LIBS) -lldap
|
||
|
|
||
|
# Dependencies (semi-automatically-generated)
|
||
|
--- dhcp-3.0.5/server/class.c.ldapconf 2004-06-10 13:59:51.000000000 -0400
|
||
|
+++ dhcp-3.0.5/server/class.c 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -90,6 +90,7 @@
|
||
|
int matched = 0;
|
||
|
int status;
|
||
|
int ignorep;
|
||
|
+ int classfound;
|
||
|
|
||
|
for (class = collection -> classes; class; class = class -> nic) {
|
||
|
#if defined (DEBUG_CLASS_MATCHING)
|
||
|
@@ -135,9 +136,19 @@
|
||
|
class -> submatch, MDL));
|
||
|
if (status && data.len) {
|
||
|
nc = (struct class *)0;
|
||
|
- if (class_hash_lookup (&nc, class -> hash,
|
||
|
- (const char *)data.data,
|
||
|
- data.len, MDL)) {
|
||
|
+ classfound = class_hash_lookup (&nc,
|
||
|
+ class -> hash,
|
||
|
+ (const char *)data.data,
|
||
|
+ data.len, MDL);
|
||
|
+
|
||
|
+#ifdef LDAP_CONFIGURATION
|
||
|
+ if (!classfound &&
|
||
|
+ find_subclass_in_ldap (class,
|
||
|
+ &nc, &data))
|
||
|
+ classfound = 1;
|
||
|
+#endif
|
||
|
+
|
||
|
+ if (classfound) {
|
||
|
#if defined (DEBUG_CLASS_MATCHING)
|
||
|
log_info ("matches subclass %s.",
|
||
|
print_hex_1 (data.len,
|
||
|
--- dhcp-3.0.5/server/confpars.c.ldapconf 2007-01-31 20:39:38.000000000 -0500
|
||
|
+++ dhcp-3.0.5/server/confpars.c 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -63,7 +63,17 @@
|
||
|
|
||
|
isc_result_t readconf ()
|
||
|
{
|
||
|
- return read_conf_file (path_dhcpd_conf, root_group, ROOT_GROUP, 0);
|
||
|
+ isc_result_t res;
|
||
|
+
|
||
|
+ res = read_conf_file (path_dhcpd_conf, root_group, ROOT_GROUP, 0);
|
||
|
+#if defined(LDAP_CONFIGURATION)
|
||
|
+ if (res != ISC_R_SUCCESS)
|
||
|
+ return (res);
|
||
|
+
|
||
|
+ return ldap_read_config ();
|
||
|
+#else
|
||
|
+ return (res);
|
||
|
+#endif
|
||
|
}
|
||
|
|
||
|
isc_result_t read_conf_file (const char *filename, struct group *group,
|
||
|
--- dhcp-3.0.5/server/dhcpd.c.ldapconf 2007-01-31 20:39:38.000000000 -0500
|
||
|
+++ dhcp-3.0.5/server/dhcpd.c 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -433,6 +433,9 @@
|
||
|
/* Add the ddns update style enumeration prior to parsing. */
|
||
|
add_enumeration (&ddns_styles);
|
||
|
add_enumeration (&syslog_enum);
|
||
|
+#if defined (LDAP_CONFIGURATION)
|
||
|
+ add_enumeration (&ldap_methods);
|
||
|
+#endif
|
||
|
|
||
|
if (!group_allocate (&root_group, MDL))
|
||
|
log_fatal ("Can't allocate root group!");
|
||
|
--- /dev/null 2007-01-31 10:24:38.956568237 -0500
|
||
|
+++ dhcp-3.0.5/server/ldap.c 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -0,0 +1,1142 @@
|
||
|
+/* ldap.c
|
||
|
+
|
||
|
+ Routines for reading the configuration from LDAP */
|
||
|
+
|
||
|
+/*
|
||
|
+ * Copyright (c) 1996-2001 Ntelos, Inc.
|
||
|
+ * All rights reserved.
|
||
|
+ *
|
||
|
+ * Redistribution and use in source and binary forms, with or without
|
||
|
+ * modification, are permitted provided that the following conditions
|
||
|
+ * are met:
|
||
|
+ *
|
||
|
+ * 1. Redistributions of source code must retain the above copyright
|
||
|
+ * notice, this list of conditions and the following disclaimer.
|
||
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
||
|
+ * notice, this list of conditions and the following disclaimer in the
|
||
|
+ * documentation and/or other materials provided with the distribution.
|
||
|
+ * 3. Neither the name of The Internet Software Consortium nor the names
|
||
|
+ * of its contributors may be used to endorse or promote products derived
|
||
|
+ * from this software without specific prior written permission.
|
||
|
+ *
|
||
|
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
|
||
|
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||
|
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||
|
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||
|
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
|
||
|
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||
|
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||
|
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||
|
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||
|
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||
|
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
|
+ * SUCH DAMAGE.
|
||
|
+ *
|
||
|
+ * This LDAP module was written by Brian Masney <masneyb@ntelos.net>. It's
|
||
|
+ * development was sponsored by Ntelos, Inc. (www.ntelos.com).
|
||
|
+ */
|
||
|
+
|
||
|
+#include "dhcpd.h"
|
||
|
+
|
||
|
+#if defined(LDAP_CONFIGURATION)
|
||
|
+
|
||
|
+static LDAP * ld = NULL;
|
||
|
+static char *ldap_server = NULL,
|
||
|
+ *ldap_username = NULL,
|
||
|
+ *ldap_password = NULL,
|
||
|
+ *ldap_base_dn = NULL;
|
||
|
+static int ldap_method = LDAP_METHOD_DYNAMIC,
|
||
|
+ disable_ldap = 0;
|
||
|
+static struct ldap_config_stack *ldap_stack = NULL;
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+ldap_parse_class (struct ldap_config_stack *item, struct parse *cfile)
|
||
|
+{
|
||
|
+ struct berval **temp;
|
||
|
+
|
||
|
+ if ((temp = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
|
||
|
+ temp[0]->bv_val == NULL)
|
||
|
+ {
|
||
|
+ if (temp != NULL)
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ strncat (cfile->inbuf, "class \"", LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, temp[0]->bv_val, LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, "\" {\n", LDAP_BUFFER_SIZE);
|
||
|
+
|
||
|
+ item->close_brace = 1;
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+ldap_parse_subclass (struct ldap_config_stack *item, struct parse *cfile)
|
||
|
+{
|
||
|
+ struct berval **temp, **classdata;
|
||
|
+
|
||
|
+ if ((temp = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
|
||
|
+ temp[0]->bv_val == NULL)
|
||
|
+ {
|
||
|
+ if (temp != NULL)
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+
|
||
|
+ if ((classdata = ldap_get_values_len (ld, item->ldent,
|
||
|
+ "dhcpClassData")) == NULL ||
|
||
|
+ classdata[0]->bv_val == NULL)
|
||
|
+ {
|
||
|
+ if (classdata != NULL)
|
||
|
+ ldap_value_free_len (classdata);
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ strncat (cfile->inbuf, "subclass ", LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, (*classdata)->bv_val, LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, (*temp)->bv_val, LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
|
||
|
+
|
||
|
+ item->close_brace = 1;
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+ ldap_value_free_len (classdata);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+ldap_parse_host (struct ldap_config_stack *item, struct parse *cfile)
|
||
|
+{
|
||
|
+ struct berval **temp, **hwaddr;
|
||
|
+
|
||
|
+
|
||
|
+ if ((temp = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
|
||
|
+ temp[0]->bv_val == NULL)
|
||
|
+ {
|
||
|
+ if (temp != NULL)
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((hwaddr = ldap_get_values_len (ld, item->ldent,
|
||
|
+ "dhcpHWAddress")) == NULL ||
|
||
|
+ hwaddr[0]->bv_val == NULL)
|
||
|
+ {
|
||
|
+ if (hwaddr != NULL)
|
||
|
+ ldap_value_free_len (hwaddr);
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ strncat (cfile->inbuf, "host ", LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, (*temp)->bv_val, LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, " {\nhardware ", LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, (*hwaddr)->bv_val, LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
|
||
|
+
|
||
|
+ item->close_brace = 1;
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+ ldap_value_free_len (hwaddr);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+ldap_parse_shared_network (struct ldap_config_stack *item, struct parse *cfile)
|
||
|
+{
|
||
|
+ struct berval **temp;
|
||
|
+
|
||
|
+
|
||
|
+ if ((temp = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
|
||
|
+ temp[0]->bv_val == NULL)
|
||
|
+ {
|
||
|
+ if (temp != NULL)
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ strncat (cfile->inbuf, "shared-network ", LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, (*temp)->bv_val, LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
|
||
|
+
|
||
|
+ item->close_brace = 1;
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+parse_netmask (int netmask, char *netmaskbuf)
|
||
|
+{
|
||
|
+ unsigned long nm;
|
||
|
+ int i;
|
||
|
+
|
||
|
+ nm = 0;
|
||
|
+ for (i=1; i <= netmask; i++)
|
||
|
+ {
|
||
|
+ nm |= 1 << (32 - i);
|
||
|
+ }
|
||
|
+
|
||
|
+ sprintf (netmaskbuf, "%d.%d.%d.%d", (int) (nm >> 24) & 0xff,
|
||
|
+ (int) (nm >> 16) & 0xff,
|
||
|
+ (int) (nm >> 8) & 0xff,
|
||
|
+ (int) nm & 0xff);
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+ldap_parse_subnet (struct ldap_config_stack *item, struct parse *cfile)
|
||
|
+{
|
||
|
+ struct berval **temp, **netmask;
|
||
|
+ char netmaskbuf[16];
|
||
|
+ int i;
|
||
|
+
|
||
|
+ if ((temp = ldap_get_values_len (ld, item->ldent, "cn")) == NULL ||
|
||
|
+ temp[0]->bv_val == NULL)
|
||
|
+ {
|
||
|
+ if (temp != NULL)
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((netmask = ldap_get_values_len (ld, item->ldent,
|
||
|
+ "dhcpNetmask")) == NULL ||
|
||
|
+ netmask[0]->bv_val == NULL)
|
||
|
+ {
|
||
|
+ if (netmask != NULL)
|
||
|
+ ldap_value_free_len (netmask);
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ strncat (cfile->inbuf, "subnet ", LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, temp[0]->bv_val, LDAP_BUFFER_SIZE);
|
||
|
+
|
||
|
+ strncat (cfile->inbuf, " netmask ", LDAP_BUFFER_SIZE);
|
||
|
+ parse_netmask (strtol (netmask[0]->bv_val, NULL, 10), netmaskbuf);
|
||
|
+ strncat (cfile->inbuf, netmaskbuf, LDAP_BUFFER_SIZE);
|
||
|
+
|
||
|
+ strncat (cfile->inbuf, " {\n", LDAP_BUFFER_SIZE);
|
||
|
+
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+ ldap_value_free_len (netmask);
|
||
|
+
|
||
|
+ if ((temp = ldap_get_values_len (ld, item->ldent, "dhcpRange")) != NULL)
|
||
|
+ {
|
||
|
+ strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE);
|
||
|
+ for (i=0; temp[i]->bv_val != NULL; i++)
|
||
|
+ {
|
||
|
+ strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, temp[i]->bv_val, LDAP_BUFFER_SIZE);
|
||
|
+ }
|
||
|
+ strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+ }
|
||
|
+
|
||
|
+ item->close_brace = 1;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+ldap_parse_pool (struct ldap_config_stack *item, struct parse *cfile)
|
||
|
+{
|
||
|
+ struct berval **temp;
|
||
|
+ int i;
|
||
|
+
|
||
|
+ strncat (cfile->inbuf, "pool {\n", LDAP_BUFFER_SIZE);
|
||
|
+
|
||
|
+ if ((temp = ldap_get_values_len (ld, item->ldent, "dhcpRange")) != NULL)
|
||
|
+ {
|
||
|
+ strncat (cfile->inbuf, "range", LDAP_BUFFER_SIZE);
|
||
|
+ for (i=0; temp[i]->bv_val != NULL; i++)
|
||
|
+ {
|
||
|
+ strncat (cfile->inbuf, " ", LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, temp[i]->bv_val, LDAP_BUFFER_SIZE);
|
||
|
+ }
|
||
|
+ strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((temp = ldap_get_values_len (ld, item->ldent, "dhcpPermitList")) != NULL)
|
||
|
+ {
|
||
|
+ for (i=0; temp[i]->bv_val != NULL; i++)
|
||
|
+ {
|
||
|
+ strncat (cfile->inbuf, temp[i]->bv_val, LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
|
||
|
+ }
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+ }
|
||
|
+
|
||
|
+ item->close_brace = 1;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+ldap_parse_group (struct ldap_config_stack *item, struct parse *cfile)
|
||
|
+{
|
||
|
+ strncat (cfile->inbuf, "group {\n", LDAP_BUFFER_SIZE);
|
||
|
+ item->close_brace = 1;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+parse_external_dns (LDAPMessage * ent)
|
||
|
+{
|
||
|
+ char *search[] = {"dhcpOptionsDN", "dhcpSharedNetworkDN", "dhcpSubnetDN",
|
||
|
+ "dhcpGroupDN", "dhcpHostDN", "dhcpClassesDN",
|
||
|
+ "dhcpPoolDN", NULL};
|
||
|
+ LDAPMessage * newres, * newent;
|
||
|
+ struct ldap_config_stack *ns;
|
||
|
+ struct berval **temp;
|
||
|
+ int i, ret;
|
||
|
+
|
||
|
+ for (i=0; search[i] != NULL; i++)
|
||
|
+ {
|
||
|
+ if ((ldap_method = LDAP_METHOD_DYNAMIC) &&
|
||
|
+ (strcmp (search[i], "dhcpHostDN") == 0))
|
||
|
+ continue;
|
||
|
+
|
||
|
+ if ((temp = ldap_get_values_len (ld, ent, search[i])) == NULL)
|
||
|
+ continue;
|
||
|
+
|
||
|
+ if ((ret = ldap_search_ext_s (ld, temp[0]->bv_val, LDAP_SCOPE_BASE,
|
||
|
+ "objectClass=*", NULL, 0,
|
||
|
+ NULL, NULL, NULL, 0,
|
||
|
+ &newres)) != LDAP_SUCCESS)
|
||
|
+ {
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+ ldap_unbind_ext (ld, NULL, NULL);
|
||
|
+ ld = NULL;
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+
|
||
|
+ newent = ldap_first_entry (ld, newres);
|
||
|
+ if (newent == NULL)
|
||
|
+ {
|
||
|
+ ldap_msgfree (newres);
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+
|
||
|
+#if defined(DEBUG_LDAP)
|
||
|
+ log_info ("Adding LDAP entry '%s' as child", ldap_get_dn (ld, newent));
|
||
|
+#endif
|
||
|
+
|
||
|
+ ns = dmalloc (sizeof (*ns), MDL);
|
||
|
+ ns->res = newres;
|
||
|
+ ns->ldent = newent;
|
||
|
+ ns->close_brace = 0;
|
||
|
+ ns->processed = 0;
|
||
|
+ ns->children = NULL;
|
||
|
+ ns->next = ldap_stack->children;
|
||
|
+ ldap_stack->children = ns;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+ldap_generate_config_string (struct ldap_config_stack *item, struct parse *cfile)
|
||
|
+{
|
||
|
+ struct berval **objectClass, **temp;
|
||
|
+ int i, j, ignore, found;
|
||
|
+
|
||
|
+ if ((objectClass = ldap_get_values_len (ld, item->ldent,
|
||
|
+ "objectClass")) == NULL)
|
||
|
+ return;
|
||
|
+
|
||
|
+ ignore = 0;
|
||
|
+ found = 1;
|
||
|
+ for (i=0; objectClass[i]->bv_val != NULL; i++)
|
||
|
+ {
|
||
|
+ if (strcmp (objectClass[i]->bv_val, "dhcpSharedNetwork") == 0)
|
||
|
+ ldap_parse_shared_network (item, cfile);
|
||
|
+ else if (strcmp (objectClass[i]->bv_val, "dhcpClass") == 0)
|
||
|
+ ldap_parse_class (item, cfile);
|
||
|
+ else if (strcmp (objectClass[i]->bv_val, "dhcpSubnet") == 0)
|
||
|
+ ldap_parse_subnet (item, cfile);
|
||
|
+ else if (strcmp (objectClass[i]->bv_val, "dhcpPool") == 0)
|
||
|
+ ldap_parse_pool (item, cfile);
|
||
|
+ else if (strcmp (objectClass[i]->bv_val, "dhcpGroup") == 0)
|
||
|
+ ldap_parse_group (item, cfile);
|
||
|
+ else if (strcmp (objectClass[i]->bv_val, "dhcpHost") == 0)
|
||
|
+ {
|
||
|
+ if (ldap_method == LDAP_METHOD_STATIC)
|
||
|
+ ldap_parse_host (item, cfile);
|
||
|
+ else
|
||
|
+ {
|
||
|
+ ignore = 1;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else if (strcmp (objectClass[i]->bv_val, "dhcpSubClass") == 0)
|
||
|
+ {
|
||
|
+ if (ldap_method == LDAP_METHOD_STATIC)
|
||
|
+ ldap_parse_subclass (item, cfile);
|
||
|
+ else
|
||
|
+ {
|
||
|
+ ignore = 1;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else
|
||
|
+ found = 0;
|
||
|
+
|
||
|
+ if (found && cfile->inbuf[0] == '\0')
|
||
|
+ {
|
||
|
+ ignore = 1;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ ldap_value_free_len (objectClass);
|
||
|
+
|
||
|
+ if (ignore)
|
||
|
+ return;
|
||
|
+
|
||
|
+ if ((temp = ldap_get_values_len (ld, item->ldent, "dhcpOption")) != NULL)
|
||
|
+ {
|
||
|
+ for (j=0; temp[j]->bv_val != NULL; j++)
|
||
|
+ {
|
||
|
+ strncat (cfile->inbuf, "option ", LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, temp[j]->bv_val, LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
|
||
|
+ }
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((temp = ldap_get_values_len (ld, item->ldent, "dhcpStatements")) != NULL)
|
||
|
+ {
|
||
|
+ for (j=0; temp[j]->bv_val != NULL; j++)
|
||
|
+ {
|
||
|
+ strncat (cfile->inbuf, temp[j]->bv_val, LDAP_BUFFER_SIZE);
|
||
|
+ strncat (cfile->inbuf, ";\n", LDAP_BUFFER_SIZE);
|
||
|
+ }
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+ }
|
||
|
+
|
||
|
+ parse_external_dns (item->ldent);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+free_stack_entry (struct ldap_config_stack *item)
|
||
|
+{
|
||
|
+ ldap_msgfree (item->res);
|
||
|
+ dfree (item, MDL);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+next_ldap_entry (struct parse *cfile)
|
||
|
+{
|
||
|
+ struct ldap_config_stack *temp_stack;
|
||
|
+
|
||
|
+ if (ldap_stack->processed && ldap_stack->children != NULL)
|
||
|
+ {
|
||
|
+ temp_stack = ldap_stack->children;
|
||
|
+ if (temp_stack->close_brace)
|
||
|
+ strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
|
||
|
+
|
||
|
+ ldap_stack->children = ldap_stack->children->next;
|
||
|
+ free_stack_entry (temp_stack);
|
||
|
+
|
||
|
+ if (ldap_stack->processed && ldap_stack->children != NULL)
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (ldap_stack->close_brace)
|
||
|
+ {
|
||
|
+ strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
|
||
|
+ ldap_stack->close_brace = 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ while (ldap_stack != NULL && ldap_stack->children == NULL &&
|
||
|
+ (ldap_stack->ldent = ldap_next_entry (ld, ldap_stack->ldent)) == NULL)
|
||
|
+ {
|
||
|
+ if (ldap_stack->close_brace)
|
||
|
+ {
|
||
|
+ strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
|
||
|
+ ldap_stack->close_brace = 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ temp_stack = ldap_stack;
|
||
|
+ ldap_stack = ldap_stack->next;
|
||
|
+ free_stack_entry (temp_stack);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (ldap_stack != NULL && ldap_stack->children == NULL &&
|
||
|
+ ldap_stack->close_brace)
|
||
|
+ {
|
||
|
+ strncat (cfile->inbuf, "}\n", LDAP_BUFFER_SIZE);
|
||
|
+ ldap_stack->close_brace = 0;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+add_to_config_stack (LDAPMessage * res, LDAPMessage * ent)
|
||
|
+{
|
||
|
+ struct ldap_config_stack *ns;
|
||
|
+
|
||
|
+ ns = dmalloc (sizeof (*ns), MDL);
|
||
|
+ ns->res = res;
|
||
|
+ ns->ldent = ent;
|
||
|
+ ns->close_brace = 0;
|
||
|
+ ns->processed = 0;
|
||
|
+ ns->children = NULL;
|
||
|
+ ns->next = ldap_stack;
|
||
|
+ ldap_stack = ns;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+ldap_start (void)
|
||
|
+{
|
||
|
+ struct option_state *options;
|
||
|
+ struct option_cache *oc;
|
||
|
+ struct data_string db;
|
||
|
+ int ret;
|
||
|
+
|
||
|
+ if (ld != NULL)
|
||
|
+ return;
|
||
|
+
|
||
|
+ if (ldap_server == NULL)
|
||
|
+ {
|
||
|
+ options = NULL;
|
||
|
+ option_state_allocate (&options, MDL);
|
||
|
+
|
||
|
+ execute_statements_in_scope ((struct binding_value **) NULL,
|
||
|
+ (struct packet *) NULL, (struct lease *) NULL,
|
||
|
+ (struct client_state *) NULL, (struct option_state *) NULL,
|
||
|
+ options, &global_scope, root_group, (struct group *) NULL);
|
||
|
+
|
||
|
+ memset (&db, 0, sizeof (db));
|
||
|
+ oc = lookup_option (&server_universe, options, SV_LDAP_SERVER);
|
||
|
+ if (oc &&
|
||
|
+ evaluate_option_cache (&db, (struct packet*) NULL,
|
||
|
+ (struct lease *) NULL, (struct client_state *) NULL,
|
||
|
+ options, (struct option_state *) NULL, &global_scope, oc, MDL))
|
||
|
+ {
|
||
|
+ ldap_server = dmalloc (db.len + 1, MDL);
|
||
|
+ if (!ldap_server)
|
||
|
+ log_fatal ("no memory for ldap server");
|
||
|
+ memcpy (ldap_server, db.data, db.len);
|
||
|
+ ldap_server[db.len] = 0;
|
||
|
+ data_string_forget (&db, MDL);
|
||
|
+ }
|
||
|
+
|
||
|
+ oc = lookup_option (&server_universe, options, SV_LDAP_USERNAME);
|
||
|
+ if (oc &&
|
||
|
+ evaluate_option_cache (&db, (struct packet*) NULL,
|
||
|
+ (struct lease *) NULL, (struct client_state *) NULL,
|
||
|
+ options, (struct option_state *) NULL, &global_scope, oc, MDL))
|
||
|
+ {
|
||
|
+ ldap_username = dmalloc (db.len + 1, MDL);
|
||
|
+ if (!ldap_username)
|
||
|
+ log_fatal ("no memory for ldap username");
|
||
|
+ memcpy (ldap_username, db.data, db.len);
|
||
|
+ ldap_username[db.len] = 0;
|
||
|
+ data_string_forget (&db, MDL);
|
||
|
+ }
|
||
|
+
|
||
|
+ oc = lookup_option (&server_universe, options, SV_LDAP_PASSWORD);
|
||
|
+ if (oc &&
|
||
|
+ evaluate_option_cache (&db, (struct packet*) NULL,
|
||
|
+ (struct lease *) NULL, (struct client_state *) NULL,
|
||
|
+ options, (struct option_state *) NULL, &global_scope, oc, MDL))
|
||
|
+ {
|
||
|
+ ldap_password = dmalloc (db.len + 1, MDL);
|
||
|
+ if (!ldap_password)
|
||
|
+ log_fatal ("no memory for ldap password");
|
||
|
+ memcpy (ldap_password, db.data, db.len);
|
||
|
+ ldap_password[db.len] = 0;
|
||
|
+ data_string_forget (&db, MDL);
|
||
|
+ }
|
||
|
+
|
||
|
+ oc = lookup_option (&server_universe, options, SV_LDAP_BASE_DN);
|
||
|
+ if (oc &&
|
||
|
+ evaluate_option_cache (&db, (struct packet*) NULL,
|
||
|
+ (struct lease *) NULL, (struct client_state *) NULL,
|
||
|
+ options, (struct option_state *) NULL, &global_scope, oc, MDL))
|
||
|
+ {
|
||
|
+ ldap_base_dn = dmalloc (db.len + 1, MDL);
|
||
|
+ if (!ldap_base_dn)
|
||
|
+ log_fatal ("no memory for ldap password");
|
||
|
+ memcpy (ldap_base_dn, db.data, db.len);
|
||
|
+ ldap_base_dn[db.len] = 0;
|
||
|
+ data_string_forget (&db, MDL);
|
||
|
+ }
|
||
|
+
|
||
|
+ oc = lookup_option (&server_universe, options, SV_LDAP_METHOD);
|
||
|
+ if (oc &&
|
||
|
+ evaluate_option_cache (&db, (struct packet*) NULL,
|
||
|
+ (struct lease *) NULL, (struct client_state *) NULL,
|
||
|
+ options, (struct option_state *) NULL, &global_scope, oc, MDL))
|
||
|
+ {
|
||
|
+
|
||
|
+ if (db.len == 1)
|
||
|
+ ldap_method = db.data [0];
|
||
|
+ else
|
||
|
+ log_fatal ("invalid dns update type");
|
||
|
+ data_string_forget (&db, MDL);
|
||
|
+ }
|
||
|
+
|
||
|
+ option_state_dereference (&options, MDL);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (ldap_server == NULL || ldap_username == NULL || ldap_password == NULL ||
|
||
|
+ ldap_base_dn == NULL)
|
||
|
+ {
|
||
|
+ log_info ("Not searching LDAP since ldap-server, ldap-port, ldap-username, ldap-password and ldap-baes-dn were not specified in the config file");
|
||
|
+ disable_ldap = 1;
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+#if defined (DEBUG_LDAP)
|
||
|
+ log_info ("Connecting to LDAP server ldap://%s", ldap_server);
|
||
|
+#endif
|
||
|
+
|
||
|
+ char *tmpserver = NULL;
|
||
|
+ if ((tmpserver = malloc(strlen(ldap_server) + 8)) == NULL)
|
||
|
+ {
|
||
|
+ log_error ("Cannot init tmpldapserver string to ldap://%s", ldap_server);
|
||
|
+ disable_ldap = 1;
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (sprintf(tmpserver, "ldap://%s", ldap_server) == -1)
|
||
|
+ {
|
||
|
+ log_error ("Cannot init tmpldapserver via sprintf()");
|
||
|
+ disable_ldap = 1;
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ ldap_initialize (&ld, tmpserver);
|
||
|
+ if (ld == NULL)
|
||
|
+ {
|
||
|
+ log_error ("Cannot init ldap session to %s", ldap_server);
|
||
|
+ disable_ldap = 1;
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ free (tmpserver);
|
||
|
+
|
||
|
+ struct berval cred;
|
||
|
+ cred.bv_val = strdup(ldap_password);
|
||
|
+ cred.bv_len = strlen(ldap_password);
|
||
|
+ ret = ldap_sasl_bind_s (ld, ldap_username, LDAP_SASL_SIMPLE,
|
||
|
+ &cred, NULL,NULL, NULL);
|
||
|
+ if (ret != LDAP_SUCCESS)
|
||
|
+ {
|
||
|
+ log_error ("Error: Cannot log into ldap server %s: %s", ldap_server,
|
||
|
+ ldap_err2string (ret));
|
||
|
+ disable_ldap = 1;
|
||
|
+ ldap_unbind_ext (ld, NULL, NULL);
|
||
|
+ ld = NULL;
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+#if defined (DEBUG_LDAP)
|
||
|
+ log_info ("Successfully logged into LDAP server %s", ldap_server);
|
||
|
+#endif
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static char
|
||
|
+ldap_read_function (struct parse *cfile)
|
||
|
+{
|
||
|
+ char *dn, eofstring[2] = {EOF, '\0'};
|
||
|
+ struct ldap_config_stack *curentry;
|
||
|
+ LDAPMessage * ent, * res;
|
||
|
+ int ret;
|
||
|
+
|
||
|
+ cfile->inbuf[0] = '\0';
|
||
|
+ cfile->buflen = 0;
|
||
|
+ while (1)
|
||
|
+ {
|
||
|
+ if (ldap_stack == NULL)
|
||
|
+ {
|
||
|
+ strncat (cfile->inbuf, eofstring, LDAP_BUFFER_SIZE);
|
||
|
+ cfile->buflen = strlen (cfile->inbuf);
|
||
|
+ cfile->bufix = 1;
|
||
|
+ return (cfile->inbuf[0]);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (ldap_stack->processed && ldap_stack->children != NULL)
|
||
|
+ curentry = ldap_stack->children;
|
||
|
+ else
|
||
|
+ curentry = ldap_stack;
|
||
|
+
|
||
|
+ dn = ldap_get_dn (ld, curentry->ldent);
|
||
|
+#if defined(DEBUG_LDAP)
|
||
|
+ log_info ("Found LDAP entry '%s'", dn);
|
||
|
+#endif
|
||
|
+
|
||
|
+ ldap_generate_config_string (curentry, cfile);
|
||
|
+ if (strlen (cfile->inbuf) == 0)
|
||
|
+ {
|
||
|
+#if defined(DEBUG_LDAP)
|
||
|
+ log_info ("Skipping LDAP entry '%s'", dn);
|
||
|
+#endif
|
||
|
+ ldap_memfree (dn);
|
||
|
+ dn = NULL;
|
||
|
+ next_ldap_entry (cfile);
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+
|
||
|
+ curentry->processed = 1;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (ld == NULL)
|
||
|
+ ldap_start ();
|
||
|
+
|
||
|
+ if (ld == NULL)
|
||
|
+ {
|
||
|
+ strncat (cfile->inbuf, eofstring, LDAP_BUFFER_SIZE);
|
||
|
+ cfile->buflen = strlen (cfile->inbuf);
|
||
|
+ cfile->bufix = 1;
|
||
|
+ return (cfile->inbuf[0]);
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((ret = ldap_search_ext_s (ld, dn, LDAP_SCOPE_ONELEVEL, "objectClass=*",
|
||
|
+ NULL, 0, NULL, NULL, NULL, 0,
|
||
|
+ &res)) != LDAP_SUCCESS)
|
||
|
+ {
|
||
|
+ ldap_unbind_ext (ld, NULL, NULL);
|
||
|
+ ld = NULL;
|
||
|
+
|
||
|
+ strncat (cfile->inbuf, eofstring, LDAP_BUFFER_SIZE);
|
||
|
+ cfile->buflen = strlen (cfile->inbuf);
|
||
|
+ cfile->bufix = 1;
|
||
|
+ return (cfile->inbuf[0]);
|
||
|
+ }
|
||
|
+
|
||
|
+ ldap_memfree (dn);
|
||
|
+
|
||
|
+ ent = ldap_first_entry (ld, res);
|
||
|
+ if (ent != NULL)
|
||
|
+ add_to_config_stack (res, ent);
|
||
|
+ else
|
||
|
+ {
|
||
|
+ ldap_msgfree (res);
|
||
|
+ next_ldap_entry (cfile);
|
||
|
+ }
|
||
|
+
|
||
|
+#if defined (DEBUG_LDAP)
|
||
|
+ log_info ("Sending config line '%s'", cfile->inbuf);
|
||
|
+#endif
|
||
|
+
|
||
|
+ cfile->buflen = strlen (cfile->inbuf);
|
||
|
+ cfile->bufix = 1;
|
||
|
+ return (cfile->inbuf[0]);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static char *
|
||
|
+ldap_get_host_name (LDAPMessage * ent)
|
||
|
+{
|
||
|
+ struct berval **name;
|
||
|
+ char *ret;
|
||
|
+
|
||
|
+ ret = NULL;
|
||
|
+ if ((name = ldap_get_values_len (ld, ent, "cn")) == NULL || name[0] == NULL)
|
||
|
+ {
|
||
|
+ if (name != NULL)
|
||
|
+ ldap_value_free_len (name);
|
||
|
+
|
||
|
+#if defined (DEBUG_LDAP)
|
||
|
+ log_info ("Cannot get cn attribute for LDAP entry %s",
|
||
|
+ ldap_get_dn (ld, ent));
|
||
|
+#endif
|
||
|
+ return (NULL);
|
||
|
+ }
|
||
|
+
|
||
|
+ ret = dmalloc (strlen (name[0]->bv_val) + 1, MDL);
|
||
|
+ strcpy (ret, name[0]->bv_val);
|
||
|
+ ldap_value_free_len (name);
|
||
|
+
|
||
|
+ return (ret);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+isc_result_t
|
||
|
+ldap_read_config (void)
|
||
|
+{
|
||
|
+ struct berval **temp;
|
||
|
+ char *buffer, dn[256];
|
||
|
+ LDAPMessage * ldres, * ent;
|
||
|
+ struct parse *cfile;
|
||
|
+ struct utsname unme;
|
||
|
+ isc_result_t res;
|
||
|
+ int ret;
|
||
|
+
|
||
|
+
|
||
|
+ buffer = dmalloc (LDAP_BUFFER_SIZE, MDL);
|
||
|
+ cfile = (struct parse *) NULL;
|
||
|
+ res = new_parse (&cfile, -1, buffer, LDAP_BUFFER_SIZE, "LDAP", 0);
|
||
|
+ if (res != ISC_R_SUCCESS)
|
||
|
+ return (res);
|
||
|
+
|
||
|
+ cfile->bufix = cfile->buflen = 0;
|
||
|
+ cfile->read_function = ldap_read_function;
|
||
|
+
|
||
|
+ if (ld == NULL)
|
||
|
+ ldap_start ();
|
||
|
+ if (ld == NULL)
|
||
|
+ return (ldap_server == NULL ? ISC_R_SUCCESS : ISC_R_FAILURE);
|
||
|
+
|
||
|
+ uname (&unme);
|
||
|
+ snprintf (dn, sizeof (dn), "(&(objectClass=dhcpServer)(cn=%s))",
|
||
|
+ unme.nodename);
|
||
|
+
|
||
|
+ if ((ret = ldap_search_ext_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE, dn, NULL,
|
||
|
+ 0, NULL, NULL, NULL, 0, &ldres)) != LDAP_SUCCESS)
|
||
|
+ {
|
||
|
+ ldap_unbind_ext (ld, NULL, NULL);
|
||
|
+ ld = NULL;
|
||
|
+ log_error ("Cannot search LDAP for %s: %s", dn, ldap_err2string (ret));
|
||
|
+ return (ISC_R_FAILURE);
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((ent = ldap_first_entry (ld, ldres)) == NULL)
|
||
|
+ {
|
||
|
+ ldap_unbind_ext (ld, NULL, NULL);
|
||
|
+ ld = NULL;
|
||
|
+ log_error ("Error: Cannot find LDAP entry matching %s", dn);
|
||
|
+ return (ISC_R_FAILURE);
|
||
|
+ }
|
||
|
+
|
||
|
+#if defined(DEBUG_LDAP)
|
||
|
+ buffer = ldap_get_dn (ld, ent);
|
||
|
+ log_info ("Found LDAP entry '%s'", buffer);
|
||
|
+ ldap_memfree (buffer);
|
||
|
+#endif
|
||
|
+
|
||
|
+ if ((temp = ldap_get_values_len (ld, ent, "dhcpServiceDN")) == NULL ||
|
||
|
+ temp[0]->bv_val == NULL)
|
||
|
+ {
|
||
|
+ if (temp != NULL)
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+
|
||
|
+ ldap_unbind_ext (ld, NULL, NULL);
|
||
|
+ ld = NULL;
|
||
|
+ log_error ("Error: Cannot find LDAP entry matching %s", dn);
|
||
|
+ return (ISC_R_FAILURE);
|
||
|
+ }
|
||
|
+
|
||
|
+ ldap_msgfree (ldres);
|
||
|
+
|
||
|
+ if ((ret = ldap_search_ext_s (ld, temp[0]->bv_val, LDAP_SCOPE_BASE,
|
||
|
+ "objectClass=*", NULL, 0,
|
||
|
+ NULL, NULL, NULL, 0, &ldres)) != LDAP_SUCCESS)
|
||
|
+ {
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+ ldap_unbind_ext (ld, NULL, NULL);
|
||
|
+ ld = NULL;
|
||
|
+ log_error ("Cannot search LDAP for %s: %s", temp[0]->bv_val,
|
||
|
+ ldap_err2string (ret));
|
||
|
+ return (ISC_R_FAILURE);
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((ent = ldap_first_entry (ld, ldres)) == NULL)
|
||
|
+ {
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+ ldap_unbind_ext (ld, NULL, NULL);
|
||
|
+ ld = NULL;
|
||
|
+ log_error ("Error: Cannot find LDAP entry matching %s", temp[0]->bv_val);
|
||
|
+ return (ISC_R_FAILURE);
|
||
|
+ }
|
||
|
+
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+
|
||
|
+ add_to_config_stack (ldres, ent);
|
||
|
+
|
||
|
+ res = conf_file_subparse (cfile, root_group, ROOT_GROUP);
|
||
|
+ end_parse (&cfile);
|
||
|
+
|
||
|
+ return (res);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+/* This function will parse the dhcpOption and dhcpStatements field in the LDAP
|
||
|
+ entry if it exists. Right now, type will be either HOST_DECL or CLASS_DECL.
|
||
|
+ If we are parsing a HOST_DECL, this always returns 0. If we are parsing a
|
||
|
+ CLASS_DECL, this will return what the current lease limit is in LDAP. If
|
||
|
+ there is no lease limit specified, we return 0 */
|
||
|
+
|
||
|
+static int
|
||
|
+ldap_parse_options (LDAPMessage * ent, struct group *group,
|
||
|
+ int type, struct host_decl *host,
|
||
|
+ struct class **class)
|
||
|
+{
|
||
|
+ struct berval **temp;
|
||
|
+ char option_buffer[8192];
|
||
|
+ int i, declaration, lease_limit;
|
||
|
+ enum dhcp_token token;
|
||
|
+ struct parse *cfile;
|
||
|
+ isc_result_t res;
|
||
|
+ const char *val;
|
||
|
+
|
||
|
+ lease_limit = 0;
|
||
|
+ *option_buffer = '\0';
|
||
|
+ if ((temp = ldap_get_values_len (ld, ent, "dhcpStatements")) != NULL)
|
||
|
+ {
|
||
|
+ for (i=0; temp[i]->bv_val != NULL; i++)
|
||
|
+ {
|
||
|
+ if (strncasecmp ("lease limit ", temp[i]->bv_val, 12) == 0)
|
||
|
+ {
|
||
|
+ lease_limit = strtol ((temp[i]->bv_val) + 12, NULL, 10);
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+
|
||
|
+ strncat (option_buffer, temp[i]->bv_val, sizeof (option_buffer) - strlen (option_buffer) - 1);
|
||
|
+ strncat (option_buffer, ";\n", sizeof (option_buffer) - strlen (option_buffer) - 1);
|
||
|
+ }
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((temp = ldap_get_values_len (ld, ent, "dhcpOption")) != NULL)
|
||
|
+ {
|
||
|
+ for (i=0; temp[i]->bv_val != NULL; i++)
|
||
|
+ {
|
||
|
+ strncat (option_buffer, "option ", sizeof (option_buffer) - strlen (option_buffer) - 1);
|
||
|
+ strncat (option_buffer, temp[i]->bv_val, sizeof (option_buffer) - strlen (option_buffer) - 1);
|
||
|
+ strncat (option_buffer, ";\n", sizeof (option_buffer) - strlen (option_buffer) - 1);
|
||
|
+ }
|
||
|
+ ldap_value_free_len (temp);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (*option_buffer == '\0')
|
||
|
+ return (lease_limit);
|
||
|
+
|
||
|
+ cfile = (struct parse *) NULL;
|
||
|
+ res = new_parse (&cfile, -1, option_buffer, strlen (option_buffer),
|
||
|
+ type == HOST_DECL ? "LDAP-HOST" : "LDAP-SUBCLASS", 0);
|
||
|
+ if (res != ISC_R_SUCCESS)
|
||
|
+ return (lease_limit);
|
||
|
+
|
||
|
+#if defined (DEBUG_LDAP)
|
||
|
+ log_info ("Sending the following options: '%s'", option_buffer);
|
||
|
+#endif
|
||
|
+
|
||
|
+ declaration = 0;
|
||
|
+ do {
|
||
|
+ token = peek_token (&val, NULL, cfile);
|
||
|
+ if (token == END_OF_FILE)
|
||
|
+ break;
|
||
|
+ declaration = parse_statement (cfile, group, type, host, declaration);
|
||
|
+ } while (1);
|
||
|
+
|
||
|
+ end_parse (&cfile);
|
||
|
+
|
||
|
+ return (lease_limit);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+int
|
||
|
+find_haddr_in_ldap (struct host_decl **hp, int htype, unsigned hlen,
|
||
|
+ const unsigned char *haddr, const char *file, int line)
|
||
|
+{
|
||
|
+ char buf[60], *type_str;
|
||
|
+ LDAPMessage * res, *ent;
|
||
|
+ struct host_decl * host;
|
||
|
+ isc_result_t status;
|
||
|
+ int ret;
|
||
|
+
|
||
|
+ if (disable_ldap || ldap_method == LDAP_METHOD_STATIC)
|
||
|
+ return (0);
|
||
|
+
|
||
|
+ if (ld == NULL)
|
||
|
+ ldap_start ();
|
||
|
+ if (ld == NULL)
|
||
|
+ return (0);
|
||
|
+
|
||
|
+ switch (htype)
|
||
|
+ {
|
||
|
+ case HTYPE_ETHER:
|
||
|
+ type_str = "ethernet";
|
||
|
+ break;
|
||
|
+ case HTYPE_IEEE802:
|
||
|
+ type_str = "token-ring";
|
||
|
+ break;
|
||
|
+ case HTYPE_FDDI:
|
||
|
+ type_str = "fddi";
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ log_info ("Ignoring unknown type %d", htype);
|
||
|
+ return (0);
|
||
|
+ }
|
||
|
+
|
||
|
+ snprintf (buf, sizeof (buf), "dhcpHWAddress=%s %s", type_str,
|
||
|
+ print_hw_addr (htype, hlen, haddr));
|
||
|
+#if defined (DEBUG_LDAP)
|
||
|
+ log_info ("Searching for %s in LDAP tree %s", buf, ldap_base_dn);
|
||
|
+#endif
|
||
|
+
|
||
|
+ if ((ret = ldap_search_ext_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE,
|
||
|
+ buf, NULL, 0, NULL, NULL, NULL, 0,
|
||
|
+ &res)) != LDAP_SUCCESS)
|
||
|
+ {
|
||
|
+ if (ret != LDAP_NO_SUCH_OBJECT)
|
||
|
+ {
|
||
|
+ log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
|
||
|
+ ldap_base_dn, ldap_err2string (ret));
|
||
|
+ ldap_unbind_ext (ld, NULL, NULL);
|
||
|
+ ld = NULL;
|
||
|
+ }
|
||
|
+#if defined (DEBUG_LDAP)
|
||
|
+ else
|
||
|
+ log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
|
||
|
+ ldap_err2string (ret), buf, ldap_base_dn);
|
||
|
+#endif
|
||
|
+
|
||
|
+ return (0);
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((ent = ldap_first_entry (ld, res)) != NULL)
|
||
|
+ {
|
||
|
+#if defined (DEBUG_LDAP)
|
||
|
+ log_info ("Found LDAP entry %s", ldap_get_dn (ld, ent));
|
||
|
+#endif
|
||
|
+
|
||
|
+ host = (struct host_decl *)0;
|
||
|
+ status = host_allocate (&host, MDL);
|
||
|
+ if (status != ISC_R_SUCCESS)
|
||
|
+ {
|
||
|
+ log_fatal ("can't allocate host decl struct: %s",
|
||
|
+ isc_result_totext (status));
|
||
|
+ return (0);
|
||
|
+ }
|
||
|
+
|
||
|
+ host->name = ldap_get_host_name (ent);
|
||
|
+ if (host->name == NULL)
|
||
|
+ {
|
||
|
+ host_dereference (&host, MDL);
|
||
|
+ ldap_msgfree (res);
|
||
|
+ return (0);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!clone_group (&host->group, root_group, MDL))
|
||
|
+ {
|
||
|
+ log_fatal ("can't clone group for host %s", host->name);
|
||
|
+ host_dereference (&host, MDL);
|
||
|
+ return (0);
|
||
|
+ }
|
||
|
+
|
||
|
+ ldap_parse_options (ent, host->group, HOST_DECL, host, NULL);
|
||
|
+
|
||
|
+ *hp = host;
|
||
|
+ ldap_msgfree (res);
|
||
|
+ return (1);
|
||
|
+ }
|
||
|
+
|
||
|
+
|
||
|
+ ldap_msgfree (res);
|
||
|
+ return (0);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+int
|
||
|
+find_subclass_in_ldap (struct class *class, struct class **newclass,
|
||
|
+ struct data_string *data)
|
||
|
+{
|
||
|
+ LDAPMessage * res, * ent;
|
||
|
+ int ret, lease_limit;
|
||
|
+ isc_result_t status;
|
||
|
+ char buf[1024];
|
||
|
+
|
||
|
+ if (disable_ldap || ldap_method == LDAP_METHOD_STATIC)
|
||
|
+ return (0);
|
||
|
+
|
||
|
+ if (ld == NULL)
|
||
|
+ ldap_start ();
|
||
|
+ if (ld == NULL)
|
||
|
+ return (0);
|
||
|
+
|
||
|
+ snprintf (buf, sizeof (buf), "(&(objectClass=dhcpSubClass)(cn=%s)(dhcpClassData=%s))", print_hex_1 (data->len, data->data, 60), print_hex_2 (strlen (class->name), (const u_int8_t *) class->name, 60));
|
||
|
+#if defined (DEBUG_LDAP)
|
||
|
+ log_info ("Searching LDAP for %s", buf);
|
||
|
+#endif
|
||
|
+
|
||
|
+ if ((ret = ldap_search_ext_s (ld, ldap_base_dn, LDAP_SCOPE_SUBTREE,
|
||
|
+ buf, NULL, 0, NULL, NULL, NULL, 0,
|
||
|
+ &res)) != LDAP_SUCCESS)
|
||
|
+ {
|
||
|
+ if (ret != LDAP_NO_SUCH_OBJECT)
|
||
|
+ {
|
||
|
+ log_error ("Cannot search for %s in LDAP tree %s: %s", buf,
|
||
|
+ ldap_base_dn, ldap_err2string (ret));
|
||
|
+ ldap_unbind_ext (ld, NULL, NULL);
|
||
|
+ ld = NULL;
|
||
|
+ }
|
||
|
+#if defined (DEBUG_LDAP)
|
||
|
+ else
|
||
|
+ log_info ("ldap_search_ext_s returned %s when searching for %s in %s",
|
||
|
+ ldap_err2string (ret), buf, ldap_base_dn);
|
||
|
+#endif
|
||
|
+
|
||
|
+ return (0);
|
||
|
+ }
|
||
|
+
|
||
|
+ if ((ent = ldap_first_entry (ld, res)) != NULL)
|
||
|
+ {
|
||
|
+#if defined (DEBUG_LDAP)
|
||
|
+ log_info ("Found LDAP entry %s", ldap_get_dn (ld, ent));
|
||
|
+#endif
|
||
|
+
|
||
|
+ status = class_allocate (newclass, MDL);
|
||
|
+ if (status != ISC_R_SUCCESS)
|
||
|
+ {
|
||
|
+ log_error ("Cannot allocate memory for a new class");
|
||
|
+ return (0);
|
||
|
+ }
|
||
|
+
|
||
|
+ group_reference (&(*newclass)->group, class->group, MDL);
|
||
|
+ class_reference (&(*newclass)->superclass, class, MDL);
|
||
|
+ lease_limit = ldap_parse_options (ent, (*newclass)->group,
|
||
|
+ CLASS_DECL, NULL, newclass);
|
||
|
+ if (lease_limit == 0)
|
||
|
+ (*newclass)->lease_limit = class->lease_limit;
|
||
|
+ else
|
||
|
+ class->lease_limit = lease_limit;
|
||
|
+
|
||
|
+ if ((*newclass)->lease_limit)
|
||
|
+ {
|
||
|
+ (*newclass)->billed_leases =
|
||
|
+ dmalloc ((*newclass)->lease_limit * sizeof (struct lease *), MDL);
|
||
|
+ if (!(*newclass)->billed_leases)
|
||
|
+ {
|
||
|
+ log_error ("no memory for billing");
|
||
|
+ class_dereference (newclass, MDL);
|
||
|
+ return (0);
|
||
|
+ }
|
||
|
+ memset ((*newclass)->billed_leases, 0,
|
||
|
+ ((*newclass)->lease_limit * sizeof (*newclass)->billed_leases));
|
||
|
+ }
|
||
|
+
|
||
|
+ data_string_copy (&(*newclass)->hash_string, data, MDL);
|
||
|
+
|
||
|
+ ldap_msgfree (res);
|
||
|
+ return (1);
|
||
|
+ }
|
||
|
+
|
||
|
+
|
||
|
+ ldap_msgfree (res);
|
||
|
+ return (0);
|
||
|
+}
|
||
|
+
|
||
|
+#endif
|
||
|
+
|
||
|
--- dhcp-3.0.5/server/mdb.c.ldapconf 2007-01-31 20:39:38.000000000 -0500
|
||
|
+++ dhcp-3.0.5/server/mdb.c 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -373,6 +373,12 @@
|
||
|
const char *file, int line)
|
||
|
{
|
||
|
struct hardware h;
|
||
|
+ int ret;
|
||
|
+
|
||
|
+#if defined(LDAP_CONFIGURATION)
|
||
|
+ if ((ret = find_haddr_in_ldap (hp, htype, hlen, haddr, file, line)))
|
||
|
+ return ret;
|
||
|
+#endif
|
||
|
|
||
|
h.hlen = hlen + 1;
|
||
|
h.hbuf [0] = htype;
|
||
|
--- dhcp-3.0.5/server/stables.c.ldapconf 2004-06-10 13:59:58.000000000 -0400
|
||
|
+++ dhcp-3.0.5/server/stables.c 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -483,12 +483,21 @@
|
||
|
{ "log-facility", "Nsyslog-facilities.", &server_universe, 44 },
|
||
|
{ "do-forward-updates", "f", &server_universe, 45 },
|
||
|
{ "ping-timeout", "T", &server_universe, 46 },
|
||
|
+#if defined(LDAP_CONFIGURATION)
|
||
|
+ { "ldap-server", "t", &server_universe, 47 },
|
||
|
+ { "ldap-port", "d", &server_universe, 48 },
|
||
|
+ { "ldap-username", "t", &server_universe, 49 },
|
||
|
+ { "ldap-password", "t", &server_universe, 50 },
|
||
|
+ { "ldap-base-dn", "t", &server_universe, 51 },
|
||
|
+ { "ldap-method", "Nldap-methods.", &server_universe, 52 },
|
||
|
+#else
|
||
|
{ "unknown-47", "X", &server_universe, 47 },
|
||
|
{ "unknown-48", "X", &server_universe, 48 },
|
||
|
{ "unknown-49", "X", &server_universe, 49 },
|
||
|
{ "unknown-50", "X", &server_universe, 50 },
|
||
|
{ "unknown-51", "X", &server_universe, 51 },
|
||
|
{ "unknown-52", "X", &server_universe, 52 },
|
||
|
+#endif
|
||
|
{ "unknown-53", "X", &server_universe, 53 },
|
||
|
{ "unknown-54", "X", &server_universe, 54 },
|
||
|
{ "unknown-55", "X", &server_universe, 55 },
|
||
|
@@ -694,6 +703,20 @@
|
||
|
{ "option-end", "e", &server_universe, 255 },
|
||
|
};
|
||
|
|
||
|
+#if defined(LDAP_CONFIGURATION)
|
||
|
+struct enumeration_value ldap_values [] = {
|
||
|
+ { "static", LDAP_METHOD_STATIC },
|
||
|
+ { "dynamic", LDAP_METHOD_DYNAMIC },
|
||
|
+ { (char *) 0, 0 }
|
||
|
+};
|
||
|
+
|
||
|
+struct enumeration ldap_methods = {
|
||
|
+ (struct enumeration *)0,
|
||
|
+ "ldap-methods",
|
||
|
+ ldap_values
|
||
|
+};
|
||
|
+#endif
|
||
|
+
|
||
|
struct enumeration_value ddns_styles_values [] = {
|
||
|
{ "none", 0 },
|
||
|
{ "ad-hoc", 1 },
|
||
|
--- /dev/null 2007-01-31 10:24:38.956568237 -0500
|
||
|
+++ dhcp-3.0.5/README.ldap 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -0,0 +1,157 @@
|
||
|
+LDAP Support in DHCP
|
||
|
+Brian Masney <masneyb@ntelos.net>
|
||
|
+Last updated 8/16/2002
|
||
|
+
|
||
|
+This document describes setting up the DHCP server to read it's configuration
|
||
|
+from LDAP. This work is based on the IETF document
|
||
|
+draft-ietf-dhc-ldap-schema-01.txt included in the doc directory. For the latest
|
||
|
+version of this document, please see http://home.ntelos.net/~masneyb.
|
||
|
+
|
||
|
+First question on most people's mind is "Why do I want to store my
|
||
|
+configuration in LDAP?" If you run a small DHCP server, and the configuration
|
||
|
+on it rarely changes, then you won't need to store your configuration in LDAP.
|
||
|
+But, if you have several DHCP servers, and you want an easy way to manage your
|
||
|
+configuration, this can be a solution.
|
||
|
+
|
||
|
+The first step will be to setup your LDAP server. I am using OpenLDAP from
|
||
|
+www.openldap.org. Building and installing OpenLDAP is beyond the scope of this
|
||
|
+document. There is plenty of documentation out there about this. Once you have
|
||
|
+OpenLDAP installed, you will have to edit your slapd.conf file. I added the
|
||
|
+following 2 lines to my configuration file:
|
||
|
+
|
||
|
+include /etc/ldap/schema/dhcp.schema
|
||
|
+index dhcpHWAddress eq
|
||
|
+index dhcpClassData eq
|
||
|
+
|
||
|
+The first line tells it to include the dhcp schema file. You will find this
|
||
|
+file under the contrib directory in this distribution. You will need to copy
|
||
|
+this file to where your other schema files are (maybe
|
||
|
+/usr/local/openldap/etc/openldap/schema/). The second line sets up
|
||
|
+an index for the dhcpHWAddress parameter. The third parameter is for reading
|
||
|
+subclasses from LDAP every time a DHCP request comes in. Make sure you run the
|
||
|
+slapindex command and restart slapd to have these changes to into effect.
|
||
|
+
|
||
|
+Now that you have LDAP setup, you should be able to use gq (http://biot.com/gq/)
|
||
|
+to verify that the dhcp schema file is loaded into LDAP. Pull up gq, and click
|
||
|
+on the Schema tab. Go under objectClasses, and you should see at least the
|
||
|
+following object classes listed: dhcpClass, dhcpGroup, dhcpHost, dhcpOptions,
|
||
|
+dhcpPool, dhcpServer, dhcpService, dhcpSharedNetwork, dhcpSubClass, and
|
||
|
+dhcpSubnet. If you do not see these, you need to check over your LDAP
|
||
|
+configuration before you go any further.
|
||
|
+
|
||
|
+You should be ready to build DHCP. Edit the includes/site.h file and uncomment
|
||
|
+the #define LDAP_CONFIGURATION. Now run configure in the base source directory.
|
||
|
+Edit the work.os/server/Makefile and add -lldap to the LIBS= line. (replace os
|
||
|
+with your operating system, linux-2.2 on my machine). You should be able to
|
||
|
+type make to build your DHCP server.
|
||
|
+
|
||
|
+Once you have DHCP installed, you will need to setup your initial plaintext
|
||
|
+config file. In my /etc/dhcpd.conf file, I have:
|
||
|
+
|
||
|
+ldap-server "localhost";
|
||
|
+ldap-port 389;
|
||
|
+ldap-username "cn=DHCP User, dc=ntelos, dc=net";
|
||
|
+ldap-password "blah";
|
||
|
+ldap-base-dn "dc=ntelos, dc=net";
|
||
|
+ldap-method dynamic;
|
||
|
+
|
||
|
+All of these parameters should be self explanatory except for the ldap-method.
|
||
|
+You can set this to static or dynamic. If you set it to static, the
|
||
|
+configuration is read once on startup, and LDAP isn't used anymore. But, if you
|
||
|
+set this to dynamic, the configuration is read once on startup, and the
|
||
|
+hosts that are stored in LDAP are looked up every time a DHCP request comes in.
|
||
|
+
|
||
|
+The next step is to set up your LDAP tree. Here is an example config that will
|
||
|
+give a 10.100.0.x address to machines that have a host entry in LDAP.
|
||
|
+Otherwise, it will give a 10.200.0.x address to them. (NOTE: replace
|
||
|
+dc=ntelos, dc=net with your base dn). If you would like to convert your
|
||
|
+existing dhcpd.conf file to LDIF format, there is a script
|
||
|
+contrib/dhcpd-conf-to-ldap.pl that will convert it for you.
|
||
|
+
|
||
|
+# You must specify the server's host name in LDAP that you are going to run
|
||
|
+# DHCP on and point it to which config tree you want to use. Whenever DHCP
|
||
|
+# first starts up, it will do a search for this entry to find out which
|
||
|
+# config to use
|
||
|
+dn: cn=brian.ntelos.net, dc=ntelos, dc=net
|
||
|
+objectClass: top
|
||
|
+objectClass: dhcpServer
|
||
|
+cn: brian.ntelos.net
|
||
|
+dhcpServiceDN: cn=DHCP Service Config, dc=ntelos, dc=net
|
||
|
+
|
||
|
+# Here is the config tree that brian.ntelos.net points to.
|
||
|
+dn: cn=DHCP Service Config, dc=ntelos, dc=net
|
||
|
+cn: DHCP Service Config
|
||
|
+objectClass: top
|
||
|
+objectClass: dhcpService
|
||
|
+dhcpPrimaryDN: dc=ntelos, dc=net
|
||
|
+dhcpStatements: ddns-update-style ad-hoc
|
||
|
+dhcpStatements: default-lease-time 600
|
||
|
+dhcpStatements: max-lease-time 7200
|
||
|
+
|
||
|
+# Set up a shared network segment
|
||
|
+dn: cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
|
||
|
+cn: WV
|
||
|
+objectClass: top
|
||
|
+objectClass: dhcpSharedNetwork
|
||
|
+
|
||
|
+# Set up a subnet declaration with a pool statement. Also note that we have
|
||
|
+# a dhcpOptions object with this entry
|
||
|
+dn: cn=10.100.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
|
||
|
+cn: 10.100.0.0
|
||
|
+objectClass: top
|
||
|
+objectClass: dhcpSubnet
|
||
|
+objectClass: dhcpOptions
|
||
|
+dhcpOption: domain-name-servers 10.100.0.2
|
||
|
+dhcpOption: routers 10.100.0.1
|
||
|
+dhcpOption: subnet-mask 255.255.255.0
|
||
|
+dhcpOption: broadcast-address 10.100.0.255
|
||
|
+dhcpNetMask: 24
|
||
|
+
|
||
|
+# Set up a pool for this subnet. Only known hosts will get these IPs
|
||
|
+dn: cn=Known Pool, cn=10.100.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
|
||
|
+cn: Known Pool
|
||
|
+objectClass: top
|
||
|
+objectClass: dhcpPool
|
||
|
+dhcpRange: 10.100.0.3 10.100.0.254
|
||
|
+dhcpPermitList: deny unknown-clients
|
||
|
+
|
||
|
+# Set up another subnet declaration with a pool statement
|
||
|
+dn: cn=10.200.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
|
||
|
+cn: 10.200.0.0
|
||
|
+objectClass: top
|
||
|
+objectClass: dhcpSubnet
|
||
|
+objectClass: dhcpOptions
|
||
|
+dhcpOption: domain-name-servers 10.200.0.2
|
||
|
+dhcpOption: routers 10.200.0.1
|
||
|
+dhcpOption: subnet-mask 255.255.255.0
|
||
|
+dhcpOption: broadcast-address 10.200.0.255
|
||
|
+dhcpNetMask: 24
|
||
|
+
|
||
|
+# Set up a pool for this subnet. Only unknown hosts will get these IPs
|
||
|
+dn: cn=Known Pool, cn=10.200.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
|
||
|
+cn: Known Pool
|
||
|
+objectClass: top
|
||
|
+objectClass: dhcpPool
|
||
|
+dhcpRange: 10.200.0.3 10.200.0.254
|
||
|
+dhcpPermitList: deny known clients
|
||
|
+
|
||
|
+# Set aside a group for all of our known MAC addresses
|
||
|
+dn: cn=Customers, cn=DHCP Service Config, dc=ntelos, dc=net
|
||
|
+objectClass: top
|
||
|
+objectClass: dhcpGroup
|
||
|
+cn: Customers
|
||
|
+
|
||
|
+# Host entry for my laptop
|
||
|
+dn: cn=brianlaptop, cn=Customers, cn=DHCP Service Config, dc=ntelos, dc=net
|
||
|
+objectClass: top
|
||
|
+objectClass: dhcpHost
|
||
|
+cn: brianlaptop
|
||
|
+dhcpHWAddress: ethernet 00:00:00:00:00:00
|
||
|
+
|
||
|
+You can use the command slapadd to load all of these entries into your LDAP
|
||
|
+server. After you load this, you should be able to start up DHCP. If you run
|
||
|
+into problems reading the configuration, try running dhcpd with the -d flag.
|
||
|
+If you still have problems, edit the site.conf file in the DHCP source and
|
||
|
+add the line: COPTS= -DDEBUG_LDAP and recompile DHCP. (make sure you run make
|
||
|
+clean and rerun configure before you rebuild).
|
||
|
+
|
||
|
--- dhcp-3.0.5/site.conf.ldapconf 1999-07-07 11:20:10.000000000 -0400
|
||
|
+++ dhcp-3.0.5/site.conf 2007-01-31 20:39:38.000000000 -0500
|
||
|
@@ -1,2 +1,7 @@
|
||
|
-# Put local site configuration stuff here to override the default
|
||
|
-# settings in Makefile.conf
|
||
|
+VARDB=/var/lib/dhcpd
|
||
|
+ADMMANDIR=/usr/share/man/man8
|
||
|
+FFMANDIR=/usr/share/man/man5
|
||
|
+LIBMANDIR=/usr/share/man/man3
|
||
|
+USRMANDIR=/usr/share/man/man1
|
||
|
+LIBDIR=/usr/lib
|
||
|
+INCDIR=/usr/include
|