Yesterday we had to move about 300 domains from one machine to another. We bought a new machine recently and are taking this opportunity to move from Qmail (difficult to use, in my opinion) towards Postfix.
After doing one or two by hand, i decided that’s stupid – why not just automate the whole thing.
So I whipped up a script that reads details from vqadmin and uses those details to create postfix emails using mailadmin.
Please note that this does not handle forwards and other weirdness – just plain old email accounts. After running it, you need to check the accounts for forwards. I /could/ adapt it, but am too lazy.
<?php
$vqadmin_url='http://1.2.3.4/cgi-bin/vqadmin/vqadmin.cgi';
$vqadmin_auth='username:password';
$postfixmailadmin_url='http://5.6.7.8/mailadmin/';
$postfixmailadmin_username='your@email.address';
$postfixmailadmin_password='password';
ob_start();
// { get all domains
$ch=curl_init($vqadmin_url);
curl_setopt($ch, CURLOPT_USERPWD,$vqadmin_auth);
curl_setopt($ch, CURLOPT_POST, true );
curl_setopt($ch, CURLOPT_POSTFIELDS, 'nav=list_domains' );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
curl_exec($ch);
$page=join('',explode("\n",curl_multi_getcontent($ch)));
preg_match_all('#<a href=vqadmin.cgi\?nav=view_domain&dname=([^>]*)>[^<]*</a>#',$page,$domains);
curl_close($ch);
// }
$numdomains=0; $numemails=0;
foreach($domains[1] as $domain){
$numdomains++;
echo '<h2>'.$numdomains.' - '.$domain.'</h2>';
// { get password page
$ch=curl_init($vqadmin_url);
curl_setopt($ch, CURLOPT_USERPWD,$vqadmin_auth);
curl_setopt($ch, CURLOPT_POST, true );
curl_setopt($ch, CURLOPT_POSTFIELDS, 'dname='.$domain.'&Submit=Show Users&nav=show_users' );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
curl_exec($ch);
$page=join('',explode("\n",curl_multi_getcontent($ch)));
curl_close($ch);
// }
// { extract passwords
preg_match_all('#<tr><td><FONT face=Verdana color="\#FFFFFF"><a href=[^>]*>[^<]*</a></FONT></td><td align=middle><FONT face=Verdana color="\#FFFFFF">[^<]*</FONT></td><td align=middle><FONT face=Verdana color="\#FFFFFF">[^<]*</FONT></td><td align=middle><FONT face=Verdana color="\#FFFFFF">[^<]*</FONT></td><td align=middle><FONT face=Verdana color="\#FFFFFF">[^<]*</FONT></td><td align=middle><FONT face=Verdana color=\#FFFFFF>(<B>)?[^<]*(</B>)?</FONT></td><td align=middle><FONT face=Verdana color=\#FFFFFF>[^<]*</font></td></tr>#',$page,$matches);
$matches=$matches[0];
$emails=array();
foreach($matches as $match){
$username=preg_replace('#<tr><td><FONT face=Verdana color="\#FFFFFF"><a href=[^>]*>([^<]*)<.*#','$1',$match);
$password=preg_replace('#<tr><td><FONT face=Verdana color="\#FFFFFF"><a href=[^>]*>[^<]*</a></FONT></td><td align=middle><FONT face=Verdana color="\#FFFFFF">([^<]*)<.*#','$1',$match);
$emails[]=array('username'=>$username,'password'=>$password);
}
// }
// { log into postfix mailadmin
$ch=curl_init($postfixmailadmin_url.'login.php');
curl_setopt($ch, CURLOPT_POST, true );
curl_setopt($ch, CURLOPT_POSTFIELDS, 'fUsername='.$postfixmailadmin_username.'&fPassword='.urlencode($postfixmailadmin_password).'&lang=en&submit=Login');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt($ch, CURLOPT_AUTOREFERER, true );
curl_setopt($ch, CURLOPT_COOKIEJAR, 'tmp/cookies.txt');
curl_exec($ch);
curl_close($ch);
// }
// { create domain
$ch=curl_init($postfixmailadmin_url.'create-domain.php');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'tmp/cookies.txt');
curl_setopt($ch, CURLOPT_POST, true );
curl_setopt($ch, CURLOPT_POSTFIELDS, 'fDomain='.$domain.'&fAliases=25&fMailboxes=25&submit=Add Domain');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
curl_exec($ch);
curl_close($ch);
// }
// { create email accounts
foreach($emails as $email){
$ch=curl_init($postfixmailadmin_url.'create-mailbox.php');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'tmp/cookies.txt');
curl_setopt($ch, CURLOPT_POST, true );
curl_setopt($ch, CURLOPT_POSTFIELDS, 'fDomain='.$domain.'&fUsername='.$email['username'].'&fPassword='.$email['password'].'&fPassword2='.$email['password'].'&fActive=on&fMail=on&submit=Add Mailbox');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
curl_exec($ch);
$numemails++;
echo $numemails.':'.$email['username'].'@'.$domain.' ';
curl_close($ch);
}
// }
flush();
ob_flush();
}
Make sure to up the timeout length of your PHP scripts – it took me about 10 minutes to transfer 1607 emails.
Also, be aware that this does not transfer the /contents/ of the email accounts – just recreates them on the other server – I don’t even want to touch that particular problem…