#
# $Header: /var/smtpd/local/src/RCS/recipient_exists.pl,v 1.3 2006/09/07 13:56:00 root Exp $
#
# This plugin calls internal methods or external scripts to ascertain if a recipient is valid
#
# To punish miscreants, a configurable delay is inserted before the DENY.
#
use Qpsmtpd::DSN;

sub hook_rcpt {

	my ($self, $transaction, $recipient) = @_;
	my $delay = 20;

	return (DECLINED) unless $recipient->host && $recipient->user;

	my $host = lc $recipient->host;
	my $user = lc($recipient->user) . '@' . $host;

	# $self->log(LOGDEBUG,"CHECKING RECIPIENT <$user>");

	if (check_recipient($self, $recipient))
	{
		$self->log(LOGINFO, "Rejecting <$user>");
		sleep $delay;
		return Qpsmtpd::DSN->no_such_user("No such user $user");
	}

	return (DECLINED);
}

sub check_recipient {

	my($self, $recipient)	= @_;

	my $user = lc($recipient->user);
	my $domain = lc($recipient->host);

	#
	# For any domain in %checklist below, call the associated script to
	# check validity of the envelope recipient.
	#
	# Scripts are given the user name (everything before the @) in $ENV{EXT}
	# and the domain (everything after the @) in $ENV{HOST}
	# and are expected to return the following values:
	#
	# 0 for a positive match
	# 99 for no match
	# nonzero for a program error
	#

	my $script_path = '/var/smtpd/local/bin';

	#
	# Handle alias domains that do not have their own directory tree
	#
	if ($domain eq 'blah.org')
	{
		$domain = 'blah.com'
	}

	my(%checklist) 	= (
		"thing.com"	=> "$script_path/nccfilter",
		"blah.com"	=> "$script_path/vpop_rcpt_check_suid_wrapper",
		"foo.com"	=> "$script_path/vpop_rcpt_check_suid_wrapper",
		"bar.net"	=> "$script_path/vpop_rcpt_check_suid_wrapper",
	);


	if (defined($checklist{$domain}))
	{
		$ENV{'EXT'} = $user;
		$ENV{'HOST'} = $domain;
		
		my($retval) = system($checklist{$domain});

		if (($retval >> 8) == 99)
		{
			return 1;
		}
		elsif ($retval != 0)
		{
			$self->log(LOGWARN, "script '$checklist{$domain}' returned error: '$retval'");
		}
	}

	return 0;
}
