35ba231dc0
- Remove manpages patch and keep modified man pages as Source files - Improve dhclient.8 man page to list options in a style consistent with most other man pages on the planet - Upgrade to latest dhcp LDAP patch, which brings in a new dhcpd-conf-to-ldap script, updated schema file, and other bug fixes including SSL support for LDAP authentication (#375711) - Do not run dhcpd and dhcrelay services by default (#362321)
761 lines
17 KiB
Perl
Executable File
761 lines
17 KiB
Perl
Executable File
#!/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
|
|
|
|
# FailOver notes:
|
|
# Failover is disabled by default, since it may need manually intervention.
|
|
# You can try the '--use=failover' option to see what happens :-)
|
|
#
|
|
# If enabled, the failover pool references will be written to LDIF output.
|
|
# The failover configs itself will be added to the dhcpServer statements
|
|
# and not to the dhcpService object (since this script uses only one and
|
|
# it may be usefull to have multiple service containers in failover mode).
|
|
# Further, this script does not check if primary or secondary makes sense,
|
|
# it simply converts what it gets...
|
|
|
|
use Net::Domain qw(hostname hostfqdn hostdomain);
|
|
use Getopt::Long;
|
|
|
|
my $domain = hostdomain(); # your.domain
|
|
my $basedn = "dc=".$domain;
|
|
$basedn =~ s/\./,dc=/g; # dc=your,dc=domain
|
|
my $server = hostname(); # hostname (nodename)
|
|
my $dhcpcn = 'DHCP Config'; # CN of DHCP config tree
|
|
my $dhcpdn = "cn=$dhcpcn, $basedn"; # DHCP config tree DN
|
|
my $second = ''; # secondary server DN / hostname
|
|
my $i_conf = ''; # dhcp.conf file to read or stdin
|
|
my $o_ldif = ''; # output ldif file name or stdout
|
|
my @use = (); # extended flags (failover)
|
|
|
|
sub usage($;$)
|
|
{
|
|
my $rc = shift;
|
|
my $err= shift;
|
|
|
|
print STDERR "Error: $err\n\n" if(defined $err);
|
|
print STDERR <<__EOF_USAGE__;
|
|
usage:
|
|
$0 [options] < dhcpd.conf > dhcpd.ldif
|
|
|
|
options:
|
|
|
|
--basedn "dc=your,dc=domain" ("$basedn")
|
|
|
|
--dhcpdn "dhcp config DN" ("$dhcpdn")
|
|
|
|
--server "dhcp server name" ("$server")
|
|
|
|
--second "secondary server or DN" ("$second")
|
|
|
|
--conf "/path/to/dhcpd.conf" (default is stdin)
|
|
--ldif "/path/to/output.ldif" (default is stdout)
|
|
|
|
--use "extended features" (see source comments)
|
|
__EOF_USAGE__
|
|
exit($rc);
|
|
}
|
|
|
|
|
|
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+(.*)/)
|
|
{
|
|
if ($token =~ /^"/) {
|
|
#handle quoted token
|
|
if ($token !~ /"\s*$/)
|
|
{
|
|
($tok, $newline) = $newline =~ /([^"]+")(.*)/;
|
|
$token .= " $tok";
|
|
}
|
|
}
|
|
$line = $newline;
|
|
}
|
|
else
|
|
{
|
|
$token = $line;
|
|
$line = '';
|
|
}
|
|
$token_number++;
|
|
|
|
$token =~ y/[A-Z]/[a-z]/ if $lowercase;
|
|
|
|
return ($token);
|
|
}
|
|
|
|
|
|
sub remaining_line
|
|
{
|
|
local ($block) = shift || 0;
|
|
local ($tmp, $str);
|
|
|
|
$str = "";
|
|
while (defined($tmp = next_token (0)))
|
|
{
|
|
$str .= ' ' if !($str eq "");
|
|
$str .= $tmp;
|
|
last if $tmp =~ /;\s*$/;
|
|
last if($block and $tmp =~ /\s*[}{]\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'}))
|
|
{
|
|
$hostdn = "cn=$server, $basedn";
|
|
print "dn: $hostdn\n";
|
|
print "cn: $server\n";
|
|
print "objectClass: top\n";
|
|
print "objectClass: dhcpServer\n";
|
|
print "dhcpServiceDN: $current_dn\n";
|
|
if(grep(/FaIlOvEr/i, @use))
|
|
{
|
|
foreach my $fo_peer (keys %failover)
|
|
{
|
|
next if(scalar(@{$failover{$fo_peer}}) <= 1);
|
|
print "dhcpStatements: failover peer $fo_peer { ",
|
|
join('; ', @{$failover{$fo_peer}}), "; }\n";
|
|
}
|
|
}
|
|
print "\n";
|
|
|
|
print "dn: $current_dn\n";
|
|
print "cn: $dhcpcn\n";
|
|
print "objectClass: top\n";
|
|
print "objectClass: dhcpService\n";
|
|
if (defined ($curentry{'options'}))
|
|
{
|
|
print "objectClass: dhcpOptions\n";
|
|
}
|
|
print "dhcpPrimaryDN: $hostdn\n";
|
|
if(grep(/FaIlOvEr/i, @use) and ($second ne ''))
|
|
{
|
|
print "dhcpSecondaryDN: $second\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{'ranges'}))
|
|
{
|
|
foreach $statement (@{$curentry{'ranges'}})
|
|
{
|
|
print "dhcpRange: $statement\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", $curentry{'idx'}, "\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'}))
|
|
{
|
|
$curentry{'hwaddress'} =~ y/[A-Z]/[a-z]/;
|
|
print "dhcpHWAddress: " . $curentry{'hwaddress'} . "\n";
|
|
}
|
|
}
|
|
elsif ($curentry{'type'} eq 'pool')
|
|
{
|
|
print "dn: $current_dn\n";
|
|
print "cn: pool", $curentry{'idx'}, "\n";
|
|
print "objectClass: top\n";
|
|
print "objectClass: dhcpPool\n";
|
|
if (defined ($curentry{'options'}))
|
|
{
|
|
print "objectClass: dhcpOptions\n";
|
|
}
|
|
|
|
if (defined ($curentry{'ranges'}))
|
|
{
|
|
foreach $statement (@{$curentry{'ranges'}})
|
|
{
|
|
print "dhcpRange: $statement\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;
|
|
$cursubnet = $ip;
|
|
$curcounter{$ip} = { pool => 0, group => 0 };
|
|
}
|
|
|
|
|
|
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 '{');
|
|
|
|
my $idx;
|
|
if(exists($curcounter{$cursubnet})) {
|
|
$idx = ++$curcounter{$cursubnet}->{'group'};
|
|
} else {
|
|
$idx = ++$curcounter{''}->{'group'};
|
|
}
|
|
|
|
add_dn_to_stack ("cn=group".$idx);
|
|
$curentry{'type'} = 'group';
|
|
$curentry{'idx'} = $idx;
|
|
}
|
|
|
|
|
|
sub parse_pool
|
|
{
|
|
local ($descr, $tmp);
|
|
|
|
print_entry () if %curentry;
|
|
|
|
$tmp = next_token (0);
|
|
parse_error () if !defined ($tmp);
|
|
parse_error () if !($tmp eq '{');
|
|
|
|
my $idx;
|
|
if(exists($curcounter{$cursubnet})) {
|
|
$idx = ++$curcounter{$cursubnet}->{'pool'};
|
|
} else {
|
|
$idx = ++$curcounter{''}->{'pool'};
|
|
}
|
|
|
|
add_dn_to_stack ("cn=pool".$idx);
|
|
$curentry{'type'} = 'pool';
|
|
$curentry{'idx'} = $idx;
|
|
}
|
|
|
|
|
|
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 (1);
|
|
parse_error () if !defined ($type);
|
|
|
|
$hw = next_token (1);
|
|
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/;$//;
|
|
push (@{$curentry{'ranges'}}, $str);
|
|
}
|
|
}
|
|
|
|
|
|
sub parse_statement
|
|
{
|
|
local ($token) = shift;
|
|
local ($str);
|
|
|
|
if ($token eq 'option')
|
|
{
|
|
$str = remaining_line ();
|
|
push (@{$curentry{'options'}}, $str);
|
|
}
|
|
elsif($token eq 'failover')
|
|
{
|
|
$str = remaining_line (1); # take care on block
|
|
if($str =~ /[{]/)
|
|
{
|
|
my ($peername, @statements);
|
|
|
|
parse_error() if($str !~ /^\s*peer\s+(.+?)\s+[{]\s*$/);
|
|
parse_error() if(($peername = $1) !~ /^\"?[^\"]+\"?$/);
|
|
|
|
#
|
|
# failover config block found:
|
|
# e.g. 'failover peer "some-name" {'
|
|
#
|
|
if(not grep(/FaIlOvEr/i, @use))
|
|
{
|
|
print STDERR "Warning: Failover config 'peer $peername' found!\n";
|
|
print STDERR " Skipping it, since failover disabled!\n";
|
|
print STDERR " You may try out --use=failover option.\n";
|
|
}
|
|
|
|
until($str =~ /[}]/ or $str eq "")
|
|
{
|
|
$str = remaining_line (1);
|
|
# collect all statements, except ending '}'
|
|
push(@statements, $str) if($str !~ /[}]/);
|
|
}
|
|
$failover{$peername} = [@statements];
|
|
}
|
|
else
|
|
{
|
|
#
|
|
# pool reference to failover config is fine
|
|
# e.g. 'failover peer "some-name";'
|
|
#
|
|
if(not grep(/FaIlOvEr/i, @use))
|
|
{
|
|
print STDERR "Warning: Failover reference '$str' found!\n";
|
|
print STDERR " Skipping it, since failover disabled!\n";
|
|
print STDERR " You may try out --use=failover option.\n";
|
|
}
|
|
else
|
|
{
|
|
push (@{$curentry{'statements'}}, $token. " " . $str);
|
|
}
|
|
}
|
|
}
|
|
elsif($token eq 'zone')
|
|
{
|
|
$str = $token;
|
|
while($str !~ /}$/) {
|
|
$str .= ' ' . next_token (0);
|
|
}
|
|
push (@{$curentry{'statements'}}, $str);
|
|
}
|
|
elsif($token =~ /^(authoritative)[;]*$/)
|
|
{
|
|
push (@{$curentry{'statements'}}, $1);
|
|
}
|
|
else
|
|
{
|
|
$str = $token . " " . remaining_line ();
|
|
push (@{$curentry{'statements'}}, $str);
|
|
}
|
|
}
|
|
|
|
|
|
my $ok = GetOptions(
|
|
'basedn=s' => \$basedn,
|
|
'dhcpdn=s' => \$dhcpdn,
|
|
'server=s' => \$server,
|
|
'second=s' => \$second,
|
|
'conf=s' => \$i_conf,
|
|
'ldif=s' => \$o_ldif,
|
|
'use=s' => \@use,
|
|
'h|help|usage' => sub { usage(0); },
|
|
);
|
|
|
|
unless($server =~ /^\w+/)
|
|
{
|
|
usage(1, "invalid server name '$server'");
|
|
}
|
|
unless($basedn =~ /^\w+=[^,]+/)
|
|
{
|
|
usage(1, "invalid base dn '$basedn'");
|
|
}
|
|
|
|
if($dhcpdn =~ /^cn=([^,]+)/i)
|
|
{
|
|
$dhcpcn = "$1";
|
|
}
|
|
$second = '' if not defined $second;
|
|
unless($second eq '' or $second =~ /^cn=[^,]+\s*,\s*\w+=[^,]+/i)
|
|
{
|
|
if($second =~ /^cn=[^,]+$/i)
|
|
{
|
|
# relative DN 'cn=name'
|
|
$second = "$second, $basedn";
|
|
}
|
|
elsif($second =~ /^\w+/)
|
|
{
|
|
# assume hostname only
|
|
$second = "cn=$second, $basedn";
|
|
}
|
|
else
|
|
{
|
|
usage(1, "invalid secondary '$second'")
|
|
}
|
|
}
|
|
|
|
usage(1) unless($ok);
|
|
|
|
if($i_conf ne "" and -f $i_conf)
|
|
{
|
|
if(not open(STDIN, '<', $i_conf))
|
|
{
|
|
print STDERR "Error: can't open conf file '$i_conf': $!\n";
|
|
exit(1);
|
|
}
|
|
}
|
|
if($o_ldif ne "")
|
|
{
|
|
if(-e $o_ldif)
|
|
{
|
|
print STDERR "Error: output ldif name '$o_ldif' already exists!\n";
|
|
exit(1);
|
|
}
|
|
if(not open(STDOUT, '>', $o_ldif))
|
|
{
|
|
print STDERR "Error: can't open ldif file '$o_ldif': $!\n";
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
|
|
print STDERR "Creating LDAP Configuration with the following options:\n";
|
|
print STDERR "\tBase DN: $basedn\n";
|
|
print STDERR "\tDHCP DN: $dhcpdn\n";
|
|
print STDERR "\tServer DN: cn=$server, $basedn\n";
|
|
print STDERR "\tSecondary DN: $second\n"
|
|
if(grep(/FaIlOvEr/i, @use) and $second ne '');
|
|
print STDERR "\n";
|
|
|
|
my $token;
|
|
my $token_number = 0;
|
|
my $line_number = 0;
|
|
my %curentry;
|
|
my $cursubnet = '';
|
|
my %curcounter = ( '' => { pool => 0, group => 0 } );
|
|
|
|
$current_dn = "$dhcpdn";
|
|
$curentry{'descr'} = $dhcpcn;
|
|
$line = '';
|
|
%failover = ();
|
|
|
|
while (($token = next_token (1)))
|
|
{
|
|
if ($token eq '}')
|
|
{
|
|
print_entry () if %curentry;
|
|
if($current_dn =~ /.+?,\s*${dhcpdn}$/) {
|
|
# don't go below dhcpdn ...
|
|
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;
|
|
}
|
|
}
|
|
|
|
close(STDIN) if($i_conf);
|
|
close(STDOUT) if($o_ldif);
|
|
|
|
print STDERR "Done.\n";
|
|
|