You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
3.1 KiB
110 lines
3.1 KiB
#!/usr/bin/perl -w
|
|
|
|
use warnings;
|
|
use strict;
|
|
use JSON;
|
|
|
|
my $result = {
|
|
users => {},
|
|
machines => {},
|
|
operations => {
|
|
connect => 0,
|
|
disconnect => 0,
|
|
chdir => 0,
|
|
open_read => 0,
|
|
open_write => 0,
|
|
close => 0,
|
|
rename => 0,
|
|
unlink => 0,
|
|
mkdir => 0,
|
|
rmdir => 0
|
|
},
|
|
files => {},
|
|
status => {
|
|
success => 0,
|
|
failure => 0
|
|
}
|
|
};
|
|
|
|
my $re_date = qr/(?<month>\w{3})\s(?<day>\d{1,2})\s(?<hour>[\d+]{1,2}):(?<minute>\d{1,2}):(?<seconds>\d{1,2})/;
|
|
my $re_hostname = qr/\w[\w\-]+/;
|
|
my $re_user = qr/\w[\w\-]+/;
|
|
my $re_op = qr/connect|disconnect|chdir|open|opendir|close|rename|unlink|mkdir|rmdir/;
|
|
my $re_path = qr{/?(\.|([^\|]/?)*)};
|
|
my $re_ip = qr/(\d{1,3}\.){3}\d{1,3}/;
|
|
my $re_share = qr/\w[\w\-]+/;
|
|
my $re_status = qr/ok|fail\s+[^\|]+/;
|
|
|
|
while (<STDIN>){
|
|
chomp;
|
|
# Jan 13 03:50:42 contis smbd[27251]: pdurant|192.168.137.117|desk-magasin|tools|close
|
|
next unless m/^$re_date\s+$re_hostname\s+smbd\[\d+\]:\s+(?<user>$re_user)\|(?<ip>$re_ip)\|(?<machine>$re_hostname)\|(?<share>$re_share)\|(?<operation>$re_op)\|(?<status>$re_status)\|/;
|
|
my $date = $+{date};
|
|
my $user = $+{user};
|
|
my $ip = $+{ip};
|
|
my $machine = $+{machine};
|
|
my $share = $+{share};
|
|
my $operation = $+{operation};
|
|
my $status = $+{status};
|
|
my $open_mode;
|
|
my $file = '';
|
|
my $new_name;
|
|
if ($operation eq 'open'){
|
|
m/(r|w)\|(?<file>$re_path)$/;
|
|
$open_mode = $1;
|
|
$file = $+{file};
|
|
if ($open_mode eq 'r'){
|
|
$result->{operations}->{open_read}++;
|
|
} else {
|
|
$result->{operations}->{open_write}++;
|
|
}
|
|
} elsif ($operation eq 'rename') {
|
|
m/(?<file>$re_path)\|(?<new_name>$re_path)$/;
|
|
$file = $+{file};
|
|
$new_name = $+{new_name};
|
|
$result->{operations}->{rename}++;
|
|
} elsif ($operation =~ m/(dis)?connect/){
|
|
$result->{operations}->{$operation}++;
|
|
} else {
|
|
m/(?<file>$re_path)$/;
|
|
$file = $+{file};
|
|
$result->{operations}->{$operation}++;
|
|
}
|
|
$result->{machines}->{$machine}++;
|
|
$result->{ip}->{$ip}++;
|
|
# Skip machine account, do not count it as a user action
|
|
$result->{users}->{$user}++ unless ($user =~ m/_$/);
|
|
$result->{files}->{$share . '/' . $file}++ unless ($file =~ m{^/});
|
|
if ($status eq 'ok'){
|
|
$result->{status}->{success}++;
|
|
} else {
|
|
$result->{status}->{failure}++;
|
|
}
|
|
}
|
|
|
|
$result->{distinct} = {
|
|
users => scalar keys %{$result->{users}},
|
|
machines => scalar keys %{$result->{machines}},
|
|
ip => scalar keys %{$result->{ip}},
|
|
files => scalar keys %{$result->{files}},
|
|
};
|
|
|
|
$result->{top10} = {
|
|
users => get_top($result->{users}),
|
|
machines => get_top($result->{machines}),
|
|
ip => get_top($result->{ip}),
|
|
files => get_top($result->{files}),
|
|
operations => get_top($result->{operations})
|
|
};
|
|
|
|
print to_json($result, { pretty => 1});
|
|
|
|
sub get_top {
|
|
my $hash = shift;
|
|
my $res = [];
|
|
foreach my $item (sort { $hash->{$b} <=> $hash->{$a} } keys %{$hash}){
|
|
push @{$res}, $item . " ($hash->{$item})";
|
|
last if (scalar(@{$res}) > 9);
|
|
}
|
|
return $res;
|
|
}
|
|
|