From 06d7b1d253ab05e2a215dbc1863dc14ad5cc3290 Mon Sep 17 00:00:00 2001 From: Daniel Berteaud Date: Thu, 14 Jan 2021 08:31:59 +0100 Subject: [PATCH] Alignment and typo in script name --- samba/audit.pl | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 samba/audit.pl diff --git a/samba/audit.pl b/samba/audit.pl new file mode 100644 index 0000000..ad1e600 --- /dev/null +++ b/samba/audit.pl @@ -0,0 +1,110 @@ +#!/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/(?\w{3})\s(?\d{1,2})\s(?[\d+]{1,2}):(?\d{1,2}):(?\d{1,2})/; +my $re_hostname = qr/\w[\w\-]+/; +my $re_user = qr/\w[\w\-]+/; +my $re_op = qr/connect|disconnect|chdir|open|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 (){ + 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+(?$re_user)\|(?$re_ip)\|(?$re_hostname)\|(?$re_share)\|(?$re_op)\|(?$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)\|(?$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/(?$re_path)\|(?$re_path)$/; + $file = $+{file}; + $new_name = $+{new_name}; + $result->{operations}->{rename}++; + } elsif ($operation =~ m/(dis)?connect/){ + $result->{operations}->{$operation}++; + }else { + m/(?$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}) ge 010); + } + return $res; +}