| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- #!/usr/bin/perl
- #
- # Copyright (C) Roman Dmitiriev, rnd@rajven.ru
- #
- use FindBin '$Bin';
- use lib "$Bin/";
- use Data::Dumper;
- use Rstat::config;
- use Rstat::main;
- use Rstat::mysql;
- use Rstat::net_utils;
- use strict;
- use warnings;
- use Getopt::Long;
- use Proc::Daemon;
- use Cwd;
- use Net::Netmask;
- use File::Spec::Functions;
- use File::Copy qw(move);
- use Text::Iconv;
- my $pf = '/var/run/dhcp-log.pid';
- my $log='/var/lib/dhcpd/dhcpd.log';
- my $daemon = Proc::Daemon->new(
- pid_file => $pf,
- work_dir => $HOME_DIR
- );
- # are you running? Returns 0 if not.
- my $pid = $daemon->Status($pf);
- my $daemonize = 1;
- GetOptions(
- 'daemon!' => \$daemonize,
- "help" => \&usage,
- "reload" => \&reload,
- "restart" => \&restart,
- "start" => \&run,
- "status" => \&status,
- "stop" => \&stop
- ) or &usage;
- exit(0);
- sub stop {
- if ($pid) {
- print "Stopping pid $pid...";
- if ($daemon->Kill_Daemon($pf)) {
- print "Successfully stopped.\n";
- } else {
- print "Could not find $pid. Was it running?\n";
- }
- } else {
- print "Not running, nothing to stop.\n";
- }
- }
- sub status {
- if ($pid) {
- print "Running with pid $pid.\n";
- } else {
- print "Not running.\n";
- }
- }
- sub run {
- if (!$pid) {
- print "Starting...";
- if ($daemonize) {
- # when Init happens, everything under it runs in the child process.
- # this is important when dealing with file handles, due to the fact
- # Proc::Daemon shuts down all open file handles when Init happens.
- # Keep this in mind when laying out your program, particularly if
- # you use filehandles.
- $daemon->Init;
- }
- setpriority(0,0,19);
- my $converter = Text::Iconv->new("cp866", "utf8");
- while (1) {
- eval {
- # Create new database handle. If we can't connect, die()
- system('touch "'.$log.'"');
- my $hdb = DBI->connect("dbi:mysql:database=$DBNAME;host=$DBHOST","$DBUSER","$DBPASS");
- if ( !defined $hdb ) { die "Cannot connect to mySQL server: $DBI::errstr\n"; }
- open(DHCP, "tail -n 0 -F $log |") || die "$log not found!";
- while (my $logline = <DHCP>) {
- next unless defined $logline;
- chomp($logline);
- log_info("GET CLIENT REQUEST: $logline");
- my ($type,$ip,$mac,$hostname) = split (/\;/, $logline);
- next if (!$type);
- next if ($type!~/(old|add|del)/i);
- if (time()-$last_refresh_config>=60) { init_option($hdb); }
- my $client_hostname='UNDEFINED';
- if ($hostname and $hostname!~/undef/i) { $client_hostname=$hostname; }
- my $auth_network = $office_networks->match_string($ip);
- if (!$auth_network) {
- log_error("Unknown network in dhcp request! IP: $ip");
- next;
- }
- my $utf_client_hostname = $converter->convert($client_hostname);
- $mac=mac_splitted(isc_mac_simplify($mac));
- log_debug(uc($type).">>");
- log_debug("MAC: ".$mac);
- log_debug("IP: ".$ip);
- log_debug("HOSTNAME: ".$client_hostname);
- log_debug("UTF8 HOSTNAME: ".$utf_client_hostname);
- log_debug("END GET");
- my $ip_aton=StrToIp($ip);
- $mac=mac_splitted($mac);
- if ($type eq 'add') {
- log_info("Check for new auth...");
- resurrection_auth($hdb,$ip,$mac,$type);
- }
- my $auth_record = get_custom_record($hdb,'SELECT * FROM User_auth WHERE ip="'.$ip.'" and mac="'.$mac.'" and deleted=0 ORDER BY last_found DESC');
- my $auth_id = $auth_record->{id};
- my $ad_zone = get_option($hdb,33);
- my $ad_dns = get_option($hdb,3);
- $update_hostname_from_dhcp = get_option($hdb,46) || 0;
- my $subnets_dhcp = get_subnets_ref($hdb);
- my $enable_ad_dns_update = ($ad_zone and $ad_dns and $update_hostname_from_dhcp);
- log_debug("Subnet: $auth_network");
- log_debug("DNS update flags - zone: $ad_zone dns: $ad_dns config: $update_hostname_from_dhcp subnet: $subnets_dhcp->{$auth_network}->{dhcp_update_hostname}");
- my $maybe_update_dns=(($type=~/add/i or $type=~/old/i) and $utf_client_hostname and $utf_client_hostname !~/UNDEFINED/i and $enable_ad_dns_update and $subnets_dhcp->{$auth_network}->{dhcp_update_hostname});
- if ($maybe_update_dns) {
- log_debug("DNS update enabled.");
- #update dns block
- my $fqdn_static;
- if ($auth_record->{dns_name}) {
- $fqdn_static=lc($auth_record->{dns_name});
- if ($fqdn_static!~/$ad_zone$/i) {
- $fqdn_static=~s/\.$//;
- $fqdn_static=lc($fqdn_static.'.'.$ad_zone);
- }
- }
- my $fqdn=lc(trim($utf_client_hostname));
- if ($fqdn!~/$ad_zone$/i) {
- $fqdn=~s/\.$//;
- $fqdn=lc($fqdn.'.'.$ad_zone);
- }
- db_log_debug($hdb,"FOUND Auth_id: $auth_id dns_name: $fqdn_static dhcp_hostname: $fqdn");
- #check exists static dns name
- my $static_exists = 0;
- my $dynamic_exists = 0;
- my $static_ok = 0;
- my $dynamic_ok = 0;
- my $static_ref;
- my $dynamic_ref;
- if ($fqdn_static ne '') {
- my @dns_record=ResolveNames($fqdn_static);
- $static_exists = (scalar @dns_record>0);
- if ($static_exists) {
- $static_ref = join(' ',@dns_record);
- foreach my $dns_a (@dns_record) {
- if ($dns_a=~/^$ip$/) { $static_ok = $dns_a; }
- }
- }
- } else { $static_ok = 1; }
- if ($fqdn ne '') {
- my @dns_record=ResolveNames($fqdn);
- $dynamic_exists = (scalar @dns_record>0);
- if ($dynamic_exists) {
- $dynamic_ref = join(' ',@dns_record);
- foreach my $dns_a (@dns_record) {
- if ($dns_a=~/^$ip$/) { $dynamic_ok = $dns_a; }
- }
- }
- }
- if ($fqdn_static ne '') {
- if (!$static_ok) {
- db_log_info($hdb,"Static record mismatch! Expected $fqdn_static => $ip, recivied: $static_ref");
- if (!$static_exists) {
- db_log_info($hdb,"Static dns hostname defined but not found. Create it ($fqdn_static => $ip)!");
- update_ad_hostname($fqdn_static,$ip,$ad_zone,$ad_dns);
- }
- } else { db_log_debug($hdb,"Static record for $fqdn_static [$static_ok] correct."); }
- }
- if ($fqdn ne '' and $dynamic_ok ne '') { db_log_debug($hdb,"Dynamic record for $fqdn [$dynamic_ok] correct. No changes required."); }
- if ($fqdn ne '' and !$dynamic_ok) {
- #log only to file!!!
- log_error($hdb,"Dynamic record mismatch! Expected: $fqdn => $ip, recivied: $dynamic_ref. Checking the status.");
- #check exists hostname
- my $another_hostname_exists = 0;
- my $hostname_filter = ' LOWER(dns_name)="'.lc($utf_client_hostname).'"';
- if ($fqdn_static ne '' and $fqdn !~/$fqdn_static/) { $hostname_filter = $hostname_filter . ' or LOWER(dns_name)="'.lc($auth_record->{dns_name}).'"'; }
- #check exists another records with some static hostname
- my $name_record = get_custom_record($hdb,'SELECT * FROM User_auth WHERE id<>'.$auth_id.' and deleted=0 and ('.$hostname_filter.') ORDER BY last_found DESC');
- if ($name_record->{id}) { $another_hostname_exists = 1; }
- if (!$another_hostname_exists) {
- if ($fqdn_static and $fqdn_static ne '') {
- if ($fqdn_static!~/$fqdn/) {
- db_log_info($hdb,"Hostname from dhcp request $fqdn differs from static dns hostanme $fqdn_static. Ignore dynamic binding!");
- # update_ad_hostname($fqdn,$ip,$ad_zone,$ad_dns);
- }
- } else {
- db_log_info($hdb,"Static dns hostname not defined. Create dns record by dhcp request. $fqdn => $ip");
- update_ad_hostname($fqdn,$ip,$ad_zone,$ad_dns);
- }
- } else {
- db_log_error($hdb,"Found another record with some hostname id: $name_record->{id} ip: $name_record->{ip} hostname: $name_record->{dns_hostname}. Skip update.");
- }
- }
- #end update dns block
- } else {
- db_log_debug($hdb,"FOUND Auth_id: $auth_id");
- }
- if ($type=~/add/i and $utf_client_hostname and $utf_client_hostname !~/UNDEFINED/i) {
- my $auth_rec;
- $auth_rec->{dhcp_hostname} = $utf_client_hostname;
- update_record($hdb,'User_auth',$auth_rec,"id=$auth_id");
- }
- if ($hotspot_networks->match_string($ip) and $ignore_hotspot_dhcp_log) { next; }
- if ($ignore_update_dhcp_event and $type=~/old/i) { next; }
- if ($type=~/(old|del)/i) {
- my $auth_rec;
- $auth_rec->{dhcp_action}=$type;
- $auth_rec->{dhcp_time}=GetNowTime();
- update_record($hdb,'User_auth',$auth_rec,"id=$auth_id");
- }
- my $dhcp_log;
- $dhcp_log->{auth_id} = $auth_id;
- $dhcp_log->{ip} = $ip;
- $dhcp_log->{ip_int} = $ip_aton;
- $dhcp_log->{mac} = $mac;
- $dhcp_log->{action} = $type;
- insert_record($hdb,'dhcp_log',$dhcp_log);
- }
- close DHCP;
- };
- if ($@) { log_error("Exception found: $@"); }
- }
- } else {
- print "Already Running with pid $pid\n";
- }
- }
- sub usage {
- print "usage: dhcp-log.pl (start|stop|status|restart)\n";
- exit(0);
- }
- sub reload {
- print "reload process not implemented.\n";
- }
- sub restart {
- stop;
- run;
- }
|