#!/usr/bin/perl use Cyrus::IMAP::Admin; # This script was created by Kevin J. Menard, Jr. . # It requires root privileges to write to a file in /etc. Best use is # to set this up as cron job. Works for me. Hope it does for you. # Any questions/complaints/praise/whatever, send 'em to the address # above. -- 08/16/2001 # These are the variables you might want to tweak. my $quota_attr = "mailQuota"; my $mail_attr = "mailRoutingAddress"; my $user = "cyrus"; my $passwd = "blah"; # These are the ones that you shouldn't have to. my @entries = (); my $index = 0; my $counter = 0; my $old_timestamp = 0; my $timestamp = "199412161032Z"; # Open the /etc/cyrus_ldap_quota_time file; it's a long name, but # shouldn't interfere with existing files :) This file contains 1 line, # the generalized time format of the last time the script ran. This is # used for the search, so we only update quotas that have been modified # since then. { if (-e "/etc/cyrus_ldap_quota_time") { open(TIME_FILE, "/etc/cyrus_ldap_quota_time") or die "could not open the time file: $!\n"; while() { $old_timestamp = $_; } close(TIME_FILE); } # Now we deal with the case where the file doesn't exist, that is to # say the first time the script was run. unless ($old_timestamp == 0) { $timestamp = $old_timestamp; } # Now that we have that information, we can overwrite the file with # the new timestamp. Maybe this overkill, but this is only a # temporary solution anyway. open(TIME_FILE, ">/etc/cyrus_ldap_quota_time") or die "could not create file: $!\n"; my @time = (localtime)[0..5]; printf TIME_FILE $time[5] + 1900; printf TIME_FILE "%02d", $time[4] + 1; for (my $i = 3; $i >= 0; $i--) { printf TIME_FILE "%02d", $time[$i];} print TIME_FILE 'Z'; close(TIME_FILE); } # This is where we do the search and then parse the results into a # useable form. In this case, an arry of hash entries. { # Okay, this very ugly line sets up the LDAP search, and the strips # away the meaningless stuff. This could be prettier, but I didn't # want to add a dependency for an LDAP module, and everyone should # have LDAP search. The greps are just to make things simpler. (my $query = "ldapsearch -x '(&(modifyTimestamp>=$timestamp)($quota_attr=*))' $quota_attr $mail_attr | grep -v ^# | grep -v ^dn | grep -v ^version | grep -v ^search | grep -v ^result | grep -v ^\$") =~ s!\n!!; # Now actually do the commands in the above line. my $result = `$query`; # Split the output into an array, one entry per line. my @output = split(/\n/, $result); # Now go through each line . . . foreach (@output) { # Split on the attribute:value boundary. (my $key, my $value) = split(/: /); # Handle mailRoutingAddress; strip away everything after '@'. if ($value =~ m!@!) { ($value, undef) = split (/@/, $value); } # Add each doctored up attribute:value pair to the entries array. $entries[$index]{$key} = $value; # A crude hack to make sure each of the two attributes makes it # into one of the entries array element. if ($counter % 2) { $index++; } $counter++; } } # Now here's the actual interaction with Cyrus IMAPd. It's all pretty # self-explanatory. { my $imap = Cyrus::IMAP::Admin->new('localhost') or die "imap: cannot connect to server: $!\n"; $imap->send(undef, undef, "LOGIN %s %s", $user, $passwd) or die "could not send user:pass to the server: $!\n"; for (my $i = 0; $i <= $#entries; $i++) { $imap->setquota("user." . $entries[$i]{$mail_attr}, "STORAGE", $entries[$i]{$quota_attr}) or die "imap: could not set quota for user.$entries[$i]{$mail_attr}: $!\n"; } $imap=undef; }