[Mimedefang] Compliance
Josh Kelley
josh at jbc.edu
Thu Apr 14 16:09:40 EDT 2005
alan premselaar wrote:
> I'd be interested in at least looking at it. Currently I'm using
> procmail for local delivery and its Quota handling is kludgey at best.
> I'd really like to get something working within MD. Since the method
> Jan uses calls the perl module for Quota directly, I don't think
> setting setuid on the quota application will make any difference
> (although I haven't looked at the Quota module code either)
Here you go. A brief explanation: we're only really interested in
checking quotas for students, since faculty/staff don't have quotas.
Students use their student IDs for their usernames, with
firstname.lastname set up as an email alias, so we have to check
aliases. We test for numeric usernames to see if the account is a
student (instead of testing something sensible like the account's gid -
I don't know what I was thinking). Rather than checking current space
usage against the message size, as Jan did, we just check to see if the
user has already exceeded their soft quota and has exceeded their grace
period (i.e., grace is 'none'). This means that the occasional
over-the-quota bounce still gets generated (for messages that exceed the
hard limit before the grace period expires, or for messages so big that
they exceed the hard limit for users currently below the soft limit).
This hasn't usually been a problem, but sometime I'll go back and add
Jan's enhancements - thanks, Jan, for posting your code.
sub filter_initialize() {
$quota_dev = Quota::getqcarg('/var/spool/mail');
tie(%alias, 'DB_File', '/etc/aliases.db', O_RDONLY, 0);
}
sub filter_recipient($$$$$$$$$) {
my ($recipient, $sender, $hostip, $hostname, $first, $helo,
$rcpt_mailer, $rcpt_host, $rcpt_addr) = @_;
# For local students, check quota
if ($rcpt_mailer eq 'local') {
my($real_addr) = lc($rcpt_addr);
# Chase down any aliases
while ($alias{$real_addr . "\0"}) {
$real_addr = $alias{$real_addr . "\0"};
$real_addr =~ s/\0$//;
}
# Only check students who don't forward mail.
($real_addr =~ /^\d+$/) or return ('CONTINUE', 'ok');
my($uid, $homedir) = (getpwnam($real_addr))[2,7];
(-f "$homedir/.forward") and return ('CONTINUE', 'ok');
# Check the quota. We have to query by UID, since numeric
# usernames confuse the quota binary.
my($quota) = grep { /^\s+$quota_dev/ } split(/\n/,
`/usr/local/bin/wwwquota $uid`);
if ($quota =~ /\*.*none/) {
return ('TEMPFAIL',
"$recipient... User mailbox is full, cannot deliver",
'452', '4.2.2');
}
}
return ('CONTINUE', 'ok');
}
Hope this helps.
Josh Kelley
More information about the MIMEDefang
mailing list