initial commit of file from CVS for smeserver-dhcp-dns on Sat Sep 7 20:16:46 AEST 2024

This commit is contained in:
Trevor Batley
2024-09-07 20:16:46 +10:00
parent a9690bc7a2
commit 7685f89bf4
16 changed files with 1161 additions and 2 deletions

View File

@@ -0,0 +1 @@
enabled

View File

@@ -0,0 +1 @@
service

View File

@@ -0,0 +1,138 @@
{
use strict;
use warnings;
use esmith::Logger;
use esmith::ConfigDB;
use esmith::HostsDB;
use Time::TAI64 qw /unixtai64/;
use Date::Manip qw /UnixDate/;
use File::Copy;
my $DB = esmith::ConfigDB->open_ro or die ("Unable to open configuration database");
my $hosts = esmith::HostsDB->open_ro or die ("Unable to open Host database");
my $dhcpdns = $DB->get_prop('dhcp-dns','status') || 'disabled';
return '' if $dhcpdns ne 'enabled';
#we start a hash for name & ip
my %allocated_name = ();
my %allocated_ip_dhcplease = ();
#start a hash of all hosts in DB
my @hosts = $hosts->keys;
my %hostsdb;
@hostsdb{@hosts} = ();
# copy dhcpd.leases to /tmp
copy("/var/lib/dhcpd/dhcpd.leases","/tmp/tmpdhcpd.leases")
or die ("Error dhcp-dns Service : Unable to copy the /var/lib/dhcpd/dhcpd.leases");
#we want to write in log
sub log2messages
{
my $message = shift;
tie *FH, 'esmith::Logger';
print FH "$message";
close FH;
}
#Text::DHCPparse forked because it doesn't allow to retrieve the end of lease
#Only the start is found by the leaseparse of DHCPparse.pm s/starts/ends
sub leaseparse
{
my $logfile = shift;
my ( %list, $ip );
open FILE, $logfile or die;
while (<FILE>)
{
next if /^#|^$/;
if (/^lease (\d+\.\d+\.\d+\.\d+)/)
{
$ip = $1;
$list{$ip} = sprintf("%-17s", $ip);
}
/^\s*hardware ethernet (.*);/ && ($list{$ip} .= sprintf("%-19s", $1));
/^\s*ends \d (.*);/ && ($list{$ip} .= sprintf("%-21s", $1));
/^\s*(abandoned).*/ && ($list{$ip} .= sprintf("%-19s", $1));
/^\s*client-hostname "(.*)";/ && ($list{$ip} .= sprintf("%-17s", $1));
}
close FILE;
# make all entries 74 characters long to format properly
foreach (keys %list)
{
$list{$_} = sprintf("%-74s", $list{$_}) if (length$list{$_} < 76);
}
return \%list;
}
#hostname validator routine
sub namevalidator
{
my $local_domain = $DB->get_value('DomainName') or die ("Unable retrieve the DomainName property");
my $server_name = $DB->get_value('SystemName') or die ("Unable retrieve the SystemName property");
my $validator = shift;
if ($validator eq $server_name) {
log2messages("The hostname of this server ($server_name) is already in use with a different IP address in /var/lib/dhcpd/dhcpd.leases");
return 1;
}
elsif ($validator !~ /^[a-zA-Z0-9][a-zA-Z0-9-]*$/) {
log2messages("The hostname of the dhcp client ($validator) contains illegal characters in /var/lib/dhcpd/dhcpd.leases");
return 1;
}
elsif (exists $hostsdb{lc "$validator\.$local_domain"}) {
log2messages("The hostname of the dhcp client ($validator) is already used in the hosts database");
return 1;
}
elsif (exists $allocated_name{$validator}) {
log2messages("The hostname ($validator) has already been assigned an IP address in /var/lib/dhcpd/dhcpd.leases");
return 1;
}
else {
return 0;
}
}
# now we parse the leases
my $return = leaseparse('/tmp/tmpdhcpd.leases');
my ($ip,$time,$mac,$name);
# retrieve the local domain name
my $localdomain = $DB->get_value('DomainName') or die ("Unable retrieve the DomainName property");
$OUT .= "# A records for dhcp hosts in $localdomain\n";
foreach (keys %$return)
{
($ip, $time, $mac, $name) = unpack("A17 A21 A19 A30", $return->{$_});
# we skip allocated ips & empty names
unless ((exists $allocated_ip_dhcplease{$ip}) || ( $name eq "" ))
{
# Convert lease end time to the format expected as
# see: http://cr.yp.to/djbdns/tinydns-data.html
my $ts = UnixDate($time, "%s");
my $endtai = unixtai64($ts);
$endtai =~ s/@//;
#we don't want finished lease
next if ($ts < time);
# Determine TTL
my $ttl = 0;
# display if the hostname is valid
$OUT .= "=$name.$localdomain:$ip:$ttl:$endtai\n" if (namevalidator("$name") ne '1');
}
$allocated_ip_dhcplease{$ip} = 1;
$allocated_name{$name} ++;
}
# remove the temp file
unlink "/tmp/tmpdhcpd.leases"
or log2messages("Error dhcp-dns Service : Unable to remove the /tmp/tmpdhcpd.leases");
}