[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