<? /*
// File : virtualqmail.wcp.phps
// Purpose : virtualqmail user manipulation
// Author : Johan <hide@address.com>
// Comment : I use vpopmail commands to manage virtual domains/users
// Install : see Linux Qmail Toaster ( http://shupp.org/toaster )
*/
// Handle domains manipulation
if ($type == "domain") {
// présentement, sendmail accepte @host.domain.com, @domain.com si nohost est
// setté, @domainpointer.com redirige vers @domain.com (si le dns MX est
// setté), les sousdomaines sont ignorés.
// Create Domain :: expect *
if ($data['action'] == "create") {
// Check if it's a pointers / sub-domains, set them here
if ( $data['type'] == 'pointer' ) {
// :: point @domain-pointer.com to >> @main-domain.com
$dbp = mysql_query("SELECT DISTINCT domain FROM domains WHERE id='".$data['owner']."'");
$ddata = mysql_fetch_array($dbp);
exec($cfg['prog']['vaddaliasdomain']." ".$data['domain']." ".$ddata['domain']);
// Forget subdomain
/*
} elseif ( $data['type'] == 'subdomain' ) {
// :: point @host.domain.com to >> @domain.com
$dbp = mysql_query("SELECT DISTINCT host,domain FROM domains WHERE id='".$data['id']."'");
$ddata = mysql_fetch_array($dbp);
exec($cfg['prog']['vaddaliasdomain']." ".$ddata['host'].".".$ddata['domain']." ".$ddata['domain']);
*/
// It's a new domain
} elseif ( $data['type'] != 'subdomain' ) {
// if nohost create virtual domain : domain & virtual alias domain : host.domain
if ($data['nohost'] == "true") {
exec($cfg['prog']['vadddomain']." ".$data['domain']." ".$cfg['vqmail_postmaster_passwd']);
exec($cfg['prog']['vaddaliasdomain']." ".$data['host'].".".$data['domain']." ".$data['domain']);
} else {
// Create virtual domain : host.domain
exec($cfg['prog']['vadddomain']." ".$data['host'].".".$data['domain']." ".$cfg['vqmail_postmaster_passwd']);
}
// catch-all is set by default to : bounce-no-mailbox
// if there is aliases, include them
$data['aliases'] = trim($data['aliases']);
if (strstr($data['aliases']," ")) {
$aliases = explode(" ",$data['aliases']);
while (current($aliases)) {
if ($data['nohost'] == "true") {
exec($cfg['prog']['vaddaliasdomain']." ".current($aliases).".".$data['domain']." ".$data['domain']);
} else {
exec($cfg['prog']['vaddaliasdomain']." ".current($aliases).".".$data['domain']." ".$data['host'].".".$data['domain']);
}
next($aliases);
}
}
elseif ($data['aliases']) {
if ($data['nohost'] == "true") {
exec($cfg['prog']['vaddaliasdomain']." ".$data['aliases'].".".$data['domain']." ".$data['domain']);
} else {
exec($cfg['prog']['vaddaliasdomain']." ".$data['aliases'].".".$data['domain']." ".$data['host'].".".$data['domain']);
}
}
}
}
// Update Domain :: expect *
if ($data['action'] == "update") {
// Check if it's a pointers / sub-domains, set them here
if ( $data['type'] == 'pointer' ) {
if ($data['domain'] != $data['domain1']) {
// :: point @domain-pointer.com to >> @main-domain.com
// Change manualy 3 files ( $cfg['qmail_rpchosts'] $cfg['qmail_virtdomains'] $cfg['qmail_assign'] )
// because vdelaliasdomain dont currently exist and php vpopmail_del_alias_domain_ex too
// Change $cfg['qmail_rpchosts']
// Load current files
$sysfile['qmail_rpchosts'] = implode("",file($cfg['qmail_rpchosts']));
// Change domain
$sysfile['qmail_rpchosts'] = str_replace($data['domain1'], $data['domain'], $sysfile['qmail_rpchosts']);
// Write change
$fp = fopen($cfg['qmail_rpchosts'],"w+");
fwrite($fp,$sysfile['qmail_rpchosts']);
fclose($fp);
// Change $cfg['qmail_virtdomains']
// Load current files
$sysfile['qmail_virtdomains'] = implode("",file($cfg['qmail_virtdomains']));
// Change domain
$sysfile['qmail_virtdomains'] = str_replace($data['domain1'], $data['domain'], $sysfile['qmail_virtdomains']);
// Write change
$fp = fopen($cfg['qmail_virtdomains'],"w+");
fwrite($fp,$sysfile['qmail_virtdomains']);
fclose($fp);
// Change $cfg['qmail_assign']
// Load current files
$sysfile['qmail_assign'] = implode("",file($cfg['qmail_assign']));
// Change domain
$sysfile['qmail_assign'] = str_replace($data['domain1'], $data['domain'], $sysfile['qmail_assign']);
// Write change
$fp = fopen($cfg['qmail_assign'],"w+");
fwrite($fp,$sysfile['qmail_assign']);
fclose($fp);
}
// Forget subdomain
/*
} elseif ( $data['type'] == 'subdomain' ) {
// :: point @host.domain.com to >> @domain.com
*/
// It's a domain change domain
} elseif ( $data['type'] != 'subdomain' ) {
if ($data['domain'] != $data['domain1']) {
// Create a new domain
exec($cfg['prog']['vadddomain']." ".$data['domain']." ".crypt($data['password'],$cfg['key']));
// Add users
$dbp = mysql_query("SELECT DISTINCT u.aliases,u.username FROM users u, domains d WHERE d.id='".$data['id']."' AND d.id=u.id");
while ($ddata = mysql_fetch_array($dbp)) {
// Add every users to that domain
exec($cfg['prog']['vadduser']." ".$ddata['username']."@".$data['domain']." norealpass");
// Copy old user directory to the new one
exec($cfg['prog']['rm']." -rf ".$cfg['vqmail_domains']."/".$data['domain']."/".$ddata['username']);
exec($cfg['prog']['cp']." -Rf ".$cfg['vqmail_domains']."/".$data['domain1']."/".$ddata['username']." ".$cfg['vqmail_domains']."/".$data['domain']."/");
}
// Copy password file (and delete vpasswd.cdb to be able to keep old password)
exec($cfg['prog']['rm']." -f ".$cfg['vqmail_domains']."/".$data['domain']."/vpasswd");
exec($cfg['prog']['rm']." -f ".$cfg['vqmail_domains']."/".$data['domain']."/vpasswd.cdb");
// Change new directory into vpasswd file
exec($cfg['prog']['sed']." -e \"s/".
str_replace("/", "\/", quotemeta($cfg['vqmail_domains']."/".$data['domain1']))."/".
str_replace("/", "\/", quotemeta($cfg['vqmail_domains']."/".$data['domain']))."/g\" ".
$cfg['vqmail_domains']."/".$data['domain1']."/vpasswd > ".
$cfg['vqmail_domains']."/".$data['domain']."/vpasswd");
// change directory owner
exec($cfg['prog']['chown']." -R ".$cfg['vqmail_user'].":".$cfg['vqmail_group']." " .$cfg['vqmail_domains']."/".$data['domain']);
// Delete old domain
exec($cfg['prog']['vdeldomain']." ".$data['domain1']);
}
}
}
// Remove Domain :: expect username
if ($data['action'] == "remove") {
// Delete domain first then check if pointers / sub-domains exists then delete them.
exec($cfg['prog']['vdeldomain']." ".$data['domain']);
// Then delete
$dbp = mysql_query("SELECT * FROM domains WHERE owner='".$data['id']."'");
if ( mysql_num_rows($dbp) != 0 ){
// Change manualy 3 files ( $cfg['qmail_rpchosts'] $cfg['qmail_virtdomains'] $cfg['qmail_assign'] )
// because vdelaliasdomain dont currently exist and php vpopmail_del_alias_domain_ex too
// Load current files
$sysfile['qmail_rpchosts'] = file($cfg['qmail_rpchosts']);
$sysfile['qmail_virtdomains'] = file($cfg['qmail_virtdomains']);
$sysfile['qmail_assign'] = file($cfg['qmail_assign']);
while ($ddata = mysql_fetch_array($dbp)) {
// Clear old newfile
if ( isset($newfile) ) {
unset($newfile);
}
// Set newfiles as array
$newfile['qmail_rpchosts'] = array();
$newfile['qmail_virtdomains'] = array();
$newfile['qmail_assign'] = array();
// Delete ligne in $cfg['qmail_rpchosts']
while ( list($line_num, $line) = each($sysfile['qmail_rpchosts'])) {
if (( substr_count($line, $ddata['domain']) == 0 ) AND ( in_array($line, $newfile['qmail_rpchosts']) == FALSE ))
{
array_push($newfile['qmail_rpchosts'], $line);
}
}
$sysfile['qmail_rpchosts'] = $newfile['qmail_rpchosts'];
// Delete ligne in $cfg['qmail_virtdomains']
while ( list( $line_num, $line ) = each( $sysfile['qmail_virtdomains'] ) ) {
if (( substr_count($line, $ddata['domain']) == 0 ) AND ( in_array($line, $newfile['qmail_virtdomains']) == FALSE ))
{
array_push($newfile['qmail_virtdomains'], $line);
}
}
$sysfile['qmail_virtdomains'] = $newfile['qmail_virtdomains'];
// Delete ligne in $cfg['qmail_assign']
while ( list( $line_num, $line ) = each( $sysfile['qmail_assign'] ) ) {
if (( substr_count($line, $ddata['domain']) == 0 ) AND ( in_array($line, $newfile['qmail_assign']) == FALSE ))
{
array_push($newfile['qmail_assign'], $line);
}
}
$sysfile['qmail_assign'] = $newfile['qmail_assign'];
}
// Write $cfg['qmail_rpchosts'] change
$sysfile['qmail_rpchosts'] = join('', $sysfile['qmail_rpchosts']);
$fp = fopen($cfg['qmail_rpchosts'],"w+");
fwrite($fp,$sysfile['qmail_rpchosts']);
fclose($fp);
// Write $cfg['qmail_virtdomains'] change
$sysfile['qmail_virtdomains'] = join('', $sysfile['qmail_virtdomains']);
$fp = fopen($cfg['qmail_virtdomains'],"w+");
fwrite($fp,$sysfile['qmail_virtdomains']);
fclose($fp);
// Write $cfg['qmail_assign'] change
$sysfile['qmail_assign'] = join('', $sysfile['qmail_assign']);
$fp = fopen($cfg['qmail_assign'],"w+");
fwrite($fp,$sysfile['qmail_assign']);
fclose($fp);
}
}
}
// Handle user manipulation
if ($type == "user") {
// Create User :: expect *
if ($data['action'] == "create") {
// Get domain name
$dbp = mysql_query("SELECT DISTINCT domain FROM domains WHERE id='".$data['id']."'");
$ddata = mysql_fetch_array($dbp);
// add vpopmail user
exec($cfg['prog']['vadduser']." ".$data['username']."@".$ddata['domain']." ".escapeshellarg($data['password']));
/*
// Does not exist for user creation
// Set Catch-All
if ($data['catchall'] == TRUE) {
$fp = fopen($cfg['vqmail_domains']."/".$ddata['domain']."/.qmail-default","w+");
fwrite($fp,"| ".$cfg['prog']['vdelivermail']." '' ".$data['username']);
fclose($fp);
// Set the write owner
exec($cfg['prog']['chown']." ".$cfg['vqmail_user'].":".$cfg['vqmail_group'].
" ".$cfg['vqmail_domains']."/".$ddata['domain']."/.qmail-default");
}
*/
// Set aliases
$linkfile['aliases'] = $cfg['vqmail_domains']."/".$ddata['domain']."/.qmail-";
$data['aliases'] = trim($data['aliases']);
if (strstr($data['aliases']," ")) {
$aliases = explode(" ",$data['aliases']);
while (current($aliases)) {
$realfile = $linkfile['aliases'].str_replace(".",":",current($aliases));
$fp = fopen($realfile,"w+");
fwrite($fp,$data['username']."@".$ddata['domain']);
fclose($fp);
// Set the write owner
exec($cfg['prog']['chown']." ".$cfg['vqmail_user'].":".$cfg['vqmail_group'].
" ".$realfile);
next($aliases);
}
}
elseif ($data['aliases']) {
// Create if it's a new aliases
$realfile = $linkfile['aliases'].str_replace(".",":",$data['aliases']);
$fp = fopen($realfile,"w+");
fwrite($fp,$data['username']."@".$ddata['domain']);
fclose($fp);
// Set the write owner
exec($cfg['prog']['chown']." ".$cfg['vqmail_user'].":".$cfg['vqmail_group'].
" ".$realfile);
}
}
// Update User :: expect *
if ($data['action'] == "update") {
// Get domain name
$dbp = mysql_query("SELECT DISTINCT domain, domain1 FROM domains WHERE id='".$data['id']."'");
$ddata = mysql_fetch_array($dbp);
if ($data['username'] != $data['username1']) {
// Create a new user
exec($cfg['prog']['vadduser']." ".$data['username']."@".$ddata['domain']." ".escapeshellarg($data['password']));
// Delete his directory
exec($cfg['prog']['rm']." -rf ".$cfg['vqmail_domains']."/".$ddata['domain']."/".$data['username']);
// Copy the old directory
exec($cfg['prog']['cp']." -R ".$cfg['vqmail_domains']."/".$ddata['domain']."/".$data['username1']." ".
$cfg['vqmail_domains']."/".$ddata['domain']."/".$data['username']);
// change directory owner
exec($cfg['prog']['chown']." -R ".$cfg['vqmail_user'].":".$cfg['vqmail_group']." " .$cfg['vqmail_domains']."/".$ddata['domain']."/".$data['username']);
// Delete old user
exec($cfg['prog']['vdeluser']." ".$data['username1']."@".$ddata['domain']);
// Move aliases file
// to air and decrease lines code number this fonction is done in 2 times ( one here and the other below )
if ( file_exists($cfg['vqmail_domains']."/".$ddata['domain']."/.qmail-".$data['username1']) ) {
exec($cfg['prog']['mv']." ".$cfg['vqmail_domains']."/".$ddata['domain']."/.qmail-".$data['username1'].
" ".$cfg['vqmail_domains']."/".$ddata['domain']."/.qmail-".$data['username']);
}
}
// Set Catch-All
$linkfile['catchall'] = $cfg['vqmail_domains']."/".$ddata['domain']."/.qmail-default";
if ( $data['catchall'] == "true" ) {
$fp = fopen($linkfile['catchall'],"w+");
fwrite($fp,"| ".$cfg['prog']['vdelivermail']." '' ".$data['username']."@".$ddata['domain']);
fclose($fp);
// Set the write owner
} else {
// Check if a catchall exist does not anymore to that domain
$dbp = mysql_query("SELECT username FROM users WHERE catchall = 'true' and id = '".$data['id']."'");
$udata = mysql_fetch_array($dbp);
if ( $udata['username'] != $data['username'] ) {
$fp = fopen($linkfile['catchall'],"w+");
fwrite($fp,"| ".$cfg['prog']['vdelivermail']." '' bounce-no-mailbox");
fclose($fp);
}
}
// Set the write owner
exec($cfg['prog']['chown']." ".$cfg['vqmail_user'].":".$cfg['vqmail_group']." ".$linkfile['catchall']);
// Set aliases
$linkfile['aliases_dir'] = $cfg['vqmail_domains']."/".$ddata['domain'];
$linkfile['aliases'] = $linkfile['aliases_dir']."/.qmail-";
// Set current aliases
// Find old aliases
$localaliases = array();
if ($dir = @opendir($linkfile['aliases_dir'])) {
while($file = readdir($dir)) {
// is it an alias file ?
if ( substr_count($file, ".qmail-") )
{
// does it contain the current username ?
$realfile = $linkfile['aliases_dir']."/".$file;
if ( $data['username']."@".$ddata['domain'] == fread(fopen($realfile, "r"), filesize($realfile)) )
{
// Add it to the list
array_push($localaliases, $file);
}
}
}
closedir($dir);
}
// Get new aliases and remove old one
$data['aliases'] = trim($data['aliases']);
if (strstr($data['aliases']," ")) {
$aliases = explode(" ",$data['aliases']);
// Find old aliases
while (current($localaliases)) {
$tmp = false;
// If no existe remove it
while (current($aliases)) {
// We know that ".qmail-" is 7 char.
if ( current($aliases) == str_replace(":",".",substr(current($localaliases),7))) {
$tmp = true;
break;
}
next($aliases);
}
if ($tmp == false) {
unlink($linkfile['aliases_dir']."/".current($localaliases));
}
next($localaliases);
}
// Find new aliases
while (current($aliases)) {
$realfile = $linkfile['aliases'].str_replace(".",":",current($aliases));
if ( file_exists($realfile) ) {
$sysfile['aliases'] = implode("",file($realfile));
} else {
$sysfile['aliases'] = "";
}
$newfile['aliases'] = $data['username']."@".$ddata['domain'];
// Write it
if ($newfile['aliases'] != $sysfile['aliases']) {
$fp = fopen($realfile,"w+");
fwrite($fp,$newfile['aliases']);
fclose($fp);
// Set the write owner
exec($cfg['prog']['chown']." ".$cfg['vqmail_user'].":".$cfg['vqmail_group'].
" ".$realfile);
}
next($aliases);
}
}
elseif ($data['aliases']) {
// Find old aliases
while (current($localaliases)) {
// If no existe remove it (we know that ".qmail-" is 7 char.)
if ( $data['aliases'] != str_replace(":",".",substr(current($localaliases),7))) {
unlink($linkfile['aliases_dir']."/".current($localaliases));
}
next($localaliases);
}
// Create if it's a new aliases
$realfile = $linkfile['aliases'].str_replace(".",":",$data['aliases']);
if ( file_exists($realfile) ) {
$sysfile['aliases'] = implode("",file($realfile));
} else {
$sysfile['aliases'] = "";
}
$newfile['aliases'] = $data['username']."@".$ddata['domain'];
// Write it
if ($newfile['aliases'] != $sysfile['aliases']) {
$fp = fopen($realfile,"w+");
fwrite($fp,$newfile['aliases']);
fclose($fp);
// Set the write owner
exec($cfg['prog']['chown']." ".$cfg['vqmail_user'].":".$cfg['vqmail_group'].
" ".$realfile);
}
}
// Set forward
$linkfile['forward'] = $cfg['vqmail_domains']."/".$ddata['domain']."/".$data['username']."/.qmail";
// Load current files
if ( file_exists($linkfile['forward']) ) {
$sysfile['forward'] = implode("",file($linkfile['forward']));
} else {
$sysfile['forward'] = "";
}
// Get information
$data['forward'] = trim($data['forward']);
if (strstr($data['forward']," ")) {
$forward = explode(" ",$data['forward']);
while (current($forward)) {
$newfile['forward'] .= current($forward)."\n";
next($forward);
}
}
elseif ($data['forward']) {
$newfile['forward'] .= $data['forward']."\n";
}
// save into forward file or unlink it if no forward
if ( empty($newfile['forward']) ) {
if ( is_file($linkfile['forward']) ) {
unlink($linkfile['forward']);
}
}
elseif ($newfile['forward'] != $sysfile['forward']) {
$fp = fopen($linkfile['forward'],"w+");
fwrite($fp,$newfile['forward']);
fclose($fp);
// Set the write owner
exec($cfg['prog']['chown']." ".$cfg['vqmail_user'].":".$cfg['vqmail_group']." ".$linkfile['forward']);
}
// Set autoreply
$linkfile['autorespond_userdir'] = $cfg['vqmail_domains']."/".$ddata['domain']."/".$data['username'];
$linkfile['autorespond_qmail'] = $linkfile['autorespond_userdir']."/.qmail";
$linkfile['autorespond_dir'] = $linkfile['autorespond_userdir']."/vacation";
$linkfile['autorespond_maildir'] = $linkfile['autorespond_userdir']."/Maildir";
$linkfile['autorespond_msg'] = $linkfile['autorespond_dir']."/message";
// Handle autoreply
if ($data['autoreply']) {
// Create vacation directory if not exist
if ( !is_dir($linkfile['autorespond_dir']) ) {
mkdir ($linkfile['autorespond_dir'], 0700);
}
// Create/change message
$newfile['msg'] = "From: ".$data['username']."@".$ddata['domain']."\n\n";
$newfile['msg'] .= "Subject: "."Re: Autoreply"."\n\n";
$newfile['msg'] .= $data['autoreply'];
// write message
$fp = fopen($linkfile['autorespond_msg'],"w+");
fwrite($fp,$newfile['msg'],10240); // limit autoreply to 10k
fclose($fp);
// Change .qmail file
$tmptxt = "| ".$cfg['prog']['autorespond']." 86400 3 ".$linkfile['autorespond_msg'].
" ".$linkfile['autorespond_dir']." \n".$linkfile['autorespond_maildir'];
// Set newfiles as array
$newfile['qmail'] = array();
if ( is_file($linkfile['qmail']) ) {
// Load current files
$sysfile['qmail'] = file($linkfile['autorespond_qmail']);
// Delete autorespond line
while ( list($line_num, $line) = each($sysfile['qmail'])) {
if (( substr_count($line, $cfg['prog']['autorespond']) == 0 ))
{
array_push($newfile['qmail'], $line);
}
}
}
// add tmptxt to .qmail
array_push($newfile['qmail'],$tmptxt);
// Write change
$newfile['qmail'] = join('', $newfile['qmail']);
// save into file or unlink it if no noting is set
if ( empty($newfile['qmail']) ) {
if ( is_file($linkfile['qmail']) ) {
unlink($linkfile['qmail']);
}
}
elseif ($newfile['qmail'] != $sysfile['qmail']) {
$fp = fopen($linkfile['autorespond_qmail'],"w+");
fwrite($fp,$newfile['qmail']);
fclose($fp);
}
// Set the write owner
exec($cfg['prog']['chown']." -R ".$cfg['vqmail_user'].":".$cfg['vqmail_group'].
" ".$linkfile['autorespond_userdir']);
} else {
// Create vacation directory if exist
if ( is_dir($linkfile['autorespond_dir']) ) {
exec($cfg['prog']['rm']." -rf ".$linkfile['autorespond_dir']);
}
if ( is_file($linkfile['autorespond_qmail'])) {
// Load current files
$sysfile['qmail'] = file($linkfile['autorespond_qmail']);
// Set newfiles as array
$newfile['qmail'] = array();
// Delete ligne
while ( list($line_num, $line) = each($sysfile['qmail'])) {
if (( substr_count($line, $cfg['prog']['autorespond']) == 0 )) {
array_push($newfile['qmail'], $line);
}
}
// Write change
$newfile['qmail'] = join('', $newfile['qmail']);
if ($newfile['qmail'] != $sysfile['qmail']) {
$fp = fopen($linkfile['autorespond_qmail'],"w+");
fwrite($fp,$newfile['qmail']);
fclose($fp);
// Set the write owner
exec($cfg['prog']['chown']." ".$cfg['vqmail_user'].":".$cfg['vqmail_group'].
" ".$linkfile['autorespond_qmail']);
}
}
}
}
// Remove User :: expect username
if ($data['action'] == "remove") {
// Get domain name
$dbp = mysql_query("SELECT DISTINCT domain FROM domains WHERE id='".$data['id']."'");
$ddata = mysql_fetch_array($dbp);
// remove vpopmail user
exec($cfg['prog']['vdeluser']." ".$data['username']."@".$ddata['domain']);
// Remove Catch-All
// Check if a catchall exist does not anymore to that domain
$dbp = mysql_query("SELECT username FROM users WHERE catchall = 'true' and id = '".$data['id']."'");
$udata = mysql_fetch_array($dbp);
if ( $udata['username'] == $data['username'] ) {
$fp = fopen($cfg['vqmail_domains']."/".$ddata['domain']."/.qmail-default","w+");
fwrite($fp,"| ".$cfg['prog']['vdelivermail']." '' bounce-no-mailbox");
fclose($fp);
// Set the write owner
exec($cfg['prog']['chown']." ".$cfg['vqmail_user'].":".$cfg['vqmail_group'].
" ".$cfg['vqmail_domains']."/".$ddata['domain']."/.qmail-default");
}
// Remove aliases file
if ($dir = @opendir($cfg['vqmail_domains']."/".$ddata['domain'])) {
while($file = readdir($dir)) {
// is it an alias file ?
if ( substr_count($file, ".qmail-") )
{
// does it contain the current username ?
$realfile = $cfg['vqmail_domains']."/".$ddata['domain']."/".$file;
if ( $data['username']."@".$ddata['domain'] == fread(fopen($realfile, "r"), filesize($realfile)) )
{
// Add it to the list
unlink($realfile);
}
}
}
closedir($dir);
}
}
}
?>