From 8b4e51370129b05817c56032555ebb2f5879758e Mon Sep 17 00:00:00 2001 From: David Goodwin Date: Sun, 8 Mar 2009 21:16:41 +0000 Subject: [PATCH] see https://sourceforge.net/tracker/index.php?func=detail&aid=2567466&group_id=191583&atid=937966 - allow adding of an alias even if a mailbox already exists (e.g. allowing you to do keep+forward) git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@572 a1433add-5e2c-0410-b055-b7f2511e0802 --- create-alias.php | 29 ++++++++--- delete.php | 124 ++++++++++++++++++++++++++++++++++------------ edit-alias.php | 14 ++++++ functions.inc.php | 88 +++++++++++++++++++++----------- list-virtual.php | 31 ++++++++++-- 5 files changed, 215 insertions(+), 71 deletions(-) diff --git a/create-alias.php b/create-alias.php index 6e2cd82b..f77a0767 100644 --- a/create-alias.php +++ b/create-alias.php @@ -117,13 +117,15 @@ if ($_SERVER['REQUEST_METHOD'] == "POST") $fAddress = "@" . escape_string ($_POST['fDomain']); } + $append_alias = false; + $result = db_query ("SELECT * FROM $table_alias WHERE address='$fAddress'"); - if ($result['rows'] == 1) { - $error = 1; + if ($result['rows'] == 1) + { + $append_alias = true; $tAddress = escape_string ($_POST['fAddress']); $tGoto = $fGoto; $tDomain = $fDomain; - $pCreate_alias_address_text = $PALANG['pCreate_alias_address_text_error2']; } if ($fActive == "on") { @@ -133,13 +135,29 @@ if ($_SERVER['REQUEST_METHOD'] == "POST") $sqlActive = db_get_boolean(False); } - if ($error != 1) { + $success = false; + /* Alias (or mailbox) already present, let's add the destination to that row */ + if ($append_alias) { + if (preg_match('/^\*@(.*)$/', $fGoto, $match)) { + $fGoto = "@" . $match[1]; + } + + $array = db_array ($result['result']); + + $values ['goto'] = $array['goto'] . ',' . $fGoto; + $result = db_update ($table_alias, "address = '$fAddress'", $values, array ('modified')); + $success = ($result == 1); + + } elseif ($error != 1) { if (preg_match('/^\*@(.*)$/', $fGoto, $match)) { $fGoto = "@" . $match[1]; } $result = db_query ("INSERT INTO $table_alias (address,goto,domain,created,modified,active) VALUES ('$fAddress','$fGoto','$fDomain',NOW(),NOW(),'$sqlActive')"); - if ($result['rows'] != 1) { + $success = ($result['rows'] == 1); + } + + if (! $success) { $tDomain = $fDomain; $tMessage = $PALANG['pCreate_alias_result_error'] . "
($fAddress -> $fGoto)
\n"; } @@ -149,7 +167,6 @@ if ($_SERVER['REQUEST_METHOD'] == "POST") $tDomain = $fDomain; $tMessage = $PALANG['pCreate_alias_result_success'] . "
($fAddress -> $fGoto)
\n"; } - } } include ("templates/header.php"); diff --git a/delete.php b/delete.php index 6340a105..ab7aee77 100644 --- a/delete.php +++ b/delete.php @@ -43,6 +43,57 @@ $fDomain = escape_string (safeget('domain')); $error=0; +/** + * delete_alias + * Action: Delete an alias + * @param String $alias- alias to delete. + * @param String $domain - domain of the alias + * @param boolean $force_delete - deletes the alias from the table if true, + * checks if the alias is real and act accordlying if false. + * Default is false. + * @return String username (e.g. foo@example.com) + */ +function delete_alias ($alias, $domain, $force_delete = false) +{ + global $table_alias, $table_mailbox; + $real_alias = true; + + if (! $force_delete) + { + $result = db_query ("SELECT 1 FROM $table_mailbox + WHERE username='$alias' AND domain='$domain'"); + if ($result['rows'] != 0) + { + /* If the alias is a real mailbox as well, remove all its real aliases and keep + * only the address */ + $real_alias = false; + } + } + + if ($force_delete or $real_alias) + { + $result = db_query ("DELETE FROM $table_alias WHERE address='$alias' AND domain='$domain'"); + } + else + { + $result = db_query ("UPDATE $table_alias SET goto='$alias',modified=NOW() + WHERE address='$alias' AND domain='$domain'"); + } + + if ($result['rows'] != 1) + { + $tMessage = $PALANG['pDelete_delete_error'] . "$alias (alias)!"; + + return false; + } + else + { + db_log ($SESSID_USERNAME, $fDomain, 'delete_alias', $fDelete); + } + + return true; +} + if ($fTable == "admin") { authentication_require_role('global-admin'); @@ -98,7 +149,7 @@ elseif ($fTable == "alias_domain") } } # ($fTable == "alias_domain") -elseif ($fTable == "alias" or $fTable == "mailbox") +elseif ($fTable == "mailbox") { if (!check_owner ($SESSID_USERNAME, $fDomain)) @@ -114,52 +165,61 @@ elseif ($fTable == "alias" or $fTable == "mailbox") else { if ($CONF['database_type'] == "pgsql") db_query('BEGIN'); - /* there may be no aliases to delete */ - $result = db_query("SELECT * FROM $table_alias WHERE address = '$fDelete' AND domain = '$fDomain'"); - if($result['rows'] == 1) { - $result = db_query ("DELETE FROM $table_alias WHERE address='$fDelete' AND domain='$fDomain'"); - db_log ($SESSID_USERNAME, $fDomain, 'delete_alias', $fDelete); - } - /* is there a mailbox? if do delete it from orbit; it's the only way to be sure */ - $result = db_query ("SELECT * FROM $table_mailbox WHERE username='$fDelete' AND domain='$fDomain'"); - if ($result['rows'] == 1) + $error = delete_alias ($fDelete, $fDomain, $force_delete = true) ? 0 : 1; + if (! $error) { - $result = db_query ("DELETE FROM $table_mailbox WHERE username='$fDelete' AND domain='$fDomain'"); - $postdel_res=mailbox_postdeletion($fDelete,$fDomain); - if ($result['rows'] != 1 || !$postdel_res) + /* is there a mailbox? if do delete it from orbit; it's the only way to be sure */ + $result = db_query ("SELECT * FROM $table_mailbox WHERE username='$fDelete' AND domain='$fDomain'"); + if ($result['rows'] == 1) { - $error = 1; - $tMessage = $PALANG['pDelete_delete_error'] . "$fDelete ("; - if ($result['rows']!=1) + $result = db_query ("DELETE FROM $table_mailbox WHERE username='$fDelete' AND domain='$fDomain'"); + $postdel_res=mailbox_postdeletion($fDelete,$fDomain); + if ($result['rows'] != 1 || !$postdel_res) { - $tMessage.='mailbox'; - if (!$postdel_res) $tMessage.=', '; + $error = 1; + $tMessage = $PALANG['pDelete_delete_error'] . "$fDelete ("; + if ($result['rows']!=1) + { + $tMessage.='mailbox'; + if (!$postdel_res) $tMessage.=', '; + } + if (!$postdel_res) + { + $tMessage.='post-deletion'; + } + $tMessage.=')'; } - if (!$postdel_res) - { - $tMessage.='post-deletion'; - } - $tMessage.=')'; + } + $result = db_query("SELECT * FROM $table_vacation WHERE email = '$fDelete' AND domain = '$fDomain'"); + if($result['rows'] == 1) { + db_query ("DELETE FROM $table_vacation WHERE email='$fDelete' AND domain='$fDomain'"); + db_query ("DELETE FROM $table_vacation_notification WHERE on_vacation ='$fDelete' "); /* should be caught by cascade, if PgSQL */ } } - $result = db_query("SELECT * FROM $table_vacation WHERE email = '$fDelete' AND domain = '$fDomain'"); - if($result['rows'] == 1) { - db_query ("DELETE FROM $table_vacation WHERE email='$fDelete' AND domain='$fDomain'"); - db_query ("DELETE FROM $table_vacation_notification WHERE on_vacation ='$fDelete' "); /* should be caught by cascade, if PgSQL */ + + if ($error != 1) + { + if ($CONF['database_type'] == "pgsql") db_query('COMMIT'); + header ("Location: list-virtual.php?domain=$fDomain"); + exit; + } else { + $tMessage = $PALANG['pDelete_delete_error'] . "$fDelete (physical mail)!"; + if ($CONF['database_type'] == "pgsql") db_query('ROLLBACK'); } - } + } # ($fTable == "mailbox") +} +elseif ($fTable == "alias") { + $error = delete_alias ($fDelete, $fDomain) ? 0 : 1; if ($error != 1) { - if ($CONF['database_type'] == "pgsql") db_query('COMMIT'); header ("Location: list-virtual.php?domain=$fDomain"); exit; } else { - $tMessage .= $PALANG['pDelete_delete_error'] . "$fDelete (physical mail)!"; - if ($CONF['database_type'] == "pgsql") db_query('ROLLBACK'); + $tMessage = $PALANG['pDelete_delete_error'] . "$fDelete (alias)!"; } -} +} else { flash_error($PALANG['invalid_parameter']); diff --git a/edit-alias.php b/edit-alias.php index 434592cf..a9a2e81f 100644 --- a/edit-alias.php +++ b/edit-alias.php @@ -46,6 +46,13 @@ if ($_SERVER['REQUEST_METHOD'] == "GET") { $row = db_array ($result['result']); $tGoto = $row['goto']; + + /* Has a mailbox as well? Remove the address from $tGoto in order to edit just the real aliases */ + $result = db_query ("SELECT * FROM $table_mailbox WHERE username='$fAddress' AND domain='$fDomain'"); + if ($result['rows'] == 1) + { + $tGoto = preg_replace ('/\s*,*\s*' . $fAddress . '\s*,*\s*/', '', $tGoto); + } } } else @@ -110,6 +117,13 @@ if ($_SERVER['REQUEST_METHOD'] == "POST") } } + $result = db_query ("SELECT * FROM $table_mailbox WHERE username='$fAddress' AND domain='$fDomain'"); + /* The alias has a real mailbox as well, prepend $goto with it */ + if ($result['rows'] == 1) + { + $goto = "$fAddress,$goto"; + } + if ($error != 1) { $result = db_query ("UPDATE $table_alias SET goto='$goto',modified=NOW() WHERE address='$fAddress' AND domain='$fDomain'"); diff --git a/functions.inc.php b/functions.inc.php index 6e4a337a..9c6f006c 100644 --- a/functions.inc.php +++ b/functions.inc.php @@ -431,18 +431,25 @@ function get_domain_properties ($domain) global $table_alias, $table_mailbox, $table_domain; $list = array (); - $result = db_query ("SELECT COUNT(*) FROM $table_alias WHERE domain='$domain'"); - $row = db_row ($result['result']); - $list['alias_count'] = $row[0]; + $result = db_query ("SELECT COUNT(*) FROM $table_alias + LEFT JOIN $table_mailbox ON $table_alias.address=$table_mailbox.username + WHERE ($table_alias.domain='$domain' AND $table_mailbox.maildir IS NULL) + OR + ($table_alias.domain='$domain' + AND $table_alias.goto LIKE '%,%' + AND $table_mailbox.maildir IS NOT NULL)"); + + $row = db_row ($result['result']); + $list['alias_count'] = $row[0]; $result = db_query ("SELECT COUNT(*) FROM $table_mailbox WHERE domain='$domain'"); $row = db_row ($result['result']); $list['mailbox_count'] = $row[0]; - $result = db_query ("SELECT SUM(quota) FROM $table_mailbox WHERE domain='$domain'"); - $row = db_row ($result['result']); - $list['quota_sum'] = $row[0]; - $list['alias_count'] = $list['alias_count'] - $list['mailbox_count']; + $result = db_query ("SELECT SUM(quota) FROM $table_mailbox WHERE domain='$domain'"); + $row = db_row ($result['result']); + $list['quota_sum'] = $row[0]; + $list['alias_count'] = $list['alias_count']; $list['alias_pgindex']=array (); $list['mbox_pgindex']=array (); @@ -455,24 +462,40 @@ function get_domain_properties ($domain) $idxlabel=""; $list['alias_pgindex_count'] = 0; - if ( $list['alias_count'] > $page_size ) - { - while ( $current < $list['alias_count'] ) - { - $limitSql=('pgsql'==$CONF['database_type']) ? "1 OFFSET $current" : "$current, 1"; - $query = "SELECT $table_alias.address FROM $table_alias LEFT JOIN $table_mailbox ON $table_alias.address=$table_mailbox.username WHERE $table_alias.domain='$domain' AND $table_mailbox.maildir IS NULL ORDER BY $table_alias.address LIMIT $limitSql"; - $result = db_query ("$query"); - $row = db_array ($result['result']); - $tmpstr = $row['address']; - //get first 2 chars - $idxlabel = $tmpstr[0] . $tmpstr[1] . "-"; - ($current + $page_size - 1 <= $list['alias_count']) ? $current = $current + $page_size - 1 : $current = $list['alias_count'] - 1; - $limitSql=('pgsql'==$CONF['database_type']) ? "1 OFFSET $current" : "$current, 1"; - $query = "SELECT $table_alias.address FROM $table_alias LEFT JOIN $table_mailbox ON $table_alias.address=$table_mailbox.username WHERE $table_alias.domain='$domain' AND $table_mailbox.maildir IS NULL ORDER BY $table_alias.address LIMIT $limitSql"; - $result = db_query ("$query"); - $row = db_array ($result['result']); - $tmpstr = $row['address']; - $idxlabel = $idxlabel . $tmpstr[0] . $tmpstr[1]; + if ( $list['alias_count'] > $page_size ) + { + while ( $current < $list['alias_count'] ) + { + $limitSql=('pgsql'==$CONF['database_type']) ? "1 OFFSET $current" : "$current, 1"; + $query = "SELECT $table_alias.address + FROM $table_alias + LEFT JOIN $table_mailbox ON $table_alias.address=$table_mailbox.username + WHERE ($table_alias.domain='$domain' AND $table_mailbox.maildir IS NULL) + OR + ($table_alias.domain='$domain' + AND $table_alias.goto LIKE '%,%' + AND $table_mailbox.maildir IS NOT NULL) + ORDER BY $table_alias.address LIMIT $limitSql"; + $result = db_query ("$query"); + $row = db_array ($result['result']); + $tmpstr = $row['address']; + //get first 2 chars + $idxlabel = $tmpstr[0] . $tmpstr[1] . "-"; + ($current + $page_size - 1 <= $list['alias_count']) ? $current = $current + $page_size - 1 : $current = $list['alias_count'] - 1; + $limitSql=('pgsql'==$CONF['database_type']) ? "1 OFFSET $current" : "$current, 1"; + $query = "SELECT $table_alias.address + FROM $table_alias + LEFT JOIN $table_mailbox ON $table_alias.address=$table_mailbox.username + WHERE ($table_alias.domain='$domain' AND $table_mailbox.maildir IS NULL) + OR + ($table_alias.domain='$domain' + AND $table_alias.goto LIKE '%,%' + AND $table_mailbox.maildir IS NOT NULL) + ORDER BY $table_alias.address LIMIT $limitSql"; + $result = db_query ("$query"); + $row = db_array ($result['result']); + $tmpstr = $row['address']; + $idxlabel = $idxlabel . $tmpstr[0] . $tmpstr[1]; $current = $current + 1; @@ -1103,11 +1126,16 @@ function generate_password () -// -// pacrypt -// Action: Encrypts password based on config settings -// Call: pacrypt (string cleartextpassword) -// +/** + * Encrypt a password, using the apparopriate hashing mechanism as defined in + * config.inc.php ($CONF['encrypt']). + * When wanting to compare one pw to another, it's necessary to provide the salt used - hence + * the second parameter ($pw_db), which is the existing hash from the DB. + * + * @param string $pw + * @param string $encrypted password + * @return string encrypted password. + */ function pacrypt ($pw, $pw_db="") { global $CONF; diff --git a/list-virtual.php b/list-virtual.php index ee4124be..329e040e 100644 --- a/list-virtual.php +++ b/list-virtual.php @@ -72,7 +72,6 @@ if (!check_owner(authentication_get_username(), $fDomain)) { exit(0); } - if (boolconf('alias_domain')) { # Alias-Domains # first try to get a list of other domains pointing @@ -118,10 +117,29 @@ if (boolconf('alias_domain')) { } } -$query = "SELECT $table_alias.address,$table_alias.goto,$table_alias.modified,$table_alias.active FROM $table_alias LEFT JOIN $table_mailbox ON $table_alias.address=$table_mailbox.username WHERE $table_alias.domain='$fDomain' AND $table_mailbox.maildir IS NULL ORDER BY $table_alias.address LIMIT $fDisplay, $page_size"; +$query = "SELECT $table_alias.address, + $table_alias.goto, + $table_alias.modified, + $table_alias.active + FROM $table_alias LEFT JOIN $table_mailbox ON $table_alias.address=$table_mailbox.username + WHERE ($table_alias.domain='$fDomain' AND $table_mailbox.maildir IS NULL) + OR + ($table_alias.domain='$fDomain' + AND $table_alias.goto LIKE '%,%' + AND $table_mailbox.maildir IS NOT NULL) + ORDER BY $table_alias.address LIMIT $fDisplay, $page_size"; + if ('pgsql'==$CONF['database_type']) { - $query = "SELECT address,goto,extract(epoch from modified) as modified,active FROM $table_alias WHERE domain='$fDomain' AND NOT EXISTS(SELECT 1 FROM $table_mailbox WHERE username=$table_alias.address) ORDER BY address LIMIT $page_size OFFSET $fDisplay"; + $query = "SELECT address, + goto, + modified, + active + FROM $table_alias WHERE domain='$fDomain' + AND NOT EXISTS(SELECT 1 FROM $table_mailbox + WHERE username=$table_alias.address + AND $table_alias.goto NOT LIKE '%,%') + ORDER BY address LIMIT $page_size OFFSET $fDisplay"; } $result = db_query ($query); if ($result['rows'] > 0) @@ -133,6 +151,13 @@ if ($result['rows'] > 0) $row['modified']=gmstrftime('%c %Z',$row['modified']); $row['active']=('t'==$row['active']) ? 1 : 0; } + + /* Has a real mailbox as well? Remove the address from $row['goto'] in order to edit just the real aliases */ + if (strstr ($row['goto'], ',') != FALSE) + { + $row['goto'] = preg_replace ('/\s*,*\s*' . $row['address'] . '\s*,*\s*/', '', $row['goto']); + } + $tAlias[] = $row; } }