#!/usr/bin/perl -wU #---------------------------------------------------------------------- # heading : Configuration # description : DHCP manager # navigation : 2000 2500 # # Copyright (c) 2003 Thierry Quaak thierry@quaak.net # 2014 Stephane de Labrusse stephdl@de-labrusse.fr #---------------------------------------------------------------------- my $fm = esmith::FormMagick->new(); $fm->parse_xml(); ###Call Modules use strict; use CGI ':all'; use CGI::Carp qw(fatalsToBrowser); use esmith::cgi; use esmith::util; use esmith::templates; use esmith::ConfigDB; use esmith::AccountsDB; use esmith::FormMagick; use Net::Ping; use esmith::util::network qw(:all); use Socket qw( inet_aton ); ###Declare function prototypes sub Main_Display ($$); sub Load_leases ($); sub Main_Save ($); sub Del_Lease ($); sub Perform_Del_Lease ($); sub Wake_Up ($); sub Perform_Wake_Up ($); sub Message ($$); sub Global_WinPopup ($); sub Perform_Message ($); sub Table_IP ($$); sub Scan_Local_Network ($); sub Del_all_Lease ($); sub Perform_del_all_Lease ($); sub Save_checkip ($); ### Clear PATH and related environment variables so that calls to ### external programs do not cause results to be tainted. See ### "perlsec" manual page for details. BEGIN { $ENV {'PATH'} = ''; $ENV {'SHELL'} = '/bin/bash'; delete $ENV {'ENV'}; } ###Define package global to SME configuration paramters using "old" method. ###We are using this method, over esmith::ConfigDB, to satisfy syntax in ###esmith::cgi our %conf = (); tie %conf, 'esmith::config'; our @liste_computer ; our @liste_connected ; ###Change UID -- not sure what we are doing this, but all panels seem to ###call this function. esmith::util::setRealToEffective (); our %status = ('enabled' => $fm->localise('ENABLED'), 'disabled' => $fm->localise('DISABLED') ); our %check = ('enabled' => $fm->localise('ENABLED'), 'disabled' => $fm->localise('DISABLED') ); ###Restrict uploads to form submittals only $CGI::POST_MAX=1024 * 100; # max 100K posts $CGI::DISABLE_UPLOADS = 1; # no uploads ###Examine state parameter and display the appropriate form my $q = new CGI; if (! grep (/^state$/, $q->param)){ Main_Display($q, '');} elsif ($q->param ('state') eq "main_display"){Main_Display ($q,'');} elsif ($q->param ('state') eq $fm->localise('REFRESH')){Table_IP ($q, '');} elsif ($q->param ('state') eq "main_save"){Main_Save ($q);} elsif ($q->param ('state') eq "del_lease"){Del_Lease ($q);} elsif ($q->param ('state') eq "perform_del_lease"){Perform_Del_Lease ($q);} elsif ($q->param ('state') eq "wake_up"){Wake_Up ($q);} elsif ($q->param ('state') eq "perform_wake_up"){Perform_Wake_Up ($q);} elsif ($q->param ('state') eq $fm->localise('GLOBAL_WINPOPUP')){Global_WinPopup ($q);} elsif ($q->param ('state') eq "message"){Message ($q,'');} elsif ($q->param ('state') eq "perform_message"){Perform_Message ($q);} elsif ($q->param ('state') eq $fm->localise('CONNECTED_IP')){Table_IP ($q,'');} elsif ($q->param ('state') eq $fm->localise('SCAN_YOUR_NETWORK')){Scan_Local_Network ($q);} elsif ($q->param ('state') eq $fm->localise('REMOVE_ALL_LEASES')){Del_all_Lease ($q);} elsif ($q->param ('state') eq $fm->localise('REMOVE_ALL_LEASES_ACTION')){Perform_del_all_Lease ($q);} elsif ($q->param ('state') eq 'Save_checkIP'){Save_checkip ($q);} else{esmith::cgi::genStateError ($q, \%conf);} exit (0); #=============================================================================== #SUBROUTINE TO SHOW MAIN PANEL #=============================================================================== sub Main_Display ($$){ ###Pull cgi object from parameters array my $q = shift; my @computer; my $status ; ###Pull action message, if any, from parameters array my $action_message = shift; ###Retrieve SME configuration entry for dhcpd my $dbh_sme = esmith::ConfigDB->open('/home/e-smith/db/configuration'); my %sme_conf = $dbh_sme->get('dhcpd')->props; ###Display Main Panel Title esmith::cgi::genHeaderNonCacheable ($q, \%conf, $fm->localise('DHCPD_TITLE')); ###Check to see if we just processed a panel action. If so, display ###action message and bail. if ($action_message) { print $q->h3 ($fm->localise('STATUS_REPORT') . " $action_message"); } #------------------------------------------------------------ # Start DHCP client Panel #------------------------------------------------------------ print $q->p (''); print $q->startform (-method => 'POST', -action => $q->url (-absolute => 1)); print $q->Tr (esmith::cgi::genButtonRow ($q,$q->submit (-name => 'state',-value => $fm->localise('CONNECTED_IP')))); print $q->Tr (esmith::cgi::genButtonRow ($q,$q->submit (-name => 'state',-value => $fm->localise('SCAN_YOUR_NETWORK')))); print $q->Tr (esmith::cgi::genButtonRow ($q,$q->submit (-name => 'state',-value => $fm->localise('GLOBAL_WINPOPUP')))); print $q->hidden (-name => 'liste_connected', -override => 1, -default => "@liste_connected"); #------------------------------------------------------------ # Start DHCP daemon Panel #------------------------------------------------------------ print $q->hr; print $q->h3 ($fm->localise('DHCPD_SETTINGS_TITLE')); if (! $sme_conf{'winscustom'} ) { $sme_conf{'winscustom'} = 'disabled' ; } if (! $sme_conf{'dnscustom'} ) { $sme_conf{'dnscustom'} = 'disabled' ; } if ( ! $sme_conf{'leasetime'} ) { $sme_conf{'leasetime'} = "86400" ; } if (! $sme_conf{'gatewaycustom'} ) { $sme_conf{'gatewaycustom'} = 'disabled' ; } #check the status (up or down) of dhcp client print $q->table ({border => 0, cellspacing => 0, cellpadding => 4}, esmith::cgi::genWidgetRow ($q, $fm->localise('CHECK_CLIENT_STATUS'), $q->popup_menu (-name => 'dhcp_check', -values => ['disabled', 'enabled'], -default => $sme_conf{'check'}, -labels => \%check)) ); # - modofication des plage DHCP print $q->table ({border => 0, cellspacing => 0, cellpadding => 4}, esmith::cgi::genWidgetRow ($q, $fm->localise('STATUS_DHCP_SERVER'), $q->popup_menu (-name => 'dhcp_enable', -values => ['enabled', 'disabled'], -default => $sme_conf{'status'}, -labels => \%status)) , esmith::cgi::genNameValueRow ($q, $fm->localise('DHCP_START'), 'dhcp_start', $sme_conf{'start'}) , esmith::cgi::genNameValueRow ($q, $fm->localise('DHCP_END') , 'dhcp_end', $sme_conf{'end'}), esmith::cgi::genTextRow ($q, $q->p ($fm->localise('CUSTOM_WINSERVER_TITLE'))), esmith::cgi::genWidgetRow ($q, $fm->localise('CUSTOM_WINSERVER_STATUS'), $q->popup_menu (-name => 'dhcp_winscustom', -values => ['enabled', 'disabled'], -default => $sme_conf{'winscustom'}, -labels => \%status)), esmith::cgi::genNameValueRow ($q, $fm->localise('CUSTOM_WINSERVER_ADDRESS'), 'dhcp_winsserver', $dbh_sme->get_prop('smb','WINSServer')), #### Custom DNS esmith::cgi::genTextRow ($q, $q->p ($fm->localise('CUSTOM_DNS_TITLE'))), esmith::cgi::genWidgetRow ($q, $fm->localise('CUSTOM_DNS_STATUS'), $q->popup_menu (-name => 'dhcp_dnscustom', -values => ['enabled', 'disabled'], -default => $sme_conf{'dnscustom'}, -labels => \%status)), esmith::cgi::genNameValueRow ($q, $fm->localise('PRIMARY_DNS_ADDRESS'), 'dhcp_dns1server', $sme_conf{'dns1server'}), esmith::cgi::genNameValueRow ($q, $fm->localise('SECONDARY_DNS_ADDRESS'), 'dhcp_dns2server', $sme_conf{'dns2server'}), esmith::cgi::genNameValueRow ($q, $fm->localise('TERTIARY_DNS_ADDRESS'), 'dhcp_dns3server', $sme_conf{'dns3server'}), #### Custom default Gateway esmith::cgi::genTextRow ($q, $q->p ($fm->localise('CUSTOM_GATEWAY_TITLE'))), esmith::cgi::genWidgetRow ($q, $fm->localise('CUSTOM_GATEWAY_STATUS'), $q->popup_menu (-name => 'dhcp_gatewaycustom', -values => ['enabled', 'disabled'], -default => $sme_conf{'gatewaycustom'}, -labels => \%status)), esmith::cgi::genNameValueRow ($q, $fm->localise('CUSTOM_GATEWAY_ADDRESS'), 'dhcp_gateway', $sme_conf{'gateway'}), #dhcp LEASE SET UP esmith::cgi::genTextRow ($q, $q->p ($fm->localise('CUSTOM_LEASETIME_TITLE'))), esmith::cgi::genNameValueRow ($q, $fm->localise('CUSTOM_LEASETIME'), 'dhcp_leasetime', $sme_conf{'leasetime'}) ); print ''; print $q->start_table ({width => "100%", -class => "sme-noborders"}), "\n"; print esmith::cgi::genButtonRow ($q, $q->submit (-name => 'action', -value => $fm->localise('SAVE/RESTART'))); print $q->end_table,"\n"; print $q->hidden ( -name => 'state', -override => 1, -default => 'main_save' ),"\n"; print $q->endform; esmith::cgi::genFooter ($q); } # #=============================================================================== #SUBROUTINE: Process Save From Main Panel #=============================================================================== sub Main_Save ($){ ##Pull CGI object from parameters array my $q = shift; ###Build Hash of config parameters to update from cgi submit my $dhcpd_status = $q->param ('dhcp_enable'); my $dhcpd_winscustom = $q->param ('dhcp_winscustom'); my $dhcpd_check = $q->param ('dhcp_check'); my $dhcpd_start = $q->param ('dhcp_start'); my $dhcpd_end = $q->param ('dhcp_end'); my $dhcpd_winsserver = $q->param ('dhcp_winsserver'); my $dhcpd_leasetime = $q->param ('dhcp_leasetime'); my $dhcpd_dnscustom = $q->param ('dhcp_dnscustom'); my $dhcpd_dns1server = $q->param ('dhcp_dns1server'); my $dhcpd_dns2server = $q->param ('dhcp_dns2server'); my $dhcpd_dns3server = $q->param ('dhcp_dns3server'); my $dhcpd_gatewaycustom = $q->param ('dhcp_gatewaycustom'); my $dhcpd_gateway = $q->param ('dhcp_gateway'); ###Update SME configuration dbase my $dbh_sme = esmith::ConfigDB->open('/home/e-smith/db/configuration'); ##Initiate get method --> create record object my $sme_record = $dbh_sme->get('dhcpd'); #get localip of server my $local_ip = $dbh_sme->get_value('LocalIP'); ##Set status of service $sme_record->set_prop('status', $dhcpd_status); $sme_record->set_prop('check' , $dhcpd_check); $sme_record->set_prop('winscustom', $dhcpd_winscustom); $sme_record->set_prop('leasetime' , $dhcpd_leasetime); $sme_record->set_prop('dnscustom' , $dhcpd_dnscustom); $sme_record->set_prop('gatewaycustom' , $dhcpd_gatewaycustom); #checkip to the dhcpserver, perform the save in DB configuration or display an error if value != of a valid ip or if dhcp_start is greater than dhcp_end if ($dhcpd_status eq "enabled") { if ( isValidIP ($dhcpd_start) && isValidIP ($dhcpd_end)) { #check if $dhcpd_start is greater than $dhcpd_end and if yes, display an error message. if (inet_aton($dhcpd_start) ge inet_aton($dhcpd_end)) { Main_Display($q, $fm->localise('DHCP_START_GREATER_DHCP_END_ERRORS') . ' (' . $dhcpd_start . '/' . $dhcpd_end .')'); } elsif ( ( (inet_aton($dhcpd_start) le inet_aton($local_ip) ) && ( inet_aton($dhcpd_end)) ge inet_aton($local_ip) ) ) { #display an error if the range of dhcp server include the ip of the server address Main_Display($q, $fm->localise('DHCP_RANGE_MUST_NOT_INCLUDE_SERVER_IP') . ' (' . $local_ip . ')'); } else { #set value my $dhcpd_start = cleanIP($dhcpd_start); my $dhcpd_end = cleanIP($dhcpd_end); $sme_record->set_prop('end', $dhcpd_end); $sme_record->set_prop('start', $dhcpd_start); } } #if $dhcpd_start or $dhcpd_end are not valid ip then display an error else { Main_Display($q, $fm->localise('DHCP_RANGE_WITH_BAD_IP') . ' (' . $dhcpd_start . '/' . $dhcpd_end .')'); } } #checkip to the winserver perform the save in DB configuration or display an error if value != of a valid ip if ($dhcpd_winscustom eq "enabled") { if ( isValidIP ($dhcpd_winsserver) ) { #set value my $dhcpd_winsserver = cleanIP($dhcpd_winsserver); $dbh_sme->set_prop('smb','WINSServer', $dhcpd_winsserver); } else { #if $dhcpd_winsserver is not valid ip then display an error Main_Display($q, $fm->localise('WINSSERVER_BAD_IP') . ' (' . $dhcpd_winsserver .')'); } } elsif ($dhcpd_winscustom eq "disabled") { my $delws = $dbh_sme->get('smb'); $delws->delete_prop('WINSServer'); } #checkip to the dnsserver custom, perform the save in DB configuration or display an error if value != of a valid ip if ($dhcpd_dnscustom eq "enabled") { #check if $dhcpd_dns1server and ( $dhcpd_dns2server are valid ip or $dhcpd_dns2server = null ) if ( isValidIP ($dhcpd_dns1server) && (isValidIP($dhcpd_dns2server) || ( $dhcpd_dns2server eq "") ) && (isValidIP($dhcpd_dns3server) || ( $dhcpd_dns3server eq "") ) ) { #set value my $dhcpd_dns1server = cleanIP($dhcpd_dns1server); $sme_record->set_prop('dns1server' , $dhcpd_dns1server); my $dhcpd_dns2server = cleanIP($dhcpd_dns2server); $sme_record->set_prop('dns2server' , $dhcpd_dns2server); my $dhcpd_dns3server = cleanIP($dhcpd_dns3server); $sme_record->set_prop('dns3server' , $dhcpd_dns3server); } else { ##if $dhcpd_dns1server or $dhcpd_dns2server or $dhcpd_dns3server are not valid ip then display an error Main_Display($q, $fm->localise('DNS_SERVER_WITH_BAD_IP') . ' (' . $dhcpd_dns1server . '/' . $dhcpd_dns2server . '/' . $dhcpd_dns3server .')'); } } #checkip to the gateway_custom perform the save in DB configuration or display an error if value != of a valid ip if ($dhcpd_gatewaycustom eq "enabled") { if ( isValidIP ($dhcpd_gateway) ) { #set value my $dhcpd_gateway = cleanIP($dhcpd_gateway); $sme_record->set_prop('gateway' , $dhcpd_gateway); } else { #if $dhcpd_gateway is not valid ip then display an error Main_Display($q, $fm->localise('GATEWAY_BAD_IP') . ' (' . $dhcpd_gateway .')'); } } # - 4 expand templates # changed to new sme standard signal-event system ("/sbin/e-smith/signal-event","workgroup-update") == 0 or die "Error while saving settings: $!"; Main_Display($q, $fm->localise('SUCCESSFULLY_SAVED_SETTINGS') ); exit; } # #=============================================================================== #SUBROUTINE: procedure qui supprime un bail dans le dhcpd.leases #=============================================================================== sub Del_Lease ($){ ###Pull CGI object from parameters array $q = shift; ###Start Panel. esmith::cgi::genHeaderNonCacheable ($q, \%conf, $fm->localise('REMOVE_A_DHCP_LEASE_TITLE')); print $q->h3($fm->localise('REMOVE_A_DHCP_LEASE')); print $q->startform (-method => 'POST', -action => $q->url (-absolute => 1)); my $ip = $q->param ('host'); my $name = $q->param ('name'); print $q->p ($fm->localise('REMOVE_A_DHCP_LEASE_ACTION') . ' (' . $name .'/' . $ip .')'); print $q->p ($q->b ($fm->localise('ARE_YOU_SURE'))); print $q->submit (-name => 'action', -value => $fm->localise('REMOVE')); print $q->hidden (-name => 'host', -override => 1, -default => $ip ); print $q->hidden (-name => 'name', -override => 1, -default => $name ); print $q->hidden (-name => 'state', -override => 1, -default => 'perform_del_lease'); print $q->endform; print $q->p($fm->localise('CLICK_HERE_TO_MAIN_PANEL')); esmith::cgi::genFooter ($q); return; } #=============================================================================== #SUBROUTINE: Perform delete lease #=============================================================================== sub Perform_Del_Lease($){ ###Pull CGI object from parameters array $q = shift; ###Pull entry to delete my $ip = $q->param('host'); my $name = $q->param('name'); my $name_in_file = '/var/lib/dhcpd/dhcpd.leases' ; my $name_tmp_file = '/var/lib/dhcpd/dhcpd.leases.tmp' ; my $name_out_file = '/var/lib/dhcpd/dhcpd.leases~' ; my $del_current = "0" ; open(INFILE,"<$name_in_file") || die "Read Error $name_in_file, Read: $!"; open(OUTFILE,">$name_tmp_file") || die "Write error $name_in_file, Write: $!"; while () { if ( "$_" =~ /lease $ip/ ) { $del_current = "1" ; } if ( $del_current == "0" ) { print OUTFILE "$_" ; } if ( "$_" =~ /}/ ) { $del_current = "0" ; } } rename ($name_tmp_file,$name_in_file) ; system ("/bin/cp","-f","$name_in_file","$name_out_file") ; close(INFILE); close(OUTFILE); # changed to new sme standard signal-event system ("/sbin/e-smith/signal-event","workgroup-update") == 0 or die "Error while saving settings: $!"; ###Return action message Table_IP($q, $fm->localise('SUCCESSFULLY_DELETED_THE_CLIENT') . ' (' . $name . '/' . $ip .')'); exit; } #=============================================================================== #SUBROUTINE: procedure qui valide les parametres de l'host eteint #=============================================================================== sub Wake_Up ($){ ###Pull CGI object from parameters array $q = shift; ###Start Panel. esmith::cgi::genHeaderNonCacheable ($q, \%conf, $fm->localise('WAKING_A_REMOTE_COMPUTER_TITLE')); print $q->h3($fm->localise('WAKING_A_REMOTE_COMPUTER')); print $q->startform (-method => 'POST', -action => $q->url (-absolute => 1)); my $mac = uc($q->param ('MAC')); my $name = uc($q->param ('name')); print $q->p ($q->b ($fm->localise('WAKING_A_REMOTE_COMPUTER_ACTION') . ' (' . $name . '/' . $mac . ')')); print $q->submit (-name => 'action', -value => $fm->localise('WAKE_UP') . " $name"); print $q->hidden (-name => 'mac', -override => 1, -default => $mac ); print $q->hidden (-name => 'name', -override => 1, -default => $name ); print $q->hidden (-name => 'state', -override => 1, -default => 'perform_wake_up'); print $q->endform; print $q->p($fm->localise('CLICK_HERE_TO_MAIN_PANEL')); esmith::cgi::genFooter ($q); return; } #=============================================================================== #SUBROUTINE: Perform wake UP #=============================================================================== sub Perform_Wake_Up($){ ###Pull CGI object from parameters array $q = shift; ###Get Mac Adress my $mac = uc($q->param('mac')); my $name = uc($q->param('name')); #Send Wake Up to the station #Old version obsolete since 1.5.0 - system ("/usr/bin/wol","$mac") ; system ("/sbin/ether-wake","$mac") ; ###Return action message Table_IP($q, $fm->localise('SUCCESSFULLY_CLIENT_WOL_REQUEST') . ' (' . $name . '/' . $mac . ')'); exit; } #========================================================================= # Procedure qui charge le dhcpd.conf # retourne un tableau contenant les informations #========================================================================= sub Load_leases ($){ #Definition de variable use vars qw/ @detail $work_line $header /; my $name_file = '/var/lib/dhcpd/dhcpd.leases' ; @liste_computer = '' ; #Ouverture du fichier en lecture seule open(FILE,"<$name_file") || die "Read error $name_file, Error: $!" ; #Parcours du fichier dhcpd.leases while () { # suppression des commentaires if ($_ =~ /^#/) { next; } #spurresion des lignes vides if ($_ =~ /^$/) { next; } #supression de la ligne uid de windows if ($_ =~ /uid/) { next; } #supression de la ligne tstp de XP if ($_ =~ /tstp/) { next; } #supression de la ligne "binding state active" if ($_ =~ /binding/) { next; } #supression de la ligne "next binding state" if ($_ =~ /next/) { next; } #suprresion des commentaire et des ; $_ =~ s/\s#.*$//; $_ =~ s/(;|{) *$//; #supression des espace en debut de lignes $_ =~ s/^ *\s//; #Suppression des retours chariot en fin de lignes. chomp $_ ; #Chargement d'un tableau avec le contenu de la ligne. (@detail) = split(/ /, $_) ; #initialisation d'un nouveau poste connect� if ($_ =~ /lease/) { $work_line = "" ; } $header = shift(@detail); $work_line = $work_line . ";" . join(" ",@detail) ; if ($header =~ /}/) { $work_line =~ s/ /;/g; $work_line =~ s/^;//; $work_line =~ s/"//g; $work_line =~ s/;$//; #we want the last entry is the first element of the array unshift(@liste_computer,$work_line) ; } } close(FILE); } #=============================================================================== #SUBROUTINE: Message #=============================================================================== sub Message($$){ ###Pull CGI object from parameters array $q = shift; ###Pull entry to delete my $name = $q->param('name'); my @liste_connected = $q->param('liste_connected'); my $message2send ; if ( $name ) { @liste_connected = () ; push(@liste_connected,$name) ; } else {$name = $fm->localise('ALL_OF_THEM')} esmith::cgi::genHeaderNonCacheable ($q, \%conf,$fm->localise('SENDING_A_WINPOPUP')); print $q->h3($fm->localise('SENDING_A_WINPOPUP_TO') . " @liste_connected."); print $q->startform (-method => 'POST', -action => $q->url (-absolute => 1)); print $q->table ({border => 0, cellspacing => 0, cellpadding => 4}, esmith::cgi::genNameValueRow ($q,$fm->localise('YOUR_MESSAGE'), 'message2send', $fm->localise('WRITE_YOUR_MESSAGE')) ); print ''; print $q->hr; print $q->p ($q->p ($fm->localise('DO_YOU_WANT_TO_SENT') . " $name")); print $q->submit (-name => 'action', -value => $fm->localise('SEND_WINPOPUP_TO') . " $name"); print $q->hidden (-name => 'liste_connected', -override => 1, -default => @liste_connected); print $q->hidden (-name => 'message2send', -override => 1, -default => $message2send); print $q->hidden (-name => 'state', -override => 1, -default => 'perform_message'); print $q->endform; print $q->p($fm->localise('CLICK_HERE_TO_MAIN_PANEL')); esmith::cgi::genFooter ($q); return; } #=============================================================================== #SUBROUTINE: Perform message #=============================================================================== sub Perform_Message($){ ###Pull CGI object from parameters array $q = shift; ###Get Mac Adress my @liste_connected = split(' ',$q->param('liste_connected')); my $message2send = $q->param('message2send'); foreach (@liste_connected){ system ("/etc/e-smith/events/actions/send-message","$_","$message2send") ; } Table_IP($q, $fm->localise('SUCCESSFULLY_SENT_MESSAGE') . " @liste_connected." . $fm->localise('WARNING_NO_WINPOPUP_GARANTY')); exit; } #=============================================================================== #SUBROUTINE: Win Popup for all connected hosts #=============================================================================== sub Global_WinPopup($){ my $q = shift; my @liste_connected = $q->param('liste_connected'); Message($q,@liste_connected); exit; } #=============================================================================== #SUBROUTINE: Create Table_IP of dhcp server #=============================================================================== sub Table_IP ($$) { ###Pull cgi object from parameters array my $q = shift; my @computer; my $status ; ###Pull action message, if any, from parameters array my $action_message = shift; ###Retrieve SME configuration entry for dhcpd my $dbh_sme = esmith::ConfigDB->open('/home/e-smith/db/configuration'); my %sme_conf = $dbh_sme->get('dhcpd')->props; ###Display Main Panel Title esmith::cgi::genHeaderNonCacheable ($q, \%conf, $fm->localise('MANAGING_DHCP_CLIENT')); ###Check to see if we just processed a panel action. If so, display ###action message and bail. if ($action_message) { print $q->h3 ($fm->localise('STATUS_REPORT') . " $action_message"); } #------------------------------------------------------------ # Start DHCP client Panel #------------------------------------------------------------ print $q->p (''); print $q->startform (-method => 'POST', -action => $q->url (-absolute => 1)); #refresh the list print esmith::cgi::genButtonRow ($q,$q->submit (-name => 'state',-value => $fm->localise('REFRESH'))); #Remove all dhcpd lease print esmith::cgi::genButtonRow ($q,$q->submit (-name => 'state',-value => $fm->localise('REMOVE_ALL_LEASES'))); print $q->hr; print $q->table ({border => 0, cellspacing => 0, cellpadding => 4}, esmith::cgi::genWidgetRow ($q, $fm->localise('CHECK_CLIENT_STATUS'), $q->popup_menu (-name => 'dhcp_check', -values => ['disabled', 'enabled'], -default => $sme_conf{'check'}, -labels => \%check)) ); ##save checkip ('Saving modification and restart the daemon...') and go to sub Save_checkip :) print $q->table ({border => 0, cellspacing => 0, cellpadding => 4}, esmith::cgi::genTextRow ($q, $q->p ($fm->localise('SAVE_TITLE')))); print $q->start_table ({width => "100%", -class => "sme-noborders"}), "\n"; print esmith::cgi::genButtonRow ($q, $q->submit (-name => 'action', -value => $fm->localise('SAVE/RESTART'))); print $q->end_table,"\n"; print $q->hidden ( -name => 'state', -override => 1, -default => 'Save_checkIP' ),"\n"; print $q->endform; # Refresh Liste print $q->p($fm->localise('CLICK_HERE_TO_MAIN_PANEL')); &Load_leases ($q) ; if ( 2 > 1 ) { print $q->p ($q->b ('')); print $q->table ({border => 1, cellspacing => 1, cellpadding => 4,nowarp => 1}); print $q->Tr (esmith::cgi::genSmallCell ($q, $q->p ( '
' . 'IP')), esmith::cgi::genSmallCell ($q, $q->p ( '
' . $fm->localise('NETWORK_NAME'))), esmith::cgi::genSmallCell ($q, $q->p ( '
' . $fm->localise('STATUS_CLICK_FOR_WOL'))), esmith::cgi::genSmallCell ($q, $q->p ( '
' . $fm->localise('START_DATE'))), esmith::cgi::genSmallCell ($q, $q->p ( '
' . $fm->localise('END_DATE'))), esmith::cgi::genSmallCell ($q, $q->p ( '
' . $fm->localise('MAC_ADDRESS') . '
')), ); ##9(sme8)12(sme9)->netbios (ancien10)::8(sme8)11(sme9)->mac address (ancien8)::0->ip:: ##it is possible you may adapt array number if more options/lines are added to the dhcpd.leases ##symptoms are a blank or wrong line in Table_IP my @mac = (); my @count = (); foreach (@liste_computer){ @computer = split(/;/, $_) ; #we want to sort elements the array by mac address $computer[11] = uc($computer[11]) ; push @mac, ($computer[11]); my @count; push @count , (grep /$computer[11]/ , @mac); next if (scalar @count > 1); #we start the table if it is a valid IP if ( $computer[0] ) { $computer[12] = uc($computer[12]) ; my $datedeb = $computer[2] . "-" . $computer[3] ; my $datefin = $computer[5] . "-" . $computer[6] ; $status = $q->a ({href => $q->url (-absolute => 1) . "?state=wake_up&MAC=" . $computer[11] . "&name=" . $computer[12]}, $fm->localise('NOT_CHECKED')) ; if ( $sme_conf{'check'} =~ /enabled/ ) { use Net::Ping; my($ping_obj) = Net::Ping->new("icmp"); # formatage des dates $computer[3] = substr($computer[3],0,5); $computer[6] = substr($computer[6],0,5); if ($ping_obj->ping("$computer[0]")) { push(@liste_connected,$computer[12]) ; $status = $fm->localise('ACTIVE_DEVICE'); #alimentation de la liste des connect� } else { $status = $q->a ({href => $q->url (-absolute => 1) . "?state=wake_up&MAC=" . $computer[11] . "&name=" . $computer[12]}, $fm->localise('WAKE_UP_ACTION')); } } else { push(@liste_connected,$computer[12]) ; } print $q->Tr (esmith::cgi::genSmallCell ($q, "$computer[0]"), esmith::cgi::genSmallCell ($q, "$computer[12]"), esmith::cgi::genSmallCell ($q, "
" ."$status" ), esmith::cgi::genSmallCell ($q, "
" . "$datedeb" . "
"), esmith::cgi::genSmallCell ($q, "
" . "$datefin" . "
"), esmith::cgi::genSmallCell ($q, "$computer[11]"), esmith::cgi::genSmallCell ($q, $q->a ({href => $q->url (-absolute => 1) . "?state=del_lease&host=" . $computer[0] . "&name=" . $computer[12]}, $fm->localise('REMOVE_ACTION'))), esmith::cgi::genSmallCell ($q, $q->a ({href => $q->url (-absolute => 1) . "?state=message&name=" . $computer[12]}, $fm->localise('WINPOPUP_ACTION'))) ); } } print ''; } else{ print $q->p ($q->b ($fm->localise('NO_CONNECTED_COMPUTERS'))); } print $q->p($fm->localise('CLICK_HERE_TO_MAIN_PANEL')); esmith::cgi::genFooter ($q); exit; } # #=============================================================================== #SUBROUTINE: procedure qui sauve le checkip de la subroutine Table_ip #=============================================================================== sub Save_checkip ($){ ##Pull CGI object from parameters array my $q = shift; ###Build Hash of config parameters to update from cgi submit my $dhcpd_check = $q->param ('dhcp_check'); ##Initiate get method --> create record object my $dbh_sme = esmith::ConfigDB->open('/home/e-smith/db/configuration'); my $sme_record = $dbh_sme->get('dhcpd'); $sme_record->set_prop('check' , $dhcpd_check); system ("/sbin/e-smith/signal-event","workgroup-update") == 0 or die "Error while saving settings: $!"; Table_IP($q, $fm->localise('SUCCESSFULLY_SAVED_SETTINGS')); exit; } # #=============================================================================== #SUBROUTINE: procedure qui supprime tous les bail dans le dhcpd.leases #=============================================================================== sub Del_all_Lease ($){ ###Pull CGI object from parameters array $q = shift; ###Start Panel. esmith::cgi::genHeaderNonCacheable ($q, \%conf, $fm->localise('REMOVE_DHCP_LEASE_TITLE')); print $q->h3($fm->localise('REMOVE_DHCP_LEASE_WARNING')); print $q->startform (-method => 'POST', -action => $q->url (-absolute => 1)); print $q->p ( $fm->localise('REMOVE_DHCP_LEASE_WARNING2')); print $q->p ($q->b ($fm->localise('ARE_YOU_SURE'))); print $q->submit (-name => 'state', -value => $fm->localise('REMOVE_ALL_LEASES_ACTION')); print $q->p($fm->localise('CLICK_HERE_TO_MAIN_PANEL')); print $q->endform; esmith::cgi::genFooter ($q); return; } # #=============================================================================== #SUBROUTINE: supprime tous les bail dans le dhcpd.leases #=============================================================================== sub Perform_del_all_Lease ($){ system ('/bin/echo "" > /var/lib/dhcpd/dhcpd.leases') ==0 or die "Error while removing all leases: $!"; system ("/sbin/e-smith/signal-event","workgroup-update") == 0 or die "Error while saving settings: $!"; Table_IP($q, $fm->localise('SUCCESSFULLY_REMOVED_ALL_LEASES')); exit; } #=============================================================================== #SUBROUTINE: Scan The Local Network #=============================================================================== sub Scan_Local_Network ($) { esmith::cgi::genHeaderNonCacheable ($q, \%conf, $fm->localise('SCANNING_NETWORK_TITLE')); my $nmap_sme = esmith::ConfigDB->open('/home/e-smith/db/configuration'); my $mask = $nmap_sme->get_value('LocalNetmask'); my $network = $nmap_sme->get_prop('InternalInterface','Network'); #we start to calculate the method to find the cidr (we want to use network/cidr with nmap) sub dec2bin { my $str = unpack("B32", pack("N", shift)); return $str; } sub netmask2cidr { my ($mask, $network) = @_; my @octet = split (/\./, $mask); my @bits; my $binmask; my $binoct; my $bitcount=0; foreach (@octet) { $binoct = dec2bin($_); $binmask = $binmask . substr $binoct, -8; } # let's count the 1s @bits = split (//,$binmask); foreach (@bits) { if ($_ eq "1") { $bitcount++; } } my $cidr = $network . "/" . $bitcount; return $cidr; } #Then lets go to calculate the cidr my $cidr = netmask2cidr($mask, $network); #ok go to use nmap with nmap -T4 -sP network/cidr print $q->p ; print $q->h3($fm->localise('NETWORK_VALUES_FOUND') . " $cidr \($mask\)"); print $q->p ; print $q->p($fm->localise('CLICK_HERE_TO_MAIN_PANEL')); foreach (`/usr/bin/nmap --script smb-os-discovery.nse -p U:137,T:139 $cidr| /bin/grep -Ev "MAC|NetBIOS|OS CPE"| /bin/grep -E "scan|done|Computer|OS"| /bin/sed -e 's/Nmap scan/-- Scan/g'|/bin/sed -e 's/done/Done/g'| /bin/sed -e 's/Nmap//g'|/bin/sed -e 's/|/ /g'`) { print $q->br($_);} print $q->p ; print $q->p($fm->localise('CLICK_HERE_TO_MAIN_PANEL')); esmith::cgi::genFooter ($q); exit; } __DATA__