#!/usr/bin/perl require '/var/www/cgi-bin/auth.pl'; my $version="0.61i"; my $adminuid="admin"; my $adminpass="secret"; $LDAP_SERVER='imap1'; $LDAP_BASEDN='o=your org,c=ca'; my $maildomain="toshiba.ca"; my $vacationfile="/var/imap/procmail/vacationmsg"; my $replyfile="/var/imap/procmail/reply"; my $vacationdb="/var/imap/procmail/vacationdb"; my $rulefile="/var/imap/procmail/procmailrc"; my $rejectfile="/var/imap/procmail/rejectfile"; my $header="X-Customfilter:"; sub updateprocmail { my ($filterval,$uid) =@_; my (@mbxlist,$rulesyes,$vacationyes,$usereject); %fields=( "subject",'^Subject:', "to2",'(^Cc:|^CC:|^To:|^TO:|^Sender:)', "to",'^TO_', "contain",'* ', "not contain",'* !', "from",'^From:', "address","* !^X-Loop: \$CYUSER\@$maildomain\n| \$FORMAIL -A\"X-Loop: \$CYUSER\@$maildomain\" | \$SENDMAIL ", "folder",'| $DELIVERTO $USERINBOX.', "nocopy",':0', "copy",':0 ic', "reply",':0 hc', "vacation",':0 Whc: locfile' ); $copybit=1; $sizebit=2; $searchbit=4; $keepbit=8; $regexbit=128; my %matchtype=( "0","allof", $searchbit,"anyof" ); my (@lrules)=split('\n',$filterval); my ($keep,$copystat,$procr,$extradefs) = ""; my $proc=""; my $not=""; $copystat=""; $procr=""; $rulesyes=0; $vacationyes=0; my ($fieldn,$field,$wc); my $regexused; my %vacation; #remove old files; my @remove=glob("$replyfile.*.$uid"); while ($_=shift(@remove)) { unlink $_; } unlink "$vacationdb.$uid"; unlink "$vacationfile.$uid"; while (@lrules) { my $tmp=''; $line=shift(@lrules); if ($line=~/^ *#vacation&&(.*)&&(.*)&&(.*)&&(.*)/i) { $vacation{'days'}=$1; $vacation{'addresses'}="$2"; $vacation{'text'}=$3; $vacation{'mode'}=$4; $vacation{'addresses'}=~s/\\@/\@/g; $vacation{'addresses'}=~s/\"//g; $usevacation=1; next; } chomp($line); my ($tag,$priority,$ruletype,$from,$to,$subject,$desttype,$dest,$flg,$fieldname,$fieldval,$size) = split("&&",$line); next if !$desttype; next if $tag=~/mode/i; $priority=~s/^ +//; $priority=~s/ +$//; $dest=~s/\r//g; $dest=~s/\\n/\r\n/g; if ($flg=~/copy/i) { $copyflg='copy'; } else { $copyflg= ($flg & $copybit); } if ($copyflg) { $copyflg='copy'; } else { $copyflg='nocopy'; } $matchflg=($flg & $searchbit); $keepflg=($flg & $keepbit); $keepflg=0 if (!$keepflg); $matchflg=0 if (!$matchflg); $sizeflg=($flg & $sizebit); $sizeflg=0 if (!$sizeflg); $regexflg=($flg & $regexbit); $regexused ||=$regexflg; if ($ruletype !~/ENABLED|\d/i) {next}; if ($desttype=~/folder/i) { next if !$dest; $dest=~s/^INBOX.INBOX/INBOX/; if (($dest =~s/^INBOX\.(.+)/$1/)||($alt_namespace)) { $msgdest=$dest; } else { $msgdest="$dest"; } # check if folder is in an addtional namespace foreach $namespace (@namespaces) { if ($dest=~/^$namespace./i) { $msgdest="$dest"; last; # stop checking } } } elsif ($desttype=~/discard/) { $msgdest="/dev/null"; } elsif ($desttype=~/address/i) { if ($dest =~/\w+\@\w+\.\w+/) { $msgdest=$dest; } else { next; } next if !$dest; } else {$msgdest='';} $rulesyes=1; $fieldn='0'; $field=''; $not=''; if ($to) { $not="!" if $to=~s/^\s*!//; $to=".*$to.*"; $field.=$not.$fields{'contain'}.$fields{'to'}."$to\n"; $fieldn++; } $not=''; if ($from) { $not="!" if $from=~s/^\s*!//; $from=".*$from.*"; $field.=$not.$fields{'contain'}.$fields{'from'}."$from\n"; $fieldn++; } $not=''; if ($subject) { $not="!" if $subject=~s/^\s*!//; $subject=".*$subject.*"; $field.=$not.$fields{'contain'}.$fields{'subject'}."$subject\n"; $fieldn++; } $not=''; if ($size) { $contains='< '; $contains='> ' if $sizeflg; $not="!" if $size=~s/^\s*!//; $size=~/([0-9]+)/; $kb=''; $size=$1; $size='' if !$size; $field.=$not.$contains.$size."$kb\n"; $fieldn++; } $not=''; if ($fieldname && $fieldval) { $not="!" if $fieldval=~s/^\s*!//; $fieldval=".*$fieldval.*"; $field.=$not.$fields{'contain'}."^".$fieldname.": "."$fieldval\n"; $fieldn++; } if (!($to || $from || $subject || $size || $fieldname || $fieldval ) && $desttype ne 'custom') { $tmp=''; # for now $copystat=''; } elsif ($desttype=~/reject/) { $msgdest="* !^X-Loop: $uid\@$maildomain\n* !^FROM_DAEMON\n"; $msgdest.="| (\$FORMAIL -r -I\"Precedeence: junk\" -A\""; $msgdest.="X-Loop: $uid\@$maildomain\";/bin/cat $rejectfile; /bin/echo \"-- \";) | \$SENDMAIL ;"; $tmp=":0 h"."\n".$field."$msgdest\n\n"; } elsif ($desttype=~/reply/i) { $msgdest="* !^X-Loop: $uid\@$maildomain\n* !^FROM_DAEMON\n"; $msgdest.="| (\$FORMAIL -r -I\"Precedeence: junk\" -A \""; $msgdest.="X-Loop: $uid\@$maildomain\";/bin/cat $replyfile.$priority.$uid ; /bin/echo \"-- \";) | \$SENDMAIL ;"; $tmp=$fields{$copyflg}."\n".$field."$msgdest\n\n"; open (REP,">$replyfile.$priority.$uid"); print REP "$dest\n"; close REP; next if !$dest; } elsif ($desttype eq 'custom') { $tmp=$dest."\n\n"; next if $tmp!~/^\s*:0/; } else { $tmp=$fields{$copyflg}."\n".$field.$fields{lc($desttype)}."\'$msgdest\'\n\n"; } $proc.=$tmp; $change=1; } #while @lrules $vacationyes=1 if ($vacation{'mode'}=~/on|active|yes|1/i); $proch="# Mail rules for user $uid\n# Created by Websieve version $version\n\n"; $proc=$proch.$proc; if($vacation{'mode'}=~/on|active|yes|1/i) { $vacation{'text'}=~s/\\n/\r\n/g; if ($vacation{'text'}) { $msgdest="* !^X-Loop: $uid\@$maildomain\n* !^FROM_DAEMON\n"; $msgdest.="| \$FORMAIL -rD 8192 $vacationdb.$uid\n\n"; $msgdest.=":0 ehc\n| (\$FORMAIL -r -I\"Precedence: junk\" -A\"X-Loop: $uid\@$maildomain\" ; /bin/cat $vacationfile.$uid; ) | \$SENDMAIL; "; $proc.=":0 Whc: $vacationdb.$uid.lock"."\n"."$msgdest\n\n"; open (VAC,">$vacationfile.$uid"); print VAC $vacation{'text'}."\n"; close VAC; open (VACDB,">$vacationdb.$uid"); close VACDB; $rulesyes=1; } else { $vacation{'mode'}='off'; } } else { unlink "$vacationfile.$uid"; unlink "$vacationdb.$uid"; } # if (!$rulesyes ) { # $proc=$proch; # $rulesyes=1; # } $change=1; if ($rulesyes) { # print "proc=\n$proc\npseudo=\n$pseudo\n"; open (OUT,">$rulefile.$uid"); print OUT "$proc\n"; close OUT; return; } # if rulesyes else { unlink "$rulefile.$uid"; } } sub parseinput { while (<>) { print $_; if (/^$header +(\w+) (\S+)/) { ($uid, $adminsecret)=($1,$2); last; } } return $uid; } #main $uid=&parseinput; $uid= $ARGV[0] if $ARGV[0]; $ld=&auth_connect($adminuid,$adminpass); $dn=&auth_getdn($ld,$uid); $rules=&auth_getatt($ld,$dn,'matchingrules'); &updateprocmail($rules,$uid) if $rules;