Mail-Milter-Authentication-Extra/lib/Mail/Milter/Authentication/Handler/UserDB.pm
package Mail::Milter::Authentication::Handler::UserDB;
use strict;
use warnings;
use DB_File;
use Mail::Milter::Authentication::Handler::UserDB::Hash;
use Sys::Syslog qw{:standard :macros};
use Mail::AuthenticationResults::Header::Entry;
use Mail::AuthenticationResults::Header::SubEntry;
use Mail::AuthenticationResults::Header::Comment;
use base 'Mail::Milter::Authentication::Handler';
our $VERSION = '2.20180611'; # VERSION
# ABSTRACT: Check inbound mail against a user list
my $CHECKED_TIME;
sub default_config {
return {
'add_header' => 1,
'lookup' => [ 'hash:/etc/postfix/virtusertable' ],
};
}
sub grafana_rows {
my ( $self ) = @_;
my @rows;
push @rows, $self->get_json( 'UserDB_metrics' );
return \@rows;
}
sub register_metrics {
return {
'userdb_total' => 'The number of emails processed for UserDB',
};
}
sub setup_callback {
my ( $self ) = @_;
delete $self->{'local_user'};
return;
}
sub envrcpt_callback {
my ( $self, $env_to ) = @_;
my $address = $self->get_address_from( $env_to );
my $user = $self->get_user_from_address( $address );
$self->{'local_user'} = $user if $user;
return;
}
sub eoh_callback {
my ( $self ) = @_;
my $config = $self->handler_config();
if ( $self->{'local_user'} ) {
$self->metric_count( 'userdb_total', { 'result' => 'pass' } );
if ( $config->{'add_header'} ) {
my $header = Mail::AuthenticationResults::Header::Entry->new()->set_key( 'x-local-user' )->safe_set_value( 'pass' );
$self->add_auth_header( $header );
}
}
else {
$self->metric_count( 'userdb_total', { 'result' => 'fail' } );
}
return;
}
sub close_callback {
my ( $self ) = @_;
delete $self->{'local_user'};
return;
}
{
my $lookers_cache;
sub get_lookers {
my ( $self ) = @_;
if ( $lookers_cache ) {
my $reloaded = 0;
foreach my $looker ( @{$lookers_cache} ) {
$reloaded = $reloaded + $looker->check_reload();
}
if ( $reloaded ) {
$self->dbgout( 'UserDb', 'Re-loading User DB', LOG_INFO );
}
return $lookers_cache;
}
$self->dbgout( 'UserDb', 'Loading User DB', LOG_DEBUG );
my @lookers;
my $config = $self->handler_config();
my $lookups = $config->{'lookup'};
foreach my $lookup ( @$lookups ) {
my ( $type, $data ) = split ':', $lookup, 2;
if ( $type eq 'hash' ) {
my $looker = Mail::Milter::Authentication::Handler::UserDB::Hash->new( $data );
push @lookers, $looker;
$looker->preload();
}
else {
die "Unknown UserDB lookup type $type";
}
}
$lookers_cache = \@lookers;
return $lookers_cache;
}
}
sub get_user_from_address {
my ( $self, $address ) = @_;
$self->dbgout( 'UserDb Lookup', $address, LOG_DEBUG );
my $lookers = $self->get_lookers();
foreach my $looker ( @{$lookers} ) {
my $user = $looker->get_user_from_address( $address );
$self->dbgout( 'UserDb Found', $user, LOG_DEBUG ) if $user;
return $user if $user;
}
return;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Mail::Milter::Authentication::Handler::UserDB - Check inbound mail against a user list
=head1 VERSION
version 2.20180611
=head1 DESCRIPTION
Check if email has a local recipient account.
=head1 CONFIGURATION
"UserDB" : {
"add_header" : 1,
"lookup" : [ "hash:/etc/postfix/virtusertable" ]
},
=head2 CONFIG
Add a block to the handlers section of your config as follows.
"UserDB" : {
"add_header" : 1,
"lookup" : [ "hash:/etc/postfix/virtusertable" ]
},
=head1 AUTHOR
Marc Bradshaw <marc@marcbradshaw.net>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2018 by Marc Bradshaw.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut