commit
7789ca862a
13 changed files with 413 additions and 0 deletions
@ -0,0 +1,15 @@ |
|||||||
|
#!/usr/bin/perl -w |
||||||
|
|
||||||
|
use esmith::Build::CreateLinks qw(:all); |
||||||
|
|
||||||
|
foreach my $event (qw/bootstrap-console-save workgroup-update/){ |
||||||
|
templates2events("/etc/e-smith/sql/init/sambadblogd", $event); |
||||||
|
} |
||||||
|
safe_symlink("restart", "root/etc/e-smith/events/workgroup-update/services2adjust/squid-db-logd"); |
||||||
|
safe_touch('root/var/service/samba-db-logd/down'); |
||||||
|
safe_symlink("../daemontools" , 'root/etc/rc.d/init.d/supervise/samba-db-logd'); |
||||||
|
safe_symlink("/var/service/samba-db-logd" , 'root/service/samba-db-logd'); |
||||||
|
service_link_enhanced("samba-db-logd", "S98", "7"); |
||||||
|
service_link_enhanced("samba-db-logd", "K15", "6"); |
||||||
|
service_link_enhanced("samba-db-logd", "K35", "0"); |
||||||
|
service_link_enhanced("samba-db-logd", "K35", "1"); |
@ -0,0 +1,53 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
DB_HOST=$(/sbin/e-smith/db configuration getprop samba-db-logd DbHost || echo localhost) |
||||||
|
RETENTION=$(/sbin/e-smith/db configuration getprop samba-db-logd Retention || echo 365) |
||||||
|
|
||||||
|
SQL_DB=$(/sbin/e-smith/db configuration getprop samba-db-logd DbName) |
||||||
|
TABNAME="audit" |
||||||
|
SQLCMD="mysql ${SQL_DB} --batch"; |
||||||
|
MONTH=$(date +%m) |
||||||
|
YEAR=$(date +%Y) |
||||||
|
|
||||||
|
# We rotate on the first day of a new month |
||||||
|
if [ "$MONTH" == "1" ]; then |
||||||
|
MONTH=12 |
||||||
|
else |
||||||
|
MONTH=$(($MONTH-1)) |
||||||
|
fi |
||||||
|
|
||||||
|
# Pad with 0 |
||||||
|
MONTH=$(printf "%02d" $MONTH) |
||||||
|
|
||||||
|
DATE=$MONTH"_"$YEAR |
||||||
|
|
||||||
|
for T in ${TABNAME}; do |
||||||
|
# create table 0 |
||||||
|
echo "CREATE TABLE IF NOT EXISTS ${T}_0 LIKE ${T};" | $SQLCMD; |
||||||
|
|
||||||
|
# Rotate table |
||||||
|
echo "FLUSH TABLES ${T}; RENAME TABLE ${T} TO ${T}_$DATE; RENAME TABLE ${T}_0 TO ${T}" | ${SQLCMD} >/dev/null 2>&1 |
||||||
|
|
||||||
|
# Drop _0 table if we rotate more than two times a month |
||||||
|
if echo "DESCRIBE ${T}_0;" | ${SQLCMD} >/dev/null 2>&1; then |
||||||
|
echo "DROP TABLE ${T}_0;" | $SQLCMD |
||||||
|
fi |
||||||
|
|
||||||
|
#compress 2 |
||||||
|
cd /var/lib/mysql/${SQL_DB}/ |
||||||
|
echo "FLUSH TABLE ${T}_${DATE};" | $SQLCMD |
||||||
|
myisampack -s "${T}_${DATE}.MYI" |
||||||
|
myisamchk -s -rq --sort-index --analyze "${T}_${DATE}.MYI" |
||||||
|
echo "FLUSH TABLE ${T}_${DATE}" | $SQLCMD |
||||||
|
done |
||||||
|
|
||||||
|
# Now check existing table to drop olds ones |
||||||
|
for T in $(echo "show tables" | $SQLCMD | grep -v -P "^Tables_in_"$SQL_DB | grep -v -P "^audit$"); do |
||||||
|
TMONTH=$(echo $T | perl -pe 'm/^audit_(\d+)_(\d+)/; print $2;exit') |
||||||
|
TYEAR=$(echo $T | perl -pe 'm/^audit_(\d+)_(\d+)/; print $3;exit') |
||||||
|
# Drop table if older than configured retention |
||||||
|
if [ "$(($(date -d "01/$MONTH/$YEAR" +%s)-$(date -d "01/$TMONTH/$TYEAR" +%s)))" -gt "$((24*3600*$RETENTION))" ]; then |
||||||
|
echo "DROP TABLE $T;" | $SQLCMD |
||||||
|
fi |
||||||
|
done |
||||||
|
|
@ -0,0 +1 @@ |
|||||||
|
samba_log |
@ -0,0 +1 @@ |
|||||||
|
samba |
@ -0,0 +1 @@ |
|||||||
|
enabled |
@ -0,0 +1 @@ |
|||||||
|
service |
@ -0,0 +1,27 @@ |
|||||||
|
{ |
||||||
|
my $rec = $DB->get('samba-db-logd') |
||||||
|
|| $DB->new_record('samba-db-logd', {type => 'service'}); |
||||||
|
my $pw = $rec->prop('DbPassword'); |
||||||
|
if (not $pw or length($pw) < 57){ |
||||||
|
use MIME::Base64 qw(encode_base64); |
||||||
|
|
||||||
|
$pw = "not set due to error"; |
||||||
|
if ( open( RANDOM, "/dev/urandom" ) ){ |
||||||
|
my $buf; |
||||||
|
# 57 bytes is a full line of Base64 coding, and contains |
||||||
|
# 456 bits of randomness - given a perfectly random /dev/random |
||||||
|
if ( read( RANDOM, $buf, 57 ) != 57 ){ |
||||||
|
warn("Short read from /dev/random: $!"); |
||||||
|
} |
||||||
|
else{ |
||||||
|
$pw = encode_base64($buf); |
||||||
|
chomp $pw; |
||||||
|
} |
||||||
|
close RANDOM; |
||||||
|
} |
||||||
|
else{ |
||||||
|
warn "Could not open /dev/urandom: $!"; |
||||||
|
} |
||||||
|
$rec->set_prop('DbPassword', $pw); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
{ |
||||||
|
my $db = ${'samba-db-logd'}{'DbName'} || 'samba_log'; |
||||||
|
my $user = ${'qpsmtpd'}{'DbUser'} || 'samba'; |
||||||
|
my $pass = ${'qpsmtpd'}{'DbPassword'} || 'samba'; |
||||||
|
|
||||||
|
my $dbstruct = `rpm -qd smeserver-samba-db-logd | grep samba_log.sql`; |
||||||
|
|
||||||
|
$OUT .= <<"END"; |
||||||
|
#! /bin/sh |
||||||
|
if [ ! -d /var/lib/mysql/$db ]; then |
||||||
|
/usr/bin/mysql -e 'create database $db' |
||||||
|
/usr/bin/mysql $db < $dbstruct |
||||||
|
fi |
||||||
|
|
||||||
|
/usr/bin/mysql <<EOF |
||||||
|
USE mysql; |
||||||
|
|
||||||
|
REPLACE INTO user ( |
||||||
|
host, |
||||||
|
user, |
||||||
|
password) |
||||||
|
VALUES ( |
||||||
|
'localhost', |
||||||
|
'$user', |
||||||
|
PASSWORD ('$pass')); |
||||||
|
|
||||||
|
|
||||||
|
REPLACE INTO db ( |
||||||
|
host, |
||||||
|
db, |
||||||
|
user, |
||||||
|
select_priv, insert_priv, update_priv, delete_priv, |
||||||
|
create_priv, alter_priv, index_priv, drop_priv, create_tmp_table_priv, |
||||||
|
grant_priv, lock_tables_priv, references_priv) |
||||||
|
VALUES ( |
||||||
|
'localhost', |
||||||
|
'$db', |
||||||
|
'$user', |
||||||
|
'Y', 'Y', 'Y', 'Y', |
||||||
|
'Y', 'Y', 'Y', 'Y', 'Y', |
||||||
|
'N', 'Y', 'Y'); |
||||||
|
|
||||||
|
FLUSH PRIVILEGES; |
||||||
|
EOF |
||||||
|
END |
||||||
|
} |
@ -0,0 +1,163 @@ |
|||||||
|
#!/usr/bin/perl -w |
||||||
|
|
||||||
|
use File::Tail; |
||||||
|
use DBI; |
||||||
|
use URI; |
||||||
|
use Getopt::Long; |
||||||
|
use strict; |
||||||
|
|
||||||
|
our %opts = (); |
||||||
|
|
||||||
|
# Set default options |
||||||
|
$opts{log} = '/var/log/smb_audit.log'; |
||||||
|
$opts{debug} = 0; |
||||||
|
$opts{dbhost} = 'localhost'; |
||||||
|
$opts{dbname} = 'samba_log'; |
||||||
|
$opts{dbuser} = 'samba'; |
||||||
|
$opts{dbpass} = 'samba'; |
||||||
|
|
||||||
|
# get command line arguments |
||||||
|
GetOptions( |
||||||
|
"debug=i" => \$opts{debug}, |
||||||
|
"log=s" => \$opts{squidlog}, |
||||||
|
"dbhost=s" => \$opts{dbhost}, |
||||||
|
"dbname=s" => \$opts{dbname}, |
||||||
|
"dbpass=s" => \$opts{dbpass} |
||||||
|
); |
||||||
|
|
||||||
|
# Disable output buffering |
||||||
|
select(STDOUT); |
||||||
|
$| = 1; |
||||||
|
select(STDERR); |
||||||
|
$| = 1; |
||||||
|
|
||||||
|
open STDERR, '>&STDOUT'; |
||||||
|
|
||||||
|
# Set process name |
||||||
|
$0 = 'samba-db-logd'; |
||||||
|
|
||||||
|
# Get hostname |
||||||
|
our $host = `hostname`; |
||||||
|
chomp($host); |
||||||
|
|
||||||
|
### Subroutines |
||||||
|
|
||||||
|
# Print messages on stderr |
||||||
|
# for debuging purpose |
||||||
|
sub printlog { |
||||||
|
my $msg = shift; |
||||||
|
print "$msg\n"; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# Connect to the database |
||||||
|
sub db_connect { |
||||||
|
my $dbh = DBI->connect("DBI:mysql:database=$opts{dbname};host=$opts{dbhost}", |
||||||
|
$opts{dbuser}, $opts{dbpass}, {RaiseError => 1}); |
||||||
|
die "Couldn't connect to database\n" unless ($dbh); |
||||||
|
return $dbh; |
||||||
|
} |
||||||
|
|
||||||
|
# escape chars for MySQL queries |
||||||
|
sub mysql_escape { |
||||||
|
my $string = shift; |
||||||
|
$string =~ s|'|\\'|g; |
||||||
|
return $string; |
||||||
|
} |
||||||
|
|
||||||
|
my $dbh = db_connect; |
||||||
|
# Open log file |
||||||
|
|
||||||
|
printlog("opening log file") if ($opts{debug} ge 1); |
||||||
|
my $tail = File::Tail->new(name=>$opts{log}, maxinterval=>15); |
||||||
|
|
||||||
|
while (defined(my $line=$tail->read)){ |
||||||
|
chomp($line); |
||||||
|
my ($username, $client_ip, $client_name, $share, |
||||||
|
$action, $status, $access_mode, $file_src, $file_dst) = undef; |
||||||
|
|
||||||
|
# Oct 12 17:20:24 sme8 smbd[11176]: admin|192.168.7.50|pc10-45|intranet|mkdir|Nouveau dossier |
||||||
|
if ($line =~ m/^\w+\s\d+\s\d+:\d+:\d+\s\w+\ssmbd\[\d+\]:\s+(\w+)\|(\d+\.\d+\.\d+\.\d+)\|(\w+)\|(\w+)\|(\w+)/){ |
||||||
|
$username = $1; |
||||||
|
$client_ip = $2; |
||||||
|
$client_name = $3; |
||||||
|
$share = $4; |
||||||
|
$action = $5; |
||||||
|
} |
||||||
|
else{ |
||||||
|
printlog("Couldn't parse this line: $line\n"); |
||||||
|
next; |
||||||
|
} |
||||||
|
my @other = split /\|/, $line; |
||||||
|
|
||||||
|
if (($action eq 'opendir') || ($action eq 'rmdir') || ($action eq 'mkdir') || ($action eq 'unlink')){ |
||||||
|
# Oct 12 17:20:24 sme8 smbd[11176]: admin|192.168.7.50|pc10-45|intranet|opendir|ok|./ |
||||||
|
$status = $other[5]; |
||||||
|
$file_src = $other[6]; |
||||||
|
} |
||||||
|
elsif ($action eq 'open'){ |
||||||
|
# Oct 12 17:20:28 sme8 smbd[11176]: admin|192.168.7.50|pc10-45|intranet|open|ok|r|Nouveau document |
||||||
|
$status = $other[5]; |
||||||
|
$access_mode = $other[6]; |
||||||
|
$file_src = $other[7]; |
||||||
|
} |
||||||
|
elsif ($action eq 'rename'){ |
||||||
|
# Oct 12 17:20:28 sme8 smbd[11176]: admin|192.168.7.50|pc10-45|intranet|rename|ok|./Nouveau document|Nouveau document 2 |
||||||
|
$status = $other[5]; |
||||||
|
$file_src = $other[6]; |
||||||
|
$file_dst = $other[7]; |
||||||
|
} |
||||||
|
|
||||||
|
my ($sec,$min,$hour,$day,$mon,$year) = localtime; |
||||||
|
$year += 1900; |
||||||
|
$mon += 1; |
||||||
|
my $date = $year.'-'.$mon.'-'.$day; |
||||||
|
my $time = $hour.':'.$min.':'.$sec; |
||||||
|
|
||||||
|
# MySQL escape |
||||||
|
# Shouldn't be needed, but just in case logs contains junk |
||||||
|
|
||||||
|
$username = mysql_escape($username); |
||||||
|
$client_ip = mysql_escape($client_ip); |
||||||
|
$client_name = mysql_escape($client_name); |
||||||
|
$share = mysql_escape($share); |
||||||
|
$action = mysql_escape($action); |
||||||
|
$access_mode = mysql_escape($access_mode) if (defined $access_mode); |
||||||
|
$status = mysql_escape($status); |
||||||
|
$file_src = mysql_escape($file_src); |
||||||
|
$file_dst = mysql_escape($file_dst) if (defined $file_dst); |
||||||
|
|
||||||
|
# File names may appear with a space at the end in the logs |
||||||
|
$file_src =~ s/\s+$//; |
||||||
|
$file_dst =~ s/\s+$// if (defined $file_dst); |
||||||
|
|
||||||
|
if ($opts{debug} ge 2){ |
||||||
|
my $msg = "New audit entry:\ndate: $date\nhour: $time\nusername: $username\n". |
||||||
|
"client_ip: $client_ip\nclient_name: $client_name\nshare: $share\n". |
||||||
|
"action: $action\nstatus: $status\nfile_src: $file_src"; |
||||||
|
$msg .= "\naccess_mode: $access_mode" if (defined $access_mode); |
||||||
|
$msg .= "\nfile_dst: $file_dst" if (defined $file_dst); |
||||||
|
$msg .= "\n"; |
||||||
|
printlog($msg); |
||||||
|
} |
||||||
|
|
||||||
|
my $q = "INSERT INTO audit ". |
||||||
|
"(samba_host,date_day,date_time,username,client_ip,client_name,". |
||||||
|
"action,"; |
||||||
|
$q .= "access_mode," if (defined $access_mode); |
||||||
|
$q .= "status,share,file_src"; |
||||||
|
$q .= ",file_dst" if (defined $file_dst); |
||||||
|
$q .= ") VALUES('$host','$date','$time','$username','$client_ip','$client_name',". |
||||||
|
"'$action'"; |
||||||
|
$q .= ",'$access_mode'" if (defined $access_mode); |
||||||
|
$q .= ",'$status','$share','$file_src'"; |
||||||
|
$q .= ",'$file_dst'" if (defined $file_dst); |
||||||
|
$q .= ")"; |
||||||
|
|
||||||
|
printlog("Current query:\n$q\n") if ($opts{debug} ge 3); |
||||||
|
|
||||||
|
my $qh = $dbh->prepare($q); |
||||||
|
$qh->execute or exit(1); |
||||||
|
} |
||||||
|
|
||||||
|
exit(0); |
@ -0,0 +1,7 @@ |
|||||||
|
#!/bin/sh |
||||||
|
|
||||||
|
exec \ |
||||||
|
/usr/local/bin/setuidgid smelog \ |
||||||
|
/usr/local/bin/multilog t s5000000 \ |
||||||
|
/var/log/samba-db-logd |
||||||
|
|
@ -0,0 +1,25 @@ |
|||||||
|
#!/usr/bin/perl -w |
||||||
|
|
||||||
|
use esmith::ConfigDB; |
||||||
|
my $c = esmith::ConfigDB->open_ro or die "Couldn't open ConfigDB\n"; |
||||||
|
my $rec = $c->get('samba-db-logd'); |
||||||
|
my $dbname = $rec->prop('DbName') || 'samba_log'; |
||||||
|
my $dbuser = $rec->prop('DbUser') || 'samba'; |
||||||
|
my $dbpass = $rec->prop('DbPassword') || 'samba'; |
||||||
|
my $dbhost = $rec->prop('DbHost') || 'localhost'; |
||||||
|
|
||||||
|
my @args = ("--debug=1", "--dbname=$dbname", "--dbuser=$dbuser", "--dbpass=$dbpass"); |
||||||
|
|
||||||
|
push @args, "--dbhost=$dbhost" if ($dbhost ne 'localhost'); |
||||||
|
|
||||||
|
my $smbd = $c->get('smbd'); |
||||||
|
|
||||||
|
if ($smbd ne 'enabled'){ |
||||||
|
exec("sv", "d", "/service/samba-db-logd"); |
||||||
|
exit(0); |
||||||
|
} |
||||||
|
|
||||||
|
exec("/usr/bin/squid-db-logd", @args) |
||||||
|
or die "Cannot run the Samba Database Loggind Daemon"; |
||||||
|
|
||||||
|
exit(1); |
@ -0,0 +1,15 @@ |
|||||||
|
CREATE TABLE audit ( |
||||||
|
id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, |
||||||
|
samba_host VARCHAR(40) NOT NULL, |
||||||
|
date_day DATE NOT NULL, |
||||||
|
date_time TIME NOT NULL, |
||||||
|
username VARCHAR(30) NOT NULL, |
||||||
|
client_ip CHAR(15) NOT NULL, |
||||||
|
client_name VARCHAR(50) NOT NULL, |
||||||
|
action VARCHAR(15) NOT NULL, |
||||||
|
access_mode VARCHAR(2) default NULL, |
||||||
|
status VARCHAR(10) NOT NULL, |
||||||
|
share VARCHAR(30) NOT NULL, |
||||||
|
file_src VARCHAR(200) default NULL, |
||||||
|
file_dst VARCHAR(200) default NULL |
||||||
|
) ENGINE=MYISAM; |
@ -0,0 +1,58 @@ |
|||||||
|
%define version 0.0.1 |
||||||
|
%define release 1.beta0 |
||||||
|
%define name smeserver-samba-db-logd |
||||||
|
|
||||||
|
|
||||||
|
Summary: samba MySQL logging module for SME Server |
||||||
|
Name: %{name} |
||||||
|
Version: %{version} |
||||||
|
Release: %{release}%{?dist} |
||||||
|
License: GPL |
||||||
|
Group: Networking/Daemons |
||||||
|
Source: %{name}-%{version}.tar.gz |
||||||
|
|
||||||
|
BuildRoot: /var/tmp/%{name}-%{version}-%{release}-buildroot |
||||||
|
BuildArchitectures: noarch |
||||||
|
BuildRequires: e-smith-devtools |
||||||
|
|
||||||
|
Requires: perl(File::Tail) |
||||||
|
Requires: perl(Getopt::Long) |
||||||
|
Requires: perl(DBI) |
||||||
|
|
||||||
|
%description |
||||||
|
Log samba events in a MySQL database |
||||||
|
|
||||||
|
%changelog |
||||||
|
* Fri Oct 12 2012 Daniel Berteaud <daniel@firewall-services.com> 0.2.0-1 |
||||||
|
- Initial release |
||||||
|
|
||||||
|
%prep |
||||||
|
%setup -q -n %{name}-%{version} |
||||||
|
|
||||||
|
%build |
||||||
|
%{__mkdir_p} root/var/log/samba-db-logd |
||||||
|
perl createlinks |
||||||
|
|
||||||
|
%install |
||||||
|
/bin/rm -rf $RPM_BUILD_ROOT |
||||||
|
(cd root ; /usr/bin/find . -depth -print | /bin/cpio -dump $RPM_BUILD_ROOT) |
||||||
|
/bin/rm -f %{name}-%{version}-filelist |
||||||
|
/sbin/e-smith/genfilelist $RPM_BUILD_ROOT \ |
||||||
|
--dir /var/log/samba-db-logd 'attr(0770,smelog,smelog)' \ |
||||||
|
--file /usr/bin/samba-db-logd 'attr(0755,root,root)' \ |
||||||
|
--file /var/service/samba-db-logd/run 'attr(0755,root,root)' \ |
||||||
|
--file /var/service/samba-db-logd/log/run 'attr(0755,root,root)' \ |
||||||
|
--file /etc/cron.monthly/samba-log-rotate 'attr(0755,root,root)' \ |
||||||
|
> %{name}-%{version}-filelist |
||||||
|
|
||||||
|
echo "%doc CHANGELOG.git" >> %{name}-%{version}-filelist |
||||||
|
echo "%doc samba_log.sql" >> %{name}-%{version}-filelist |
||||||
|
%files -f %{name}-%{version}-filelist |
||||||
|
%defattr(-,root,root) |
||||||
|
|
||||||
|
%clean |
||||||
|
rm -rf $RPM_BUILD_ROOT |
||||||
|
|
||||||
|
%post |
||||||
|
%preun |
||||||
|
|
Loading…
Reference in new issue