diff --git a/zabbix_conf/samba_dc.conf b/zabbix_conf/samba_dc.conf index 44333b2..af189c8 100644 --- a/zabbix_conf/samba_dc.conf +++ b/zabbix_conf/samba_dc.conf @@ -1,3 +1,7 @@ +UserParameter=samba_dc.discovery[*],sudo /var/lib/zabbix/bin/disco_samba_dc_sudo --what='$1' # Create a text item with key samba_dc.info[300] and a check interval of 300 # Then use dependent item to get individual counters -UserParameter=samba_dc.info[*],sudo /var/lib/zabbix/bin/check_samba_dc_sudo --since=$1 +UserParameter=samba_dc.info[*],sudo /var/lib/zabbix/bin/check_samba_dc_sudo --since='$1' +# Create a text item with key samba_dc.ou[{#SAMBA_OU}], then use dependant items with JSONPath to get individual info +UserParameter=samba_dc.ou[*],sudo /var/lib/zabbix/bin/check_samba_dc_sudo --ou='$1' + diff --git a/zabbix_scripts/check_samba_dc_sudo b/zabbix_scripts/check_samba_dc_sudo index 0862735..56b55d4 100644 --- a/zabbix_scripts/check_samba_dc_sudo +++ b/zabbix_scripts/check_samba_dc_sudo @@ -13,6 +13,9 @@ my $pdbedit = which('pdbedit'); # Number of seconds in the past to count authentications my $since = 300; my $pretty = 0; +my $general = 1; +my $ou = undef; + # This log is expected to be in JSON format. For example, in smb.conf : # log level = 1 auth_audit:3 auth_json_audit:4@/var/log/samba/audit_auth.log my $audit_auth_log = '/var/log/samba/audit_auth.log'; @@ -25,132 +28,150 @@ if (not defined $samba_tool or not defined $pdbedit){ GetOptions( 'pretty' => \$pretty, 'since=i' => \$since, - 'audit-auth-log=s' => \$audit_auth_log + 'audit-auth-log=s' => \$audit_auth_log, + 'general' => \$general, + 'ou=s' => \$ou ); if ($since !~ m/^\d+$/){ die "Invalid value for since\n"; } -my $json = { - accounts => { - users => 0, - inactive_users => 0, - active_users => 0, - groups => 0, - computers => 0 - }, - replication => 'UNKNWON', - processes => { - cldap_server => 0, - kccsrv => 0, - dreplsrv => 0, - ldap_server => 0, - kdc_server => 0, - dnsupdate => 0, - 'notify-daemon' => 0, - rpc_server => 0, - winbind_server => 0, - nbt_server => 0, - dnssrv => 0, - samba => 0, - }, - gpo => 0, - ou => 0, - activity => { - authentications => { - users => { - success => 0, - failure => 0 - }, - computers => { - success => 0, - failure => 0 - } +my $json = {}; + +if (defined $ou){ + $json = { + objects => 0 + }; + if ($ou !~ m/^(?(?(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+)\=(?(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+))(?:\s*\,\s*(?(?(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+)\=(?(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+)))*$/){ + die "Invalid OU\n"; + } + foreach (qx($samba_tool ou listobjects '$ou')){ + die "Error while counting objects of OU $ou\n" if ($? != 0); + chomp; + $json->{objects}++; + } +} elsif ($general){ + $json = { + accounts => { + users => 0, + inactive_users => 0, + active_users => 0, + groups => 0, + computers => 0 }, - authorizations => { - users => 0, - computers => 0 + replication => 'UNKNWON', + processes => { + cldap_server => 0, + kccsrv => 0, + dreplsrv => 0, + ldap_server => 0, + kdc_server => 0, + dnsupdate => 0, + 'notify-daemon' => 0, + rpc_server => 0, + winbind_server => 0, + nbt_server => 0, + dnssrv => 0, + samba => 0, }, - since => $since - } -}; - -# Get the numbers of users. pdbedit is prefered here because we can -# differentiate active and inactive users, which samba-tool can't do -# While at it, also get the computers -foreach (qx($pdbedit -L -v)){ - next unless (m/^Account Flags:\s+\[(.*)\]/); - my $flags = $1; - if ($flags =~ m/U/){ - $json->{accounts}->{users}++; - if ($flags =~ m/D/){ - $json->{accounts}->{inactive_users}++; - } else { - $json->{accounts}->{active_users}++; + gpo => 0, + ou => 0, + activity => { + authentications => { + users => { + success => 0, + failure => 0 + }, + computers => { + success => 0, + failure => 0 + } + }, + authorizations => { + users => 0, + computers => 0 + }, + since => $since + } + }; + + # Get the numbers of users. pdbedit is prefered here because we can + # differentiate active and inactive users, which samba-tool can't do + # While at it, also get the computers + foreach (qx($pdbedit -L -v)){ + next unless (m/^Account Flags:\s+\[(.*)\]/); + my $flags = $1; + if ($flags =~ m/U/){ + $json->{accounts}->{users}++; + if ($flags =~ m/D/){ + $json->{accounts}->{inactive_users}++; + } else { + $json->{accounts}->{active_users}++; + } + } elsif ($flags =~ m/W/){ + $json->{accounts}->{computers}++; } - } elsif ($flags =~ m/W/){ - $json->{accounts}->{computers}++; } -} -# Now count groups -foreach (qx($samba_tool group list)){ - $json->{accounts}->{groups}++; -} + # Now count groups + foreach (qx($samba_tool group list)){ + $json->{accounts}->{groups}++; + } -# Get replication status -# We want just a quick summary, so only output the first line -# manual checks will be needed to get the details, but if this field doesn't contains [ALL GOOD], -# then something is probably wrong -$json->{replication} = (split(/\n/, qx($samba_tool drs showrepl --summary)))[0]; + # Get replication status + # We want just a quick summary, so only output the first line + # manual checks will be needed to get the details, but if this field doesn't contains [ALL GOOD], + # then something is probably wrong + $json->{replication} = (split(/\n/, qx($samba_tool drs showrepl --summary)))[0]; -# Get the list of workers -foreach (qx($samba_tool processes)){ - if (/^([^\(\s]+).+\d+$/){ - $json->{processes}->{$1}++; + # Get the list of workers + foreach (qx($samba_tool processes)){ + if (/^([^\(\s]+).+\d+$/){ + $json->{processes}->{$1}++; + } } -} -# Get the number of GPO -foreach (qx($samba_tool gpo listall)){ - next unless (/^GPO/); - $json->{gpo}++; -} + # Get the number of GPO + foreach (qx($samba_tool gpo listall)){ + next unless (/^GPO/); + $json->{gpo}++; + } -# Get the number of OU -foreach (qx($samba_tool ou list)){ - $json->{ou}++; -} + # Get the number of OU + foreach (qx($samba_tool ou list)){ + $json->{ou}++; + } + + if (-e $audit_auth_log){ + open (my $auth_log, '<', $audit_auth_log) or die "Couldn't open $audit_auth_log : $!\n"; + foreach my $line (<$auth_log>){ + my $event = from_json($line); + my $type = $event->{type}; + # We're only interested in Authentication and Authorization messages + next if ($type ne 'Authentication' and $type ne 'Authorization'); + # Parse the date in the timstamp field + my $timestamp = str2time($event->{timestamp}); + + # Only look at lines from the last $since seconds. Skip if date couldn't be parsed + next if (not defined $timestamp or time() - $timestamp > $since); -if (-e $audit_auth_log){ - open (my $auth_log, '<', $audit_auth_log) or die "Couldn't open $audit_auth_log : $!\n"; - foreach my $line (<$auth_log>){ - my $event = from_json($line); - my $type = $event->{type}; - # We're only interested in Authentication and Authorization messages - next if ($type ne 'Authentication' and $type ne 'Authorization'); - # Parse the date in the timstamp field - my $timestamp = str2time($event->{timestamp}); - - # Only look at lines from the last $since seconds. Skip if date couldn't be parsed - next if (not defined $timestamp or time() - $timestamp > $since); - - my $subject; - if ($type eq 'Authentication'){ - # Accounts ending with $ are for computers - $subject = ($event->{$type}->{mappedAccount} =~ m/\$$/) ? 'computers' : 'users'; - if ($event->{Authentication}->{status} eq 'NT_STATUS_OK'){ - $json->{activity}->{authentications}->{$subject}->{success}++; + my $subject; + if ($type eq 'Authentication'){ + # Accounts ending with $ are for computers + $subject = ($event->{$type}->{mappedAccount} =~ m/\$$/) ? 'computers' : 'users'; + if ($event->{Authentication}->{status} eq 'NT_STATUS_OK'){ + $json->{activity}->{authentications}->{$subject}->{success}++; + } else { + $json->{activity}->{authentications}->{$subject}->{failure}++; + } } else { - $json->{activity}->{authentications}->{$subject}->{failure}++; + $subject = ($event->{$type}->{account} =~ m/\$$/) ? 'computers' : 'users'; + $json->{activity}->{authorizations}->{$subject}++; } - } else { - $subject = ($event->{$type}->{account} =~ m/\$$/) ? 'computers' : 'users'; - $json->{activity}->{authorizations}->{$subject}++; } + close $auth_log; } - close $auth_log; } print to_json($json, { pretty => $pretty }); diff --git a/zabbix_scripts/disco_samba_dc_sudo b/zabbix_scripts/disco_samba_dc_sudo new file mode 100644 index 0000000..12ad1b2 --- /dev/null +++ b/zabbix_scripts/disco_samba_dc_sudo @@ -0,0 +1,34 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; +use JSON; +use Getopt::Long; +use File::Which; + +my $what = 'ou'; +my $pretty = 0; +my $json = []; + +my $samba_tool = which('samba-tool'); + +if (not defined $samba_tool){ + print $json; + exit 0; +} + +GetOptions( + 'what=s' => \$what, + 'pretty' => \$pretty +); + +if ($what eq 'ou'){ + foreach (qx($samba_tool ou list)){ + chomp; + push @{$json}, { + '{#SAMBA_OU}' => $_ + } + } +} + +print to_json($json, { pretty => $pretty }); diff --git a/zabbix_templates/Template_App_Samba_DC.xml b/zabbix_templates/Template_App_Samba_DC.xml index 1402a49..6aa863a 100644 --- a/zabbix_templates/Template_App_Samba_DC.xml +++ b/zabbix_templates/Template_App_Samba_DC.xml @@ -1,7 +1,7 @@ 5.0 - 2021-01-11T08:38:19Z + 2021-01-11T15:08:31Z Templates @@ -644,6 +644,51 @@ + + + Samba:OU discovery + samba_dc.discovery[ou] + 1h + + + Samba: Number of objects in {#SAMBA_OU} + DEPENDENT + samba_dc.ou[{#SAMBA_OU},objects] + 0 + 60d + 1825d + !objects + + + Samba + + + + + JSONPATH + $.objects + + + + samba_dc.ou[{#SAMBA_OU}] + + + + Samba: Info for {#SAMBA_OU} + samba_dc.ou[{#SAMBA_OU}] + 5m + 0 + 0 + TEXT + + + Samba + + + + + +