poste.io

complete mail server built in docker
Open source plugins for QPSMTPD:

RCPT database


Download
#!perl -w

=head1 NAME

check_rcpt_database - check recipient against database

=head1 DESCRIPTION

See script inside. This plugin do not allow aliases and similar stuff.
Database should have table "domains" and "users". Its all somewhat
hardcoded so you might update it to fit your needs...

=head1 AUTHOR

Copyright (c) 2015 Stanislav Humplik (stanislav@analogic.cz)
http://poste.io

This plugin is free software; you can distribute it and/or modify it
under the terms of the General Public License v3.

=cut

use strict;
use warnings;

use Qpsmtpd::Constants;
use Qpsmtpd::DSN;
use DBI;

sub hook_rcpt {
    my ($self, $transaction, $recipient, %param) = @_;

    if ($self->qp && $self->qp->connection) {
        my $previous = $self->qp->connection->notes('logging-session-last-to');
        $self->qp->connection->notes('logging-session-last-to', ($previous ? "$previous;" : '' ).$recipient->address);
    }

    my $dbh = DBI->connect(
        "DBI:SQLite:dbname=/data/users.db",
        "",
        "",
        { RaiseError => 1 },
    );

    if(!$dbh) {
        $self->log(LOGERROR, 'skip, DBI: ' . $DBI::errstr);
        return (DECLINED, 'cant connect to database');
    }

    my @domain = $dbh->selectrow_array( "SELECT * FROM domains WHERE name = ?", undef, $recipient->host());

    if(@domain == 0) {
        $dbh->disconnect();

        $self->log(LOGINFO, "skip, $recipient has remote delivery domain");
        return (DECLINED, 'remote delivery domain');
    }


    my @user = $dbh->selectrow_array( "SELECT * FROM users WHERE address = ?", undef, $recipient->address());

    $dbh->disconnect();

    if(@user > 0) {
        $self->log(LOGINFO, "ok, user $recipient found in user database");
        return (OK);
    } else {
        $self->log(LOGINFO, "deny, user $recipient not found in user database");
        return (DENY, "no such user");
    }

}