Benutzer:Kirmse/delixs-hostadd
delixs-hostadd
- Dieses Script dient dazu, DHCP-Hosts im LDAP einzutragen
- Parameter: --pool oder -p, --tnetz oder -t, --mac oder -m, --rechner oder -r, --ip oder i, --help oder -h
- Aufruf: delixs-hostadd -p mathe -r aachen -m aa:bb:cc:12:ef:28
Die Parameter Pool (entspricht Raum), Rechnername und MAC-Adresse sind zwingend.
das Script
<source lang="perl">
- !/usr/bin/perl
use warnings; use strict;
use Net::LDAP; use Getopt::Long;
my ($ldap, $ldap_base, $pass, $entry, $mesg, $poolname, $vorgabe_teilnetz,
$pcname, $mac, $teilnetz, $ip, $minimum, $maximum, $min, $max, $dhcpRange, $drei_oktetts, @oktetts, $my_oktett, $temp);
- --------- Konfigurationsbereich --------------------------------------------
$vorgabe_teilnetz = '10.100.0.0'; # Vorgabe fuer das Teilnetz
- ----------------------------------------------------------------------------
- Initialisieren der Variablen fuer die Parameter
$pcname = ; $poolname = ; $mac = ; $teilnetz = ; $ip = ;
- wir holen uns zuerst die Parameter,
- falls --help, dann Ausgabe der Hilfe (siehe &help) und beenden
GetOptions('rechner=s' => \$pcname,
'pool=s' => \$poolname, 'mac=s' => \$mac, 'tnetz=s' => \$teilnetz, 'ip=s' => \$ip, 'help' => \&help);
- --------- formale Ueberpruefung der uebergebenen Parameter -----------------
- Wenn kein Parameter -r oder --rechner uebergeben wurde, dann Abbruch
if ($pcname eq ) {
die "Abbruch: es wurde kein Name fuer den Rechner uebergeben!\n";
}
- Wenn der Rechnername nicht den (meinen) Konventionen entspricht, dann Abbruch
unless ($pcname =~ /^[a-zA-Z]\w{1,10}$/) {
die "Abbruch: Der Name $pcname fuer den Rechner ist nicht korrekt!\n";
}
- Wenn kein Parameter -p oder --poolname uebergeben wurde, dann Abbruch
if ($poolname eq ) {
die "Abbruch: es wurde kein Name fuer die Rechnergruppe uebergeben!\n";
}
- Wenn der Poolname nicht den (meinen) Konventionen entspricht, dann Abbruch
unless ($poolname =~ /^[a-zA-Z]\w{1,10}$/) {
die "Abbruch: Der Name fuer die Rechnergruppe ist nicht korrekt!\n";
}
- Wenn kein Parameter -m oder --mac uebergeben wurde, dann Abbruch
if ($mac eq ) {
die "Abbruch: es wurde keine MAC-Adresse uebergeben!\n";
}
- Wenn die MAC-Adresse nicht das richtige Format hat, dann Abbruch
unless ($mac =~ /^\w\w:\w\w:\w\w:\w\w:\w\w:\w\w$/) {
die "Abbruch: Die MAC-Adresse ist nicht korrekt!\n";
}
- Wenn Parameter Teilnetz uebergeben, dann kontrollieren
unless ($teilnetz eq ) {
# ob richtiges Format unless ($teilnetz =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.0$/) { die "Abbruch: Das Teilnetz $teilnetz ist keine gueltige Angabe!\n" }
}
- Wenn der Parameter nicht uebergeben
else {
# dann setzen wir das Teilnetz $teilnetz = $vorgabe_teilnetz;
}
- Wenn Parameter IP uebergeben, dann kontrollieren
unless ($ip eq ) {
# ob richtiges Format unless ($ip =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { die "Abbruch: Das IP $ip hat nicht das richtige Format!\n" }
}
- Wenn wir keine root-Rechte haben, dann Abbruch
if ($> != 0) { # siehe $EFFECTIVE_USER_ID,$EUID
die "Abbruch: das Script muss mit root-Rechten ausgefuehrt werden!\n";
}
- wir holen uns die Such-Basis ($ldap_base) aus der ldap.conf
open DATEI, '<', '/etc/ldap/ldap.conf'
or die "Abbruch: konnte ldap.conf nicht oeffnen, $!\n";
while (my $zeile = <DATEI>) {
if ($zeile =~ m/^\s*base\s+(\w.*\w)\s*$/i) { $ldap_base = $1; last; }
} close DATEI;
- da wir (spaeter) in den LDAP schreiben wollen, brauchen wir noch das Passwort
open DATEI, '<', '/etc/ldap.secret'
or die "Abbruch: konnte ldap.secret nicht oeffnen, $!\n";
$pass = <DATEI>; chomp($pass); close DATEI;
- wir verbinden uns mit dem LDAP
$ldap = Net::LDAP->new('127.0.0.1', version => 3) or die "Abbruch: $@"; $ldap->bind( dn => "cn=admin, $ldap_base", password => $pass)
or die "Abbruch: konnte mich nicht mit dem LDAP verbinden";
- wir ueberpruefen, ob das Teilnetz im LDAP existiert
$mesg = $ldap->search(base => "cn=$teilnetz,cn=DHCP Config,$ldap_base",
filter => "cn=$teilnetz");
- wenn wir keinen Eintrag erhalten haben, dann Abbruch
if (scalar ($mesg->entries) == 0) {
die "Abbruch: Das Teilnetz $teilnetz existiert nicht im LDAP!\n";
}
- Wir ueberpruefen, ob der Pool im LDAP existiert
$mesg = $ldap->search(
base => "cn=$poolname,cn=$teilnetz,cn=DHCP Config,$ldap_base", filter => "cn=$poolname", attrs => 'dhcpRange' );
- Wenn der Pool nicht gefunden wird dann Abbruch
if (scalar ($mesg->entries) == 0) {
die "Abbruch: Der Pool $poolname existiert nicht im LDAP!\n";
}
- wir holen uns den dhcpRange (die beiden IPs)
$entry = ($mesg->entries)[0]; # nur ein Element in der Liste $dhcpRange = $entry->get_value('dhcpRange');
- wir holen uns die ersten 3 Oktetts der IP
($minimum, $maximum) = split /\s+/, $dhcpRange; # am Leerzeichen splitten if ($minimum =~ /^\s*(\d{1,3}\.\d{1,3}\.\d{1,3})\.(\d{1,3})\s*$/) {
$drei_oktetts = $1; $min = $2;
} else {
die "Abbruch: der dhcpRange vom Pool $poolname konnte nicht ausgewertet werden!\n";
}
if ($maximum =~ /^\s*\d{1,3}\.\d{1,3}\.\d{1,3}\.(\d{1,3})\s*$/) {
$max = $1;
} else {
die "Abbruch: der dhcpRange vom Pool $poolname konnte nicht ausgewertet werden!\n";
}
- Wenn die IP uebergeben wurde
unless ($ip eq ) {
# dann testen, ob die IP zum Teilnetz passt ($temp) = $teilnetz =~ /^\s*(\d{1,3}\.\d{1,3})/ ; unless ( $ip =~ /^$temp/ ) { die "Abbruch: Die IP \"$ip\" passt nicht zum Teilnetz \"$teilnetz\"!\n" } # dann testen, ob die IP zu diesem Pool gehoert unless ( $ip =~ /^$drei_oktetts/ ) { die "Abbruch: Die IP \"$ip\" passt nicht zum Pool \"$drei_oktetts\"!\n" }
} else {
# wir holen uns von dem Pool alle DHCP-Hosts $mesg = $ldap->search( base => "cn=$poolname,cn=$teilnetz,cn=DHCP Config,$ldap_base", filter => 'objectClass=dhcpHost', attrs => 'dhcpStatements' ); # dann holen wir uns von allen dhcpStatements die IP / das letzte Oktett @oktetts = (); if (scalar $mesg->entries > 0) { foreach my $entry ($mesg->entries) { $temp = $entry->get_value('dhcpStatements'); if ($temp =~ /^fixed-address\s*\d{1,3}\.\d{1,3}\.\d{1,3}\.(\d{1,3})$/) { push @oktetts, $1; } } }
# dann sortieren wir die Liste, groesste Zahl ist vorn @oktetts = sort { $b <=> $a } @oktetts; if (scalar @oktetts == 0) { $my_oktett = $min; } else { $my_oktett = $oktetts[0] + 1; }
# wir testen, ob $my_oktett kleiner als die Obergrenze von dhcpRange ist if ($my_oktett > $max) { die "Abbruch: die Obergrenze von dhcpRange wurde ueberschritten!\n"; }
# wir bauen uns die IP $ip = $drei_oktetts . '.' . $my_oktett;
}
- um z.B. versehentliches mehrfaches Aufrufen des Scriptes abzufangen:
$mesg = $ldap->search(
base => "cn=$pcname,cn=$poolname,cn=$teilnetz,cn=DHCP Config,$ldap_base", filter => 'objectClass=dhcpHost' );
- Wenn der Host gefunden wird dann Abbruch
if (scalar ($mesg->entries) > 0) {
die "Abbruch: Der Host $pcname ist schon im LDAP eingetragen!\n";
}
- jetzt tragen wir (endlich) den Host ein
$mesg = $ldap->add(
dn => "cn=$pcname,cn=$poolname,cn=$teilnetz,cn=DHCP Config,$ldap_base", attr => [ objectClass => ['top', 'dhcpHost'], cn => $pcname, dhcpHWAddress => "ethernet $mac", dhcpStatements => "fixed-address $ip" ] );
- wenn Fehlercode, dann das Script mit Fehlermeldung sterben lassen (nur dann!)
$mesg->code and die $mesg->error;
- wir trennen uns vom LDAP
$ldap->unbind;
- Ausgabe auf der Konsole (Rueckmeldung)
print "Der DHCP-Host \"$pcname\" wurde in den LDAP eingetragen.\n";
- Programm-Ende #####################################
- Wenn Parameter -h uebergeben wurde, dann Hilfe ausgegeben und beenden
sub help {
print "Hilfe muss noch erstellt werden.\n"; exit (0);
}
__END__
</source>