# this plugin checks the rcpt address (replaces check_relay) # It should be configured to be run _LAST_! # Copyright (c) 2002 Andrew Pam sub register { my ($self, $qp) = @_; $self->register_hook("rcpt", "check_rcptto"); } sub check_rcptto { my ($self, $transaction, $recipient) = @_; return (DECLINED) unless $recipient->host && $recipient->user; my $host = lc $recipient->host; my $local = 0; unless (exists $ENV{RELAYCLIENT}) { # Check if domain is in "rcpthosts" my @rcpt_hosts = $self->qp->config("rcpthosts"); for my $allowed (@rcpt_hosts) { $allowed =~ s/^\s*(\S+)/$1/; last if $local = (($host eq lc $allowed) or (substr($allowed,0,1) eq "." and $host =~ m/\Q$allowed\E$/i)); } return (DENY) unless $local; } # Check if domain is in "locals" my @locals; @locals = $self->qp->config("locals") or @locals = $self->qp->config("me"); $local = 0; for my $domain (@locals) { $domain =~ s/^\s*(\S+)/$1/; last if $local = ($host eq lc $domain); } my $delivery = $recipient->user; $delivery =~ s/\./:/g; if ($local) { # Add check for "users/assign" here $self->log(7, "$host is local"); } else { # Check if domain is in "virtualdomains" my @virtual = $self->qp->config("virtualdomains") or return (OK); my %virtual = map split(/:/), @virtual; return (OK) unless defined $virtual{$host}; $delivery = $virtual{$host} . "-" . $delivery; } my ($user, $uid, $gid, $dir, $duid, $dgid); my $message = "Return to sender, address unknown"; ($user, $delivery) = split /-/, $delivery, 2; $self->log(5, "User: $user"); $self->log(5, "Delivery: $delivery") if defined $delivery; if ($user eq "alias") { # I don't think we should allow delivery to the actual "alias" user return (DENY, $message) unless defined $delivery; } else { # Should we run "qmail-getpw" here instead? if (($_,$_,$uid,$gid,$_,$_,$_,$dir) = getpwnam($user)) { # Check home directory existence and ownership return (OK) if (-d $dir and ($_,$_,$_,$_,$duid,$dgid) = stat _ and $duid == $uid and $dgid == $gid); } # Can't deliver to a user, look for aliases $delivery = (defined $delivery ? "$user-$delivery" : $user); } # Check for existence of .qmail file ($_,$_,$_,$_,$_,$_,$_,$dir) = getpwnam("alias"); $self->log(5, "Checking $dir/.qmail-$delivery"); return (OK) if -l "$dir/.qmail-$delivery" or -e _; # Also check for .qmail*-default files do { $delivery =~ s/[^-]+$//; $self->log(5, "Checking $dir/.qmail-${delivery}default"); return (OK) if -l "$dir/.qmail-${delivery}default" or -e _; $delivery =~ s/-$//; } while $delivery; return (DENY, $message); }