Home | History | Annotate | Line # | Download | only in ldap
dhcpd-conf-to-ldap revision 1.1.1.1.2.2
      1  1.1.1.1.2.2  pgoyette #!/usr/bin/perl -w
      2  1.1.1.1.2.2  pgoyette 
      3  1.1.1.1.2.2  pgoyette # Brian Masney <masneyb (at] gftp.org>
      4  1.1.1.1.2.2  pgoyette # To use this script, set your base DN below. Then run 
      5  1.1.1.1.2.2  pgoyette # ./dhcpd-conf-to-ldap.pl < /path-to-dhcpd-conf/dhcpd.conf > output-file
      6  1.1.1.1.2.2  pgoyette # The output of this script will generate entries in LDIF format. You can use
      7  1.1.1.1.2.2  pgoyette # the slapadd command to add these entries into your LDAP server. You will
      8  1.1.1.1.2.2  pgoyette # definately want to double check that your LDAP entries are correct before
      9  1.1.1.1.2.2  pgoyette # you load them into LDAP.
     10  1.1.1.1.2.2  pgoyette 
     11  1.1.1.1.2.2  pgoyette # This script does not do much error checking. Make sure before you run this
     12  1.1.1.1.2.2  pgoyette # that the DHCP server doesn't give any errors about your config file
     13  1.1.1.1.2.2  pgoyette 
     14  1.1.1.1.2.2  pgoyette # FailOver notes:
     15  1.1.1.1.2.2  pgoyette #   Failover is disabled by default, since it may need manually intervention.
     16  1.1.1.1.2.2  pgoyette #   You can try the '--use=failover' option to see what happens :-)
     17  1.1.1.1.2.2  pgoyette #
     18  1.1.1.1.2.2  pgoyette #   If enabled, the failover pool references will be written to LDIF output.
     19  1.1.1.1.2.2  pgoyette #   The failover configs itself will be added to the dhcpServer statements
     20  1.1.1.1.2.2  pgoyette #   and not to the dhcpService object (since this script uses only one and
     21  1.1.1.1.2.2  pgoyette #   it may be usefull to have multiple service containers in failover mode).
     22  1.1.1.1.2.2  pgoyette #   Further, this script does not check if primary or secondary makes sense,
     23  1.1.1.1.2.2  pgoyette #   it simply converts what it gets...
     24  1.1.1.1.2.2  pgoyette 
     25  1.1.1.1.2.2  pgoyette use Net::Domain qw(hostname hostfqdn hostdomain);
     26  1.1.1.1.2.2  pgoyette use Getopt::Long;
     27  1.1.1.1.2.2  pgoyette 
     28  1.1.1.1.2.2  pgoyette my $domain = hostdomain();           # your.domain
     29  1.1.1.1.2.2  pgoyette my $basedn = "dc=".$domain;
     30  1.1.1.1.2.2  pgoyette    $basedn =~ s/\./,dc=/g;           # dc=your,dc=domain
     31  1.1.1.1.2.2  pgoyette my $server = hostname();             # hostname (nodename)
     32  1.1.1.1.2.2  pgoyette my $dhcpcn = 'DHCP Config';          # CN of DHCP config tree
     33  1.1.1.1.2.2  pgoyette my $dhcpdn = "cn=$dhcpcn, $basedn";  # DHCP config tree DN
     34  1.1.1.1.2.2  pgoyette my $second = '';                     # secondary server DN / hostname
     35  1.1.1.1.2.2  pgoyette my $i_conf = '';                     # dhcp.conf file to read or stdin
     36  1.1.1.1.2.2  pgoyette my $o_ldif = '';                     # output ldif file name or stdout
     37  1.1.1.1.2.2  pgoyette my @use    = ();                     # extended flags (failover)
     38  1.1.1.1.2.2  pgoyette 
     39  1.1.1.1.2.2  pgoyette sub usage($;$)
     40  1.1.1.1.2.2  pgoyette {
     41  1.1.1.1.2.2  pgoyette   my $rc = shift;
     42  1.1.1.1.2.2  pgoyette   my $err= shift;
     43  1.1.1.1.2.2  pgoyette 
     44  1.1.1.1.2.2  pgoyette   print STDERR "Error: $err\n\n" if(defined $err);
     45  1.1.1.1.2.2  pgoyette   print STDERR <<__EOF_USAGE__;
     46  1.1.1.1.2.2  pgoyette usage: 
     47  1.1.1.1.2.2  pgoyette   $0 [options] < dhcpd.conf > dhcpd.ldif
     48  1.1.1.1.2.2  pgoyette 
     49  1.1.1.1.2.2  pgoyette options:
     50  1.1.1.1.2.2  pgoyette 
     51  1.1.1.1.2.2  pgoyette   --basedn  "dc=your,dc=domain"        ("$basedn")
     52  1.1.1.1.2.2  pgoyette 
     53  1.1.1.1.2.2  pgoyette   --dhcpdn  "dhcp config DN"           ("$dhcpdn")
     54  1.1.1.1.2.2  pgoyette 
     55  1.1.1.1.2.2  pgoyette   --server  "dhcp server name"         ("$server")
     56  1.1.1.1.2.2  pgoyette 
     57  1.1.1.1.2.2  pgoyette   --second  "secondary server or DN"   ("$second")
     58  1.1.1.1.2.2  pgoyette 
     59  1.1.1.1.2.2  pgoyette   --conf    "/path/to/dhcpd.conf"      (default is stdin)
     60  1.1.1.1.2.2  pgoyette   --ldif    "/path/to/output.ldif"     (default is stdout)
     61  1.1.1.1.2.2  pgoyette 
     62  1.1.1.1.2.2  pgoyette   --use     "extended features"        (see source comments)
     63  1.1.1.1.2.2  pgoyette __EOF_USAGE__
     64  1.1.1.1.2.2  pgoyette   exit($rc);
     65  1.1.1.1.2.2  pgoyette }
     66  1.1.1.1.2.2  pgoyette 
     67  1.1.1.1.2.2  pgoyette 
     68  1.1.1.1.2.2  pgoyette sub next_token
     69  1.1.1.1.2.2  pgoyette {
     70  1.1.1.1.2.2  pgoyette   local ($lowercase) = @_;
     71  1.1.1.1.2.2  pgoyette   local ($token, $newline);
     72  1.1.1.1.2.2  pgoyette 
     73  1.1.1.1.2.2  pgoyette   do 
     74  1.1.1.1.2.2  pgoyette     {
     75  1.1.1.1.2.2  pgoyette       if (!defined ($line) || length ($line) == 0)
     76  1.1.1.1.2.2  pgoyette         {
     77  1.1.1.1.2.2  pgoyette           $line = <>;
     78  1.1.1.1.2.2  pgoyette           return undef if !defined ($line);
     79  1.1.1.1.2.2  pgoyette           chop $line;
     80  1.1.1.1.2.2  pgoyette           $line_number++;
     81  1.1.1.1.2.2  pgoyette           $token_number = 0;
     82  1.1.1.1.2.2  pgoyette         }
     83  1.1.1.1.2.2  pgoyette 
     84  1.1.1.1.2.2  pgoyette       $line =~ s/#.*//;
     85  1.1.1.1.2.2  pgoyette       $line =~ s/^\s+//;
     86  1.1.1.1.2.2  pgoyette       $line =~ s/\s+$//;
     87  1.1.1.1.2.2  pgoyette     }
     88  1.1.1.1.2.2  pgoyette   while (length ($line) == 0);
     89  1.1.1.1.2.2  pgoyette 
     90  1.1.1.1.2.2  pgoyette   if (($token, $newline) = $line =~ /^(.*?)\s+(.*)/)
     91  1.1.1.1.2.2  pgoyette     {
     92  1.1.1.1.2.2  pgoyette       if ($token =~ /^"/) {
     93  1.1.1.1.2.2  pgoyette        #handle quoted token
     94  1.1.1.1.2.2  pgoyette        if ($token !~ /"\s*$/)
     95  1.1.1.1.2.2  pgoyette        {
     96  1.1.1.1.2.2  pgoyette          ($tok, $newline)  = $newline =~ /([^"]+")(.*)/;
     97  1.1.1.1.2.2  pgoyette          $token .= " $tok";
     98  1.1.1.1.2.2  pgoyette         }
     99  1.1.1.1.2.2  pgoyette       }
    100  1.1.1.1.2.2  pgoyette       $line = $newline;
    101  1.1.1.1.2.2  pgoyette     }
    102  1.1.1.1.2.2  pgoyette   else
    103  1.1.1.1.2.2  pgoyette     {
    104  1.1.1.1.2.2  pgoyette       $token = $line;
    105  1.1.1.1.2.2  pgoyette       $line = '';
    106  1.1.1.1.2.2  pgoyette     }
    107  1.1.1.1.2.2  pgoyette   $token_number++;
    108  1.1.1.1.2.2  pgoyette 
    109  1.1.1.1.2.2  pgoyette   $token =~ y/[A-Z]/[a-z]/ if $lowercase;
    110  1.1.1.1.2.2  pgoyette 
    111  1.1.1.1.2.2  pgoyette   return ($token);
    112  1.1.1.1.2.2  pgoyette }
    113  1.1.1.1.2.2  pgoyette 
    114  1.1.1.1.2.2  pgoyette 
    115  1.1.1.1.2.2  pgoyette sub remaining_line
    116  1.1.1.1.2.2  pgoyette {
    117  1.1.1.1.2.2  pgoyette   local ($block) = shift || 0;
    118  1.1.1.1.2.2  pgoyette   local ($tmp, $str);
    119  1.1.1.1.2.2  pgoyette 
    120  1.1.1.1.2.2  pgoyette   $str = "";
    121  1.1.1.1.2.2  pgoyette   while (defined($tmp = next_token (0)))
    122  1.1.1.1.2.2  pgoyette     {
    123  1.1.1.1.2.2  pgoyette       $str .= ' ' if !($str eq "");
    124  1.1.1.1.2.2  pgoyette       $str .= $tmp;
    125  1.1.1.1.2.2  pgoyette       last if $tmp =~ /;\s*$/;
    126  1.1.1.1.2.2  pgoyette       last if($block and $tmp =~ /\s*[}{]\s*$/);
    127  1.1.1.1.2.2  pgoyette     }
    128  1.1.1.1.2.2  pgoyette 
    129  1.1.1.1.2.2  pgoyette   $str =~ s/;$//;
    130  1.1.1.1.2.2  pgoyette   return ($str);
    131  1.1.1.1.2.2  pgoyette }
    132  1.1.1.1.2.2  pgoyette 
    133  1.1.1.1.2.2  pgoyette 
    134  1.1.1.1.2.2  pgoyette sub
    135  1.1.1.1.2.2  pgoyette add_dn_to_stack
    136  1.1.1.1.2.2  pgoyette {
    137  1.1.1.1.2.2  pgoyette   local ($dn) = @_;
    138  1.1.1.1.2.2  pgoyette 
    139  1.1.1.1.2.2  pgoyette   $current_dn = "$dn, $current_dn";
    140  1.1.1.1.2.2  pgoyette   $curentry{'current_dn'} = $current_dn;
    141  1.1.1.1.2.2  pgoyette }
    142  1.1.1.1.2.2  pgoyette 
    143  1.1.1.1.2.2  pgoyette 
    144  1.1.1.1.2.2  pgoyette sub
    145  1.1.1.1.2.2  pgoyette remove_dn_from_stack
    146  1.1.1.1.2.2  pgoyette {
    147  1.1.1.1.2.2  pgoyette   $current_dn =~ s/^.*?,\s*//;
    148  1.1.1.1.2.2  pgoyette }
    149  1.1.1.1.2.2  pgoyette 
    150  1.1.1.1.2.2  pgoyette 
    151  1.1.1.1.2.2  pgoyette sub
    152  1.1.1.1.2.2  pgoyette parse_error
    153  1.1.1.1.2.2  pgoyette {
    154  1.1.1.1.2.2  pgoyette   print "Parse error on line number $line_number at token number $token_number\n";
    155  1.1.1.1.2.2  pgoyette   exit (1);
    156  1.1.1.1.2.2  pgoyette }
    157  1.1.1.1.2.2  pgoyette 
    158  1.1.1.1.2.2  pgoyette sub
    159  1.1.1.1.2.2  pgoyette new_entry
    160  1.1.1.1.2.2  pgoyette {
    161  1.1.1.1.2.2  pgoyette    if (%curentry) {
    162  1.1.1.1.2.2  pgoyette      $curentry{'current_dn'} = $current_dn;
    163  1.1.1.1.2.2  pgoyette      push(@entrystack, {%curentry});
    164  1.1.1.1.2.2  pgoyette      undef(%curentry);
    165  1.1.1.1.2.2  pgoyette    }
    166  1.1.1.1.2.2  pgoyette }
    167  1.1.1.1.2.2  pgoyette 
    168  1.1.1.1.2.2  pgoyette sub
    169  1.1.1.1.2.2  pgoyette pop_entry
    170  1.1.1.1.2.2  pgoyette {
    171  1.1.1.1.2.2  pgoyette   if (%curentry) {
    172  1.1.1.1.2.2  pgoyette     push(@outputlist, {%curentry});
    173  1.1.1.1.2.2  pgoyette   }
    174  1.1.1.1.2.2  pgoyette   $rentry = pop(@entrystack);
    175  1.1.1.1.2.2  pgoyette   %curentry = %$rentry if $rentry;
    176  1.1.1.1.2.2  pgoyette }
    177  1.1.1.1.2.2  pgoyette 
    178  1.1.1.1.2.2  pgoyette 
    179  1.1.1.1.2.2  pgoyette sub
    180  1.1.1.1.2.2  pgoyette print_entry
    181  1.1.1.1.2.2  pgoyette {
    182  1.1.1.1.2.2  pgoyette   return if (scalar keys %curentry == 0);
    183  1.1.1.1.2.2  pgoyette 
    184  1.1.1.1.2.2  pgoyette   if (!defined ($curentry{'type'}))
    185  1.1.1.1.2.2  pgoyette     {
    186  1.1.1.1.2.2  pgoyette       $hostdn = "cn=$server, $basedn";
    187  1.1.1.1.2.2  pgoyette       print "dn: $hostdn\n";
    188  1.1.1.1.2.2  pgoyette       print "cn: $server\n";
    189  1.1.1.1.2.2  pgoyette       print "objectClass: top\n";
    190  1.1.1.1.2.2  pgoyette       print "objectClass: dhcpServer\n";
    191  1.1.1.1.2.2  pgoyette       print "dhcpServiceDN: $curentry{'current_dn'}\n";
    192  1.1.1.1.2.2  pgoyette       if(grep(/FaIlOvEr/i, @use))
    193  1.1.1.1.2.2  pgoyette         {
    194  1.1.1.1.2.2  pgoyette           foreach my $fo_peer (keys %failover)
    195  1.1.1.1.2.2  pgoyette             {
    196  1.1.1.1.2.2  pgoyette               next if(scalar(@{$failover{$fo_peer}}) <= 1);
    197  1.1.1.1.2.2  pgoyette               print "dhcpStatements: failover peer $fo_peer { ",
    198  1.1.1.1.2.2  pgoyette                     join('; ', @{$failover{$fo_peer}}), "; }\n";
    199  1.1.1.1.2.2  pgoyette             }
    200  1.1.1.1.2.2  pgoyette         }
    201  1.1.1.1.2.2  pgoyette       print "\n";
    202  1.1.1.1.2.2  pgoyette 
    203  1.1.1.1.2.2  pgoyette       print "dn: $curentry{'current_dn'}\n";
    204  1.1.1.1.2.2  pgoyette       print "cn: $dhcpcn\n";
    205  1.1.1.1.2.2  pgoyette       print "objectClass: top\n";
    206  1.1.1.1.2.2  pgoyette       print "objectClass: dhcpService\n";
    207  1.1.1.1.2.2  pgoyette       if (defined ($curentry{'options'}))
    208  1.1.1.1.2.2  pgoyette         {
    209  1.1.1.1.2.2  pgoyette           print "objectClass: dhcpOptions\n";
    210  1.1.1.1.2.2  pgoyette         }
    211  1.1.1.1.2.2  pgoyette       print "dhcpPrimaryDN: $hostdn\n";
    212  1.1.1.1.2.2  pgoyette       if(grep(/FaIlOvEr/i, @use) and ($second ne ''))
    213  1.1.1.1.2.2  pgoyette         {
    214  1.1.1.1.2.2  pgoyette           print "dhcpSecondaryDN: $second\n";
    215  1.1.1.1.2.2  pgoyette         }
    216  1.1.1.1.2.2  pgoyette     }
    217  1.1.1.1.2.2  pgoyette   elsif ($curentry{'type'} eq 'subnet')
    218  1.1.1.1.2.2  pgoyette     {
    219  1.1.1.1.2.2  pgoyette       print "dn: $curentry{'current_dn'}\n";
    220  1.1.1.1.2.2  pgoyette       print "cn: " . $curentry{'ip'} . "\n";
    221  1.1.1.1.2.2  pgoyette       print "objectClass: top\n";
    222  1.1.1.1.2.2  pgoyette       print "objectClass: dhcpSubnet\n";
    223  1.1.1.1.2.2  pgoyette       if (defined ($curentry{'options'}))
    224  1.1.1.1.2.2  pgoyette         {
    225  1.1.1.1.2.2  pgoyette           print "objectClass: dhcpOptions\n";
    226  1.1.1.1.2.2  pgoyette         }
    227  1.1.1.1.2.2  pgoyette       
    228  1.1.1.1.2.2  pgoyette       print "dhcpNetMask: " . $curentry{'netmask'} . "\n";
    229  1.1.1.1.2.2  pgoyette       if (defined ($curentry{'ranges'}))
    230  1.1.1.1.2.2  pgoyette         {
    231  1.1.1.1.2.2  pgoyette           foreach $statement (@{$curentry{'ranges'}})
    232  1.1.1.1.2.2  pgoyette             {
    233  1.1.1.1.2.2  pgoyette               print "dhcpRange: $statement\n";
    234  1.1.1.1.2.2  pgoyette             }
    235  1.1.1.1.2.2  pgoyette         }
    236  1.1.1.1.2.2  pgoyette     }
    237  1.1.1.1.2.2  pgoyette   elsif ($curentry{'type'} eq 'shared-network')
    238  1.1.1.1.2.2  pgoyette     {
    239  1.1.1.1.2.2  pgoyette       print "dn: $curentry{'current_dn'}\n";
    240  1.1.1.1.2.2  pgoyette       print "cn: " . $curentry{'descr'} . "\n";
    241  1.1.1.1.2.2  pgoyette       print "objectClass: top\n";
    242  1.1.1.1.2.2  pgoyette       print "objectClass: dhcpSharedNetwork\n";
    243  1.1.1.1.2.2  pgoyette       if (defined ($curentry{'options'}))
    244  1.1.1.1.2.2  pgoyette         {
    245  1.1.1.1.2.2  pgoyette           print "objectClass: dhcpOptions\n";
    246  1.1.1.1.2.2  pgoyette         }
    247  1.1.1.1.2.2  pgoyette     }
    248  1.1.1.1.2.2  pgoyette   elsif ($curentry{'type'} eq 'group')
    249  1.1.1.1.2.2  pgoyette     {
    250  1.1.1.1.2.2  pgoyette       print "dn: $curentry{'current_dn'}\n";
    251  1.1.1.1.2.2  pgoyette       print "cn: group", $curentry{'idx'}, "\n";
    252  1.1.1.1.2.2  pgoyette       print "objectClass: top\n";
    253  1.1.1.1.2.2  pgoyette       print "objectClass: dhcpGroup\n";
    254  1.1.1.1.2.2  pgoyette       if (defined ($curentry{'options'}))
    255  1.1.1.1.2.2  pgoyette         {
    256  1.1.1.1.2.2  pgoyette           print "objectClass: dhcpOptions\n";
    257  1.1.1.1.2.2  pgoyette         }
    258  1.1.1.1.2.2  pgoyette     }
    259  1.1.1.1.2.2  pgoyette   elsif ($curentry{'type'} eq 'host')
    260  1.1.1.1.2.2  pgoyette     {
    261  1.1.1.1.2.2  pgoyette       print "dn: $curentry{'current_dn'}\n";
    262  1.1.1.1.2.2  pgoyette       print "cn: " . $curentry{'host'} . "\n";
    263  1.1.1.1.2.2  pgoyette       print "objectClass: top\n";
    264  1.1.1.1.2.2  pgoyette       print "objectClass: dhcpHost\n";
    265  1.1.1.1.2.2  pgoyette       if (defined ($curentry{'options'}))
    266  1.1.1.1.2.2  pgoyette         {
    267  1.1.1.1.2.2  pgoyette           print "objectClass: dhcpOptions\n";
    268  1.1.1.1.2.2  pgoyette         }
    269  1.1.1.1.2.2  pgoyette 
    270  1.1.1.1.2.2  pgoyette       if (defined ($curentry{'hwaddress'}))
    271  1.1.1.1.2.2  pgoyette         {
    272  1.1.1.1.2.2  pgoyette           $curentry{'hwaddress'} =~ y/[A-Z]/[a-z]/;
    273  1.1.1.1.2.2  pgoyette           print "dhcpHWAddress: " . $curentry{'hwaddress'} . "\n";
    274  1.1.1.1.2.2  pgoyette         }
    275  1.1.1.1.2.2  pgoyette     }
    276  1.1.1.1.2.2  pgoyette   elsif ($curentry{'type'} eq 'pool')
    277  1.1.1.1.2.2  pgoyette     {
    278  1.1.1.1.2.2  pgoyette       print "dn: $curentry{'current_dn'}\n";
    279  1.1.1.1.2.2  pgoyette       print "cn: pool", $curentry{'idx'}, "\n";
    280  1.1.1.1.2.2  pgoyette       print "objectClass: top\n";
    281  1.1.1.1.2.2  pgoyette       print "objectClass: dhcpPool\n";
    282  1.1.1.1.2.2  pgoyette       if (defined ($curentry{'options'}))
    283  1.1.1.1.2.2  pgoyette         {
    284  1.1.1.1.2.2  pgoyette           print "objectClass: dhcpOptions\n";
    285  1.1.1.1.2.2  pgoyette         }
    286  1.1.1.1.2.2  pgoyette 
    287  1.1.1.1.2.2  pgoyette       if (defined ($curentry{'ranges'}))
    288  1.1.1.1.2.2  pgoyette         {
    289  1.1.1.1.2.2  pgoyette           foreach $statement (@{$curentry{'ranges'}})
    290  1.1.1.1.2.2  pgoyette             {
    291  1.1.1.1.2.2  pgoyette               print "dhcpRange: $statement\n";
    292  1.1.1.1.2.2  pgoyette             }
    293  1.1.1.1.2.2  pgoyette         }
    294  1.1.1.1.2.2  pgoyette     }
    295  1.1.1.1.2.2  pgoyette   elsif ($curentry{'type'} eq 'class')
    296  1.1.1.1.2.2  pgoyette     {
    297  1.1.1.1.2.2  pgoyette       print "dn: $curentry{'current_dn'}\n";
    298  1.1.1.1.2.2  pgoyette       print "cn: " . $curentry{'class'} . "\n";
    299  1.1.1.1.2.2  pgoyette       print "objectClass: top\n";
    300  1.1.1.1.2.2  pgoyette       print "objectClass: dhcpClass\n";
    301  1.1.1.1.2.2  pgoyette       if (defined ($curentry{'options'}))
    302  1.1.1.1.2.2  pgoyette         {
    303  1.1.1.1.2.2  pgoyette           print "objectClass: dhcpOptions\n";
    304  1.1.1.1.2.2  pgoyette         }
    305  1.1.1.1.2.2  pgoyette     }
    306  1.1.1.1.2.2  pgoyette   elsif ($curentry{'type'} eq 'subclass')
    307  1.1.1.1.2.2  pgoyette     {
    308  1.1.1.1.2.2  pgoyette       print "dn: $curentry{'current_dn'}\n";
    309  1.1.1.1.2.2  pgoyette       print "cn: " . $curentry{'subclass'} . "\n";
    310  1.1.1.1.2.2  pgoyette       print "objectClass: top\n";
    311  1.1.1.1.2.2  pgoyette       print "objectClass: dhcpSubClass\n";
    312  1.1.1.1.2.2  pgoyette       if (defined ($curentry{'options'}))
    313  1.1.1.1.2.2  pgoyette         {
    314  1.1.1.1.2.2  pgoyette           print "objectClass: dhcpOptions\n";
    315  1.1.1.1.2.2  pgoyette         }
    316  1.1.1.1.2.2  pgoyette       print "dhcpClassData: " . $curentry{'class'} . "\n";
    317  1.1.1.1.2.2  pgoyette     }
    318  1.1.1.1.2.2  pgoyette 
    319  1.1.1.1.2.2  pgoyette   if (defined ($curentry{'statements'}))
    320  1.1.1.1.2.2  pgoyette     {
    321  1.1.1.1.2.2  pgoyette       foreach $statement (@{$curentry{'statements'}})
    322  1.1.1.1.2.2  pgoyette         {
    323  1.1.1.1.2.2  pgoyette           print "dhcpStatements: $statement\n";
    324  1.1.1.1.2.2  pgoyette         }
    325  1.1.1.1.2.2  pgoyette     }
    326  1.1.1.1.2.2  pgoyette 
    327  1.1.1.1.2.2  pgoyette   if (defined ($curentry{'options'}))
    328  1.1.1.1.2.2  pgoyette     {
    329  1.1.1.1.2.2  pgoyette       foreach $statement (@{$curentry{'options'}})
    330  1.1.1.1.2.2  pgoyette         {
    331  1.1.1.1.2.2  pgoyette           print "dhcpOption: $statement\n";
    332  1.1.1.1.2.2  pgoyette         }
    333  1.1.1.1.2.2  pgoyette     }
    334  1.1.1.1.2.2  pgoyette 
    335  1.1.1.1.2.2  pgoyette   print "\n";
    336  1.1.1.1.2.2  pgoyette   undef (%curentry);
    337  1.1.1.1.2.2  pgoyette }
    338  1.1.1.1.2.2  pgoyette 
    339  1.1.1.1.2.2  pgoyette 
    340  1.1.1.1.2.2  pgoyette sub parse_netmask
    341  1.1.1.1.2.2  pgoyette {
    342  1.1.1.1.2.2  pgoyette   local ($netmask) = @_;
    343  1.1.1.1.2.2  pgoyette   local ($i);
    344  1.1.1.1.2.2  pgoyette 
    345  1.1.1.1.2.2  pgoyette   if ((($a, $b, $c, $d) = $netmask =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) != 4)
    346  1.1.1.1.2.2  pgoyette     {
    347  1.1.1.1.2.2  pgoyette       parse_error ();
    348  1.1.1.1.2.2  pgoyette     }
    349  1.1.1.1.2.2  pgoyette 
    350  1.1.1.1.2.2  pgoyette   $num = (($a & 0xff) << 24) |
    351  1.1.1.1.2.2  pgoyette          (($b & 0xff) << 16) |
    352  1.1.1.1.2.2  pgoyette          (($c & 0xff) << 8) |
    353  1.1.1.1.2.2  pgoyette           ($d & 0xff);
    354  1.1.1.1.2.2  pgoyette 
    355  1.1.1.1.2.2  pgoyette   for ($i=1; $i<=32 && $num & (1 << (32 - $i)); $i++)
    356  1.1.1.1.2.2  pgoyette     {
    357  1.1.1.1.2.2  pgoyette     }
    358  1.1.1.1.2.2  pgoyette   $i--;
    359  1.1.1.1.2.2  pgoyette 
    360  1.1.1.1.2.2  pgoyette   return ($i);
    361  1.1.1.1.2.2  pgoyette }
    362  1.1.1.1.2.2  pgoyette 
    363  1.1.1.1.2.2  pgoyette 
    364  1.1.1.1.2.2  pgoyette sub parse_subnet
    365  1.1.1.1.2.2  pgoyette {
    366  1.1.1.1.2.2  pgoyette   local ($ip, $tmp, $netmask);
    367  1.1.1.1.2.2  pgoyette 
    368  1.1.1.1.2.2  pgoyette   new_entry ();
    369  1.1.1.1.2.2  pgoyette     
    370  1.1.1.1.2.2  pgoyette   $ip = next_token (0);
    371  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($ip);
    372  1.1.1.1.2.2  pgoyette 
    373  1.1.1.1.2.2  pgoyette   $tmp = next_token (1);
    374  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($tmp);
    375  1.1.1.1.2.2  pgoyette   parse_error () if !($tmp eq 'netmask');
    376  1.1.1.1.2.2  pgoyette 
    377  1.1.1.1.2.2  pgoyette   $tmp = next_token (0);
    378  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($tmp);
    379  1.1.1.1.2.2  pgoyette   $netmask = parse_netmask ($tmp);
    380  1.1.1.1.2.2  pgoyette 
    381  1.1.1.1.2.2  pgoyette   $tmp = next_token (0);
    382  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($tmp);
    383  1.1.1.1.2.2  pgoyette   parse_error () if !($tmp eq '{');
    384  1.1.1.1.2.2  pgoyette 
    385  1.1.1.1.2.2  pgoyette   add_dn_to_stack ("cn=$ip");
    386  1.1.1.1.2.2  pgoyette   $curentry{'type'} = 'subnet';
    387  1.1.1.1.2.2  pgoyette   $curentry{'ip'} = $ip;
    388  1.1.1.1.2.2  pgoyette   $curentry{'netmask'} = $netmask;
    389  1.1.1.1.2.2  pgoyette   $cursubnet = $ip;
    390  1.1.1.1.2.2  pgoyette   $curcounter{$ip} = { pool  => 0, group => 0 };
    391  1.1.1.1.2.2  pgoyette }
    392  1.1.1.1.2.2  pgoyette 
    393  1.1.1.1.2.2  pgoyette 
    394  1.1.1.1.2.2  pgoyette sub parse_shared_network
    395  1.1.1.1.2.2  pgoyette {
    396  1.1.1.1.2.2  pgoyette   local ($descr, $tmp);
    397  1.1.1.1.2.2  pgoyette 
    398  1.1.1.1.2.2  pgoyette   new_entry ();
    399  1.1.1.1.2.2  pgoyette 
    400  1.1.1.1.2.2  pgoyette   $descr = next_token (0);
    401  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($descr);
    402  1.1.1.1.2.2  pgoyette 
    403  1.1.1.1.2.2  pgoyette   $tmp = next_token (0);
    404  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($tmp);
    405  1.1.1.1.2.2  pgoyette   parse_error () if !($tmp eq '{');
    406  1.1.1.1.2.2  pgoyette 
    407  1.1.1.1.2.2  pgoyette   add_dn_to_stack ("cn=$descr");
    408  1.1.1.1.2.2  pgoyette   $curentry{'type'} = 'shared-network';
    409  1.1.1.1.2.2  pgoyette   $curentry{'descr'} = $descr;
    410  1.1.1.1.2.2  pgoyette }
    411  1.1.1.1.2.2  pgoyette 
    412  1.1.1.1.2.2  pgoyette 
    413  1.1.1.1.2.2  pgoyette sub parse_host
    414  1.1.1.1.2.2  pgoyette {
    415  1.1.1.1.2.2  pgoyette   local ($descr, $tmp);
    416  1.1.1.1.2.2  pgoyette 
    417  1.1.1.1.2.2  pgoyette   new_entry ();
    418  1.1.1.1.2.2  pgoyette 
    419  1.1.1.1.2.2  pgoyette   $host = next_token (0);
    420  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($host);
    421  1.1.1.1.2.2  pgoyette 
    422  1.1.1.1.2.2  pgoyette   $tmp = next_token (0);
    423  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($tmp);
    424  1.1.1.1.2.2  pgoyette   parse_error () if !($tmp eq '{');
    425  1.1.1.1.2.2  pgoyette 
    426  1.1.1.1.2.2  pgoyette   add_dn_to_stack ("cn=$host");
    427  1.1.1.1.2.2  pgoyette   $curentry{'type'} = 'host';
    428  1.1.1.1.2.2  pgoyette   $curentry{'host'} = $host;
    429  1.1.1.1.2.2  pgoyette }
    430  1.1.1.1.2.2  pgoyette 
    431  1.1.1.1.2.2  pgoyette 
    432  1.1.1.1.2.2  pgoyette sub parse_group
    433  1.1.1.1.2.2  pgoyette {
    434  1.1.1.1.2.2  pgoyette   local ($descr, $tmp);
    435  1.1.1.1.2.2  pgoyette 
    436  1.1.1.1.2.2  pgoyette   new_entry ();
    437  1.1.1.1.2.2  pgoyette 
    438  1.1.1.1.2.2  pgoyette   $tmp = next_token (0);
    439  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($tmp);
    440  1.1.1.1.2.2  pgoyette   parse_error () if !($tmp eq '{');
    441  1.1.1.1.2.2  pgoyette 
    442  1.1.1.1.2.2  pgoyette   my $idx;
    443  1.1.1.1.2.2  pgoyette   if(exists($curcounter{$cursubnet})) {
    444  1.1.1.1.2.2  pgoyette     $idx = ++$curcounter{$cursubnet}->{'group'};
    445  1.1.1.1.2.2  pgoyette   } else {
    446  1.1.1.1.2.2  pgoyette     $idx = ++$curcounter{''}->{'group'};
    447  1.1.1.1.2.2  pgoyette   }
    448  1.1.1.1.2.2  pgoyette 
    449  1.1.1.1.2.2  pgoyette   add_dn_to_stack ("cn=group".$idx);
    450  1.1.1.1.2.2  pgoyette   $curentry{'type'} = 'group';
    451  1.1.1.1.2.2  pgoyette   $curentry{'idx'} = $idx;
    452  1.1.1.1.2.2  pgoyette }
    453  1.1.1.1.2.2  pgoyette 
    454  1.1.1.1.2.2  pgoyette 
    455  1.1.1.1.2.2  pgoyette sub parse_pool
    456  1.1.1.1.2.2  pgoyette {
    457  1.1.1.1.2.2  pgoyette   local ($descr, $tmp);
    458  1.1.1.1.2.2  pgoyette 
    459  1.1.1.1.2.2  pgoyette   new_entry ();
    460  1.1.1.1.2.2  pgoyette 
    461  1.1.1.1.2.2  pgoyette   $tmp = next_token (0);
    462  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($tmp);
    463  1.1.1.1.2.2  pgoyette   parse_error () if !($tmp eq '{');
    464  1.1.1.1.2.2  pgoyette 
    465  1.1.1.1.2.2  pgoyette   my $idx;
    466  1.1.1.1.2.2  pgoyette   if(exists($curcounter{$cursubnet})) {
    467  1.1.1.1.2.2  pgoyette     $idx = ++$curcounter{$cursubnet}->{'pool'};
    468  1.1.1.1.2.2  pgoyette   } else {
    469  1.1.1.1.2.2  pgoyette     $idx = ++$curcounter{''}->{'pool'};
    470  1.1.1.1.2.2  pgoyette   }
    471  1.1.1.1.2.2  pgoyette 
    472  1.1.1.1.2.2  pgoyette   add_dn_to_stack ("cn=pool".$idx);
    473  1.1.1.1.2.2  pgoyette   $curentry{'type'} = 'pool';
    474  1.1.1.1.2.2  pgoyette   $curentry{'idx'} = $idx;
    475  1.1.1.1.2.2  pgoyette }
    476  1.1.1.1.2.2  pgoyette 
    477  1.1.1.1.2.2  pgoyette 
    478  1.1.1.1.2.2  pgoyette sub parse_class
    479  1.1.1.1.2.2  pgoyette {
    480  1.1.1.1.2.2  pgoyette   local ($descr, $tmp);
    481  1.1.1.1.2.2  pgoyette 
    482  1.1.1.1.2.2  pgoyette   new_entry ();
    483  1.1.1.1.2.2  pgoyette 
    484  1.1.1.1.2.2  pgoyette   $class = next_token (0);
    485  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($class);
    486  1.1.1.1.2.2  pgoyette 
    487  1.1.1.1.2.2  pgoyette   $tmp = next_token (0);
    488  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($tmp);
    489  1.1.1.1.2.2  pgoyette   parse_error () if !($tmp eq '{');
    490  1.1.1.1.2.2  pgoyette 
    491  1.1.1.1.2.2  pgoyette   $class =~ s/\"//g;
    492  1.1.1.1.2.2  pgoyette   add_dn_to_stack ("cn=$class");
    493  1.1.1.1.2.2  pgoyette   $curentry{'type'} = 'class';
    494  1.1.1.1.2.2  pgoyette   $curentry{'class'} = $class;
    495  1.1.1.1.2.2  pgoyette }
    496  1.1.1.1.2.2  pgoyette 
    497  1.1.1.1.2.2  pgoyette 
    498  1.1.1.1.2.2  pgoyette sub parse_subclass
    499  1.1.1.1.2.2  pgoyette {
    500  1.1.1.1.2.2  pgoyette   local ($descr, $tmp);
    501  1.1.1.1.2.2  pgoyette 
    502  1.1.1.1.2.2  pgoyette   new_entry ();
    503  1.1.1.1.2.2  pgoyette 
    504  1.1.1.1.2.2  pgoyette   $class = next_token (0);
    505  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($class);
    506  1.1.1.1.2.2  pgoyette 
    507  1.1.1.1.2.2  pgoyette   $subclass = next_token (0);
    508  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($subclass);
    509  1.1.1.1.2.2  pgoyette 
    510  1.1.1.1.2.2  pgoyette   if (substr($subclass,-1) eq ';') {
    511  1.1.1.1.2.2  pgoyette     $tmp = ";";
    512  1.1.1.1.2.2  pgoyette     $subclass = substr($subclass,0,-1);
    513  1.1.1.1.2.2  pgoyette   } else {
    514  1.1.1.1.2.2  pgoyette     $tmp = next_token (0); 
    515  1.1.1.1.2.2  pgoyette     parse_error () if !defined ($tmp);
    516  1.1.1.1.2.2  pgoyette   }
    517  1.1.1.1.2.2  pgoyette   parse_error () if !($tmp eq '{' or $tmp eq ';');
    518  1.1.1.1.2.2  pgoyette   add_dn_to_stack ("cn=$subclass");
    519  1.1.1.1.2.2  pgoyette   $curentry{'type'} = 'subclass';
    520  1.1.1.1.2.2  pgoyette   $curentry{'class'} = $class;
    521  1.1.1.1.2.2  pgoyette   $curentry{'subclass'} = $subclass;
    522  1.1.1.1.2.2  pgoyette 
    523  1.1.1.1.2.2  pgoyette   if ($tmp eq ';') {
    524  1.1.1.1.2.2  pgoyette     pop_entry ();
    525  1.1.1.1.2.2  pgoyette     remove_dn_from_stack ();
    526  1.1.1.1.2.2  pgoyette   }
    527  1.1.1.1.2.2  pgoyette }
    528  1.1.1.1.2.2  pgoyette 
    529  1.1.1.1.2.2  pgoyette 
    530  1.1.1.1.2.2  pgoyette sub parse_hwaddress
    531  1.1.1.1.2.2  pgoyette {
    532  1.1.1.1.2.2  pgoyette   local ($type, $hw, $tmp);
    533  1.1.1.1.2.2  pgoyette 
    534  1.1.1.1.2.2  pgoyette   $type = next_token (1);
    535  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($type);
    536  1.1.1.1.2.2  pgoyette 
    537  1.1.1.1.2.2  pgoyette   $hw = next_token (1);
    538  1.1.1.1.2.2  pgoyette   parse_error () if !defined ($hw);
    539  1.1.1.1.2.2  pgoyette   $hw =~ s/;$//;
    540  1.1.1.1.2.2  pgoyette 
    541  1.1.1.1.2.2  pgoyette   $curentry{'hwaddress'} = "$type $hw";
    542  1.1.1.1.2.2  pgoyette }
    543  1.1.1.1.2.2  pgoyette 
    544  1.1.1.1.2.2  pgoyette     
    545  1.1.1.1.2.2  pgoyette sub parse_range
    546  1.1.1.1.2.2  pgoyette {
    547  1.1.1.1.2.2  pgoyette   local ($tmp, $str);
    548  1.1.1.1.2.2  pgoyette 
    549  1.1.1.1.2.2  pgoyette   $str = remaining_line ();
    550  1.1.1.1.2.2  pgoyette 
    551  1.1.1.1.2.2  pgoyette   if (!($str eq ''))
    552  1.1.1.1.2.2  pgoyette     {
    553  1.1.1.1.2.2  pgoyette       $str =~ s/;$//;
    554  1.1.1.1.2.2  pgoyette       push (@{$curentry{'ranges'}}, $str);
    555  1.1.1.1.2.2  pgoyette     }
    556  1.1.1.1.2.2  pgoyette }
    557  1.1.1.1.2.2  pgoyette 
    558  1.1.1.1.2.2  pgoyette 
    559  1.1.1.1.2.2  pgoyette sub parse_statement
    560  1.1.1.1.2.2  pgoyette {
    561  1.1.1.1.2.2  pgoyette   local ($token) = shift;
    562  1.1.1.1.2.2  pgoyette   local ($str);
    563  1.1.1.1.2.2  pgoyette 
    564  1.1.1.1.2.2  pgoyette   if ($token eq 'option')
    565  1.1.1.1.2.2  pgoyette     {
    566  1.1.1.1.2.2  pgoyette       $str = remaining_line ();
    567  1.1.1.1.2.2  pgoyette       push (@{$curentry{'options'}}, $str);
    568  1.1.1.1.2.2  pgoyette     }
    569  1.1.1.1.2.2  pgoyette   elsif($token eq 'failover')
    570  1.1.1.1.2.2  pgoyette     {
    571  1.1.1.1.2.2  pgoyette       $str = remaining_line (1); # take care on block
    572  1.1.1.1.2.2  pgoyette       if($str =~ /[{]/)
    573  1.1.1.1.2.2  pgoyette         {
    574  1.1.1.1.2.2  pgoyette           my ($peername, @statements);
    575  1.1.1.1.2.2  pgoyette 
    576  1.1.1.1.2.2  pgoyette           parse_error() if($str !~ /^\s*peer\s+(.+?)\s+[{]\s*$/);
    577  1.1.1.1.2.2  pgoyette           parse_error() if(($peername = $1) !~ /^\"?[^\"]+\"?$/);
    578  1.1.1.1.2.2  pgoyette 
    579  1.1.1.1.2.2  pgoyette           #
    580  1.1.1.1.2.2  pgoyette           # failover config block found:
    581  1.1.1.1.2.2  pgoyette           # e.g. 'failover peer "some-name" {'
    582  1.1.1.1.2.2  pgoyette           #
    583  1.1.1.1.2.2  pgoyette           if(not grep(/FaIlOvEr/i, @use))
    584  1.1.1.1.2.2  pgoyette             {
    585  1.1.1.1.2.2  pgoyette               print STDERR "Warning: Failover config 'peer $peername' found!\n";
    586  1.1.1.1.2.2  pgoyette               print STDERR "         Skipping it, since failover disabled!\n";
    587  1.1.1.1.2.2  pgoyette               print STDERR "         You may try out --use=failover option.\n";
    588  1.1.1.1.2.2  pgoyette             }
    589  1.1.1.1.2.2  pgoyette 
    590  1.1.1.1.2.2  pgoyette           until($str =~ /[}]/ or $str eq "")
    591  1.1.1.1.2.2  pgoyette             {
    592  1.1.1.1.2.2  pgoyette                 $str = remaining_line (1);
    593  1.1.1.1.2.2  pgoyette                 # collect all statements, except ending '}'
    594  1.1.1.1.2.2  pgoyette                 push(@statements, $str) if($str !~ /[}]/);
    595  1.1.1.1.2.2  pgoyette             }
    596  1.1.1.1.2.2  pgoyette           $failover{$peername} = [@statements];
    597  1.1.1.1.2.2  pgoyette         }
    598  1.1.1.1.2.2  pgoyette       else
    599  1.1.1.1.2.2  pgoyette         {
    600  1.1.1.1.2.2  pgoyette           #
    601  1.1.1.1.2.2  pgoyette           # pool reference to failover config is fine
    602  1.1.1.1.2.2  pgoyette           # e.g. 'failover peer "some-name";'
    603  1.1.1.1.2.2  pgoyette           #
    604  1.1.1.1.2.2  pgoyette           if(not grep(/FaIlOvEr/i, @use))
    605  1.1.1.1.2.2  pgoyette             {
    606  1.1.1.1.2.2  pgoyette               print STDERR "Warning: Failover reference '$str' found!\n";
    607  1.1.1.1.2.2  pgoyette               print STDERR "         Skipping it, since failover disabled!\n";
    608  1.1.1.1.2.2  pgoyette               print STDERR "         You may try out --use=failover option.\n";
    609  1.1.1.1.2.2  pgoyette             }
    610  1.1.1.1.2.2  pgoyette           else
    611  1.1.1.1.2.2  pgoyette             {
    612  1.1.1.1.2.2  pgoyette               push (@{$curentry{'statements'}}, $token. " " . $str);
    613  1.1.1.1.2.2  pgoyette             }
    614  1.1.1.1.2.2  pgoyette         }
    615  1.1.1.1.2.2  pgoyette     }
    616  1.1.1.1.2.2  pgoyette   elsif($token eq 'zone')
    617  1.1.1.1.2.2  pgoyette     {
    618  1.1.1.1.2.2  pgoyette       $str = $token;
    619  1.1.1.1.2.2  pgoyette       while($str !~ /}$/) {
    620  1.1.1.1.2.2  pgoyette         $str .= ' ' . next_token (0);
    621  1.1.1.1.2.2  pgoyette       }
    622  1.1.1.1.2.2  pgoyette       push (@{$curentry{'statements'}}, $str);
    623  1.1.1.1.2.2  pgoyette     }
    624  1.1.1.1.2.2  pgoyette   elsif($token =~ /^(authoritative)[;]*$/)
    625  1.1.1.1.2.2  pgoyette     {
    626  1.1.1.1.2.2  pgoyette       push (@{$curentry{'statements'}}, $1);
    627  1.1.1.1.2.2  pgoyette     }
    628  1.1.1.1.2.2  pgoyette   else
    629  1.1.1.1.2.2  pgoyette     {
    630  1.1.1.1.2.2  pgoyette       $str = $token . " " . remaining_line ();
    631  1.1.1.1.2.2  pgoyette       push (@{$curentry{'statements'}}, $str);
    632  1.1.1.1.2.2  pgoyette     }
    633  1.1.1.1.2.2  pgoyette }
    634  1.1.1.1.2.2  pgoyette 
    635  1.1.1.1.2.2  pgoyette 
    636  1.1.1.1.2.2  pgoyette my $ok = GetOptions(
    637  1.1.1.1.2.2  pgoyette     'basedn=s'      => \$basedn,
    638  1.1.1.1.2.2  pgoyette     'dhcpdn=s'      => \$dhcpdn,
    639  1.1.1.1.2.2  pgoyette     'server=s'      => \$server,
    640  1.1.1.1.2.2  pgoyette     'second=s'      => \$second,
    641  1.1.1.1.2.2  pgoyette     'conf=s'        => \$i_conf,
    642  1.1.1.1.2.2  pgoyette     'ldif=s'        => \$o_ldif,
    643  1.1.1.1.2.2  pgoyette     'use=s'         => \@use,
    644  1.1.1.1.2.2  pgoyette     'h|help|usage'  => sub { usage(0); },
    645  1.1.1.1.2.2  pgoyette );
    646  1.1.1.1.2.2  pgoyette 
    647  1.1.1.1.2.2  pgoyette unless($server =~ /^\w+/)
    648  1.1.1.1.2.2  pgoyette   {
    649  1.1.1.1.2.2  pgoyette     usage(1, "invalid server name '$server'");
    650  1.1.1.1.2.2  pgoyette   }
    651  1.1.1.1.2.2  pgoyette unless($basedn =~ /^\w+=[^,]+/)
    652  1.1.1.1.2.2  pgoyette   {
    653  1.1.1.1.2.2  pgoyette     usage(1, "invalid base dn '$basedn'");
    654  1.1.1.1.2.2  pgoyette   }
    655  1.1.1.1.2.2  pgoyette 
    656  1.1.1.1.2.2  pgoyette if($dhcpdn =~ /^cn=([^,]+)/i)
    657  1.1.1.1.2.2  pgoyette   {
    658  1.1.1.1.2.2  pgoyette     $dhcpcn = "$1";
    659  1.1.1.1.2.2  pgoyette   }
    660  1.1.1.1.2.2  pgoyette $second = '' if not defined $second;
    661  1.1.1.1.2.2  pgoyette unless($second eq '' or $second =~ /^cn=[^,]+\s*,\s*\w+=[^,]+/i)
    662  1.1.1.1.2.2  pgoyette   {
    663  1.1.1.1.2.2  pgoyette     if($second =~ /^cn=[^,]+$/i)
    664  1.1.1.1.2.2  pgoyette       {
    665  1.1.1.1.2.2  pgoyette         # relative DN 'cn=name'
    666  1.1.1.1.2.2  pgoyette         $second = "$second, $basedn";
    667  1.1.1.1.2.2  pgoyette       }
    668  1.1.1.1.2.2  pgoyette     elsif($second =~ /^\w+/)
    669  1.1.1.1.2.2  pgoyette       {
    670  1.1.1.1.2.2  pgoyette         # assume hostname only
    671  1.1.1.1.2.2  pgoyette         $second = "cn=$second, $basedn";
    672  1.1.1.1.2.2  pgoyette       }
    673  1.1.1.1.2.2  pgoyette     else
    674  1.1.1.1.2.2  pgoyette       {
    675  1.1.1.1.2.2  pgoyette         usage(1, "invalid secondary '$second'")
    676  1.1.1.1.2.2  pgoyette       }
    677  1.1.1.1.2.2  pgoyette   }
    678  1.1.1.1.2.2  pgoyette 
    679  1.1.1.1.2.2  pgoyette usage(1) unless($ok);
    680  1.1.1.1.2.2  pgoyette 
    681  1.1.1.1.2.2  pgoyette if($i_conf ne "" and -f $i_conf)
    682  1.1.1.1.2.2  pgoyette   {
    683  1.1.1.1.2.2  pgoyette     if(not open(STDIN, '<', $i_conf))
    684  1.1.1.1.2.2  pgoyette       {
    685  1.1.1.1.2.2  pgoyette         print STDERR "Error: can't open conf file '$i_conf': $!\n";
    686  1.1.1.1.2.2  pgoyette         exit(1);
    687  1.1.1.1.2.2  pgoyette       }
    688  1.1.1.1.2.2  pgoyette   }
    689  1.1.1.1.2.2  pgoyette if($o_ldif ne "")
    690  1.1.1.1.2.2  pgoyette   {
    691  1.1.1.1.2.2  pgoyette     if(-e $o_ldif)
    692  1.1.1.1.2.2  pgoyette       {
    693  1.1.1.1.2.2  pgoyette         print STDERR "Error: output ldif name '$o_ldif' already exists!\n";
    694  1.1.1.1.2.2  pgoyette         exit(1);
    695  1.1.1.1.2.2  pgoyette       }
    696  1.1.1.1.2.2  pgoyette     if(not open(STDOUT, '>', $o_ldif))
    697  1.1.1.1.2.2  pgoyette       {
    698  1.1.1.1.2.2  pgoyette         print STDERR "Error: can't open ldif file '$o_ldif': $!\n";
    699  1.1.1.1.2.2  pgoyette         exit(1);
    700  1.1.1.1.2.2  pgoyette       }
    701  1.1.1.1.2.2  pgoyette   }
    702  1.1.1.1.2.2  pgoyette 
    703  1.1.1.1.2.2  pgoyette 
    704  1.1.1.1.2.2  pgoyette print STDERR "Creating LDAP Configuration with the following options:\n";
    705  1.1.1.1.2.2  pgoyette print STDERR "\tBase DN: $basedn\n";
    706  1.1.1.1.2.2  pgoyette print STDERR "\tDHCP DN: $dhcpdn\n";
    707  1.1.1.1.2.2  pgoyette print STDERR "\tServer DN: cn=$server, $basedn\n";
    708  1.1.1.1.2.2  pgoyette print STDERR "\tSecondary DN: $second\n"
    709  1.1.1.1.2.2  pgoyette              if(grep(/FaIlOvEr/i, @use) and $second ne '');
    710  1.1.1.1.2.2  pgoyette print STDERR "\n";
    711  1.1.1.1.2.2  pgoyette 
    712  1.1.1.1.2.2  pgoyette my $token;
    713  1.1.1.1.2.2  pgoyette my $token_number = 0;
    714  1.1.1.1.2.2  pgoyette my $line_number = 0;
    715  1.1.1.1.2.2  pgoyette my $cursubnet = '';
    716  1.1.1.1.2.2  pgoyette my %curcounter = ( '' => { pool => 0, group => 0 } );
    717  1.1.1.1.2.2  pgoyette 
    718  1.1.1.1.2.2  pgoyette $current_dn = "$dhcpdn";
    719  1.1.1.1.2.2  pgoyette $curentry{'current_dn'} = $current_dn;
    720  1.1.1.1.2.2  pgoyette $curentry{'descr'} = $dhcpcn;
    721  1.1.1.1.2.2  pgoyette $line = '';
    722  1.1.1.1.2.2  pgoyette %failover = ();
    723  1.1.1.1.2.2  pgoyette 
    724  1.1.1.1.2.2  pgoyette while (($token = next_token (1)))
    725  1.1.1.1.2.2  pgoyette   {
    726  1.1.1.1.2.2  pgoyette     if ($token eq '}')
    727  1.1.1.1.2.2  pgoyette       {
    728  1.1.1.1.2.2  pgoyette         pop_entry ();
    729  1.1.1.1.2.2  pgoyette         if($current_dn =~ /.+?,\s*${dhcpdn}$/) {
    730  1.1.1.1.2.2  pgoyette           # don't go below dhcpdn ...
    731  1.1.1.1.2.2  pgoyette           remove_dn_from_stack ();
    732  1.1.1.1.2.2  pgoyette         }
    733  1.1.1.1.2.2  pgoyette       }
    734  1.1.1.1.2.2  pgoyette     elsif ($token eq 'subnet')
    735  1.1.1.1.2.2  pgoyette       {
    736  1.1.1.1.2.2  pgoyette         parse_subnet ();
    737  1.1.1.1.2.2  pgoyette         next;
    738  1.1.1.1.2.2  pgoyette       }
    739  1.1.1.1.2.2  pgoyette     elsif ($token eq 'shared-network')
    740  1.1.1.1.2.2  pgoyette       {
    741  1.1.1.1.2.2  pgoyette         parse_shared_network ();
    742  1.1.1.1.2.2  pgoyette         next;
    743  1.1.1.1.2.2  pgoyette       }
    744  1.1.1.1.2.2  pgoyette     elsif ($token eq 'class')
    745  1.1.1.1.2.2  pgoyette       {
    746  1.1.1.1.2.2  pgoyette         parse_class ();
    747  1.1.1.1.2.2  pgoyette         next;
    748  1.1.1.1.2.2  pgoyette       }
    749  1.1.1.1.2.2  pgoyette     elsif ($token eq 'subclass')
    750  1.1.1.1.2.2  pgoyette       {
    751  1.1.1.1.2.2  pgoyette         parse_subclass ();
    752  1.1.1.1.2.2  pgoyette         next;
    753  1.1.1.1.2.2  pgoyette       }
    754  1.1.1.1.2.2  pgoyette     elsif ($token eq 'pool')
    755  1.1.1.1.2.2  pgoyette       {
    756  1.1.1.1.2.2  pgoyette         parse_pool ();
    757  1.1.1.1.2.2  pgoyette         next;
    758  1.1.1.1.2.2  pgoyette       }
    759  1.1.1.1.2.2  pgoyette     elsif ($token eq 'group')
    760  1.1.1.1.2.2  pgoyette       {
    761  1.1.1.1.2.2  pgoyette         parse_group ();
    762  1.1.1.1.2.2  pgoyette         next;
    763  1.1.1.1.2.2  pgoyette       }
    764  1.1.1.1.2.2  pgoyette     elsif ($token eq 'host')
    765  1.1.1.1.2.2  pgoyette       {
    766  1.1.1.1.2.2  pgoyette         parse_host ();
    767  1.1.1.1.2.2  pgoyette         next;
    768  1.1.1.1.2.2  pgoyette       }
    769  1.1.1.1.2.2  pgoyette     elsif ($token eq 'hardware')
    770  1.1.1.1.2.2  pgoyette       {
    771  1.1.1.1.2.2  pgoyette         parse_hwaddress ();
    772  1.1.1.1.2.2  pgoyette         next;
    773  1.1.1.1.2.2  pgoyette       }
    774  1.1.1.1.2.2  pgoyette     elsif ($token eq 'range')
    775  1.1.1.1.2.2  pgoyette       {
    776  1.1.1.1.2.2  pgoyette         parse_range ();
    777  1.1.1.1.2.2  pgoyette         next;
    778  1.1.1.1.2.2  pgoyette       }
    779  1.1.1.1.2.2  pgoyette     else
    780  1.1.1.1.2.2  pgoyette       {
    781  1.1.1.1.2.2  pgoyette         parse_statement ($token);
    782  1.1.1.1.2.2  pgoyette         next;
    783  1.1.1.1.2.2  pgoyette       }
    784  1.1.1.1.2.2  pgoyette   }
    785  1.1.1.1.2.2  pgoyette 
    786  1.1.1.1.2.2  pgoyette pop_entry ();
    787  1.1.1.1.2.2  pgoyette 
    788  1.1.1.1.2.2  pgoyette while ($#outputlist >= 0) {
    789  1.1.1.1.2.2  pgoyette   $rentry = pop(@outputlist);
    790  1.1.1.1.2.2  pgoyette   if ($rentry) {
    791  1.1.1.1.2.2  pgoyette     %curentry = %$rentry;
    792  1.1.1.1.2.2  pgoyette     print_entry ();
    793  1.1.1.1.2.2  pgoyette   }
    794  1.1.1.1.2.2  pgoyette }
    795  1.1.1.1.2.2  pgoyette 
    796  1.1.1.1.2.2  pgoyette close(STDIN)  if($i_conf);
    797  1.1.1.1.2.2  pgoyette close(STDOUT) if($o_ldif);
    798  1.1.1.1.2.2  pgoyette 
    799  1.1.1.1.2.2  pgoyette print STDERR "Done.\n";
    800  1.1.1.1.2.2  pgoyette 
    801