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>