'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'access_denied' ); return false; } $local_dest = strtolower(trim($_data['local_dest'])); $bcc_dest = $_data['bcc_dest']; $active = intval($_data['active']); $type = $_data['type']; if ($type != 'sender' && $type != 'rcpt') { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'invalid_bcc_map_type' ); return false; } if (empty($bcc_dest)) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'bcc_empty' ); return false; } if (is_valid_domain_name($local_dest)) { if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $local_dest)) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'access_denied' ); return false; } $domain = idn_to_ascii($local_dest); $local_dest_sane = '@' . idn_to_ascii($local_dest); } elseif (filter_var($local_dest, FILTER_VALIDATE_EMAIL)) { if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $local_dest)) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'access_denied' ); return false; } $domain = mailbox('get', 'mailbox_details', $local_dest)['domain']; if (empty($domain)) { return false; } $local_dest_sane = $local_dest; } else { return false; } if (!filter_var($bcc_dest, FILTER_VALIDATE_EMAIL)) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'bcc_must_be_email' ); return false; } try { $stmt = $pdo->prepare("SELECT `id` FROM `bcc_maps` WHERE `local_dest` = :local_dest AND `type` = :type"); $stmt->execute(array(':local_dest' => $local_dest_sane, ':type' => $type)); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); } catch(PDOException $e) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('mysql_error', $e) ); return false; } if ($num_results != 0) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('bcc_exists', htmlspecialchars($local_dest_sane), $type) ); return false; } try { $stmt = $pdo->prepare("INSERT INTO `bcc_maps` (`local_dest`, `bcc_dest`, `domain`, `active`, `type`) VALUES (:local_dest, :bcc_dest, :domain, :active, :type)"); $stmt->execute(array( ':local_dest' => $local_dest_sane, ':bcc_dest' => $bcc_dest, ':domain' => $domain, ':active' => $active, ':type' => $type )); } catch (PDOException $e) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('mysql_error', $e) ); return false; } $_SESSION['return'] = array( 'type' => 'success', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'bcc_saved' ); break; case 'edit': if (!isset($_SESSION['acl']['bcc_maps']) || $_SESSION['acl']['bcc_maps'] != "1" ) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'access_denied' ); return false; } $ids = (array)$_data['id']; foreach ($ids as $id) { $is_now = bcc('details', $id); if (!empty($is_now)) { $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int']; $bcc_dest = (!empty($_data['bcc_dest'])) ? $_data['bcc_dest'] : $is_now['bcc_dest']; $local_dest = $is_now['local_dest']; $type = (!empty($_data['type'])) ? $_data['type'] : $is_now['type']; } else { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'access_denied' ); return false; } $active = intval($_data['active']); if (!filter_var($bcc_dest, FILTER_VALIDATE_EMAIL)) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'bcc_must_be_email' ); return false; } if (empty($bcc_dest)) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'bcc_empty' ); return false; } try { $stmt = $pdo->prepare("SELECT `id` FROM `bcc_maps` WHERE `local_dest` = :local_dest AND `type` = :type"); $stmt->execute(array(':local_dest' => $local_dest, ':type' => $type)); $id_now = $stmt->fetch(PDO::FETCH_ASSOC)['id']; } catch(PDOException $e) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('mysql_error', $e) ); return false; } if (isset($id_now) && $id_now != $id) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('bcc_exists', htmlspecialchars($local_dest), $type) ); return false; } try { $stmt = $pdo->prepare("UPDATE `bcc_maps` SET `bcc_dest` = :bcc_dest, `active` = :active, `type` = :type WHERE `id`= :id"); $stmt->execute(array( ':bcc_dest' => $bcc_dest, ':active' => $active, ':type' => $type, ':id' => $id )); } catch (PDOException $e) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('mysql_error', $e) ); return false; } } $_SESSION['return'] = array( 'type' => 'success', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'bcc_edited' ); break; case 'details': $bccdata = array(); $id = intval($_data); try { $stmt = $pdo->prepare("SELECT `id`, `local_dest`, `bcc_dest`, `active` AS `active_int`, CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`, `type`, `created`, `domain`, `modified` FROM `bcc_maps` WHERE `id` = :id"); $stmt->execute(array(':id' => $id)); $bccdata = $stmt->fetch(PDO::FETCH_ASSOC); } catch(PDOException $e) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('mysql_error', $e) ); return false; } if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $bccdata['domain'])) { $bccdata = null; return false; } return $bccdata; break; case 'get': $bccdata = array(); $all_items = array(); $id = intval($_data); try { $stmt = $pdo->query("SELECT `id`, `domain` FROM `bcc_maps`"); $all_items = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch(PDOException $e) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('mysql_error', $e) ); return false; } foreach ($all_items as $i) { if (hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $i['domain'])) { $bccdata[] = $i['id']; } } $all_items = null; return $bccdata; break; case 'delete': $ids = (array)$_data['id']; foreach ($ids as $id) { if (!is_numeric($id)) { return false; } try { $stmt = $pdo->prepare("SELECT `domain` FROM `bcc_maps` WHERE id = :id"); $stmt->execute(array(':id' => $id)); $domain = $stmt->fetch(PDO::FETCH_ASSOC)['domain']; if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'access_denied' ); return false; } $stmt = $pdo->prepare("DELETE FROM `bcc_maps` WHERE `id`= :id"); $stmt->execute(array(':id' => $id)); } catch (PDOException $e) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('mysql_error', $e) ); return false; } } $_SESSION['return'] = array( 'type' => 'success', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('bcc_deleted', implode(', ', $ids)) ); return true; break; } } function recipient_map($_action, $_data = null, $attr = null) { global $pdo; global $lang; if ($_SESSION['mailcow_cc_role'] != "admin") { return false; } switch ($_action) { case 'add': $old_dest = strtolower(trim($_data['recipient_map_old'])); if (substr($old_dest, 0, 1) == '@') { $old_dest = substr($old_dest, 1); } $new_dest = strtolower(trim($_data['recipient_map_new'])); $active = intval($_data['active']); if (is_valid_domain_name($old_dest)) { $old_dest_sane = '@' . idn_to_ascii($old_dest); } elseif (filter_var($old_dest, FILTER_VALIDATE_EMAIL)) { $old_dest_sane = $old_dest; } else { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('invalid_recipient_map_old', htmlspecialchars($old_dest)) ); return false; } if (!filter_var($new_dest, FILTER_VALIDATE_EMAIL)) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('invalid_recipient_map_new', htmlspecialchars($new_dest)) ); return false; } $rmaps = recipient_map('get'); foreach ($rmaps as $rmap) { $old_dests_existing[] = recipient_map('details', $rmap)['recipient_map_old']; } if (in_array($old_dest_sane, $old_dests_existing)) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('recipient_map_entry_exists', htmlspecialchars($old_dest)) ); return false; } try { $stmt = $pdo->prepare("INSERT INTO `recipient_maps` (`old_dest`, `new_dest`, `active`) VALUES (:old_dest, :new_dest, :active)"); $stmt->execute(array( ':old_dest' => $old_dest_sane, ':new_dest' => $new_dest, ':active' => $active )); } catch (PDOException $e) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('mysql_error', $e) ); return false; } $_SESSION['return'] = array( 'type' => 'success', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('recipient_map_entry_saved', htmlspecialchars($old_dest_sane)) ); break; case 'edit': $ids = (array)$_data['id']; foreach ($ids as $id) { $is_now = recipient_map('details', $id); if (!empty($is_now)) { $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int']; $new_dest = (!empty($_data['recipient_map_new'])) ? $_data['recipient_map_new'] : $is_now['recipient_map_new']; $old_dest = (!empty($_data['recipient_map_old'])) ? $_data['recipient_map_old'] : $is_now['recipient_map_old']; if (substr($old_dest, 0, 1) == '@') { $old_dest = substr($old_dest, 1); } } else { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => 'access_denied' ); return false; } if (is_valid_domain_name($old_dest)) { $old_dest_sane = '@' . idn_to_ascii($old_dest); } elseif (filter_var($old_dest, FILTER_VALIDATE_EMAIL)) { $old_dest_sane = $old_dest; } else { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('invalid_recipient_map_old', htmlspecialchars($old_dest)) ); return false; } $active = intval($_data['active']); if (!filter_var($new_dest, FILTER_VALIDATE_EMAIL)) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('invalid_recipient_map_new', htmlspecialchars($new_dest)) ); return false; } $rmaps = recipient_map('get'); foreach ($rmaps as $rmap) { $old_dests_existing[] = recipient_map('details', $rmap)['recipient_map_old']; } if (in_array($old_dest_sane, $old_dests_existing) && recipient_map('details', $id)['recipient_map_old'] != $old_dest_sane) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('recipient_map_entry_exists', htmlspecialchars($old_dest_sane)) ); return false; } try { $stmt = $pdo->prepare("UPDATE `recipient_maps` SET `old_dest` = :old_dest, `new_dest` = :new_dest, `active` = :active WHERE `id`= :id"); $stmt->execute(array( ':old_dest' => $old_dest_sane, ':new_dest' => $new_dest, ':active' => $active, ':id' => $id )); } catch (PDOException $e) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('mysql_error', $e) ); return false; } } $_SESSION['return'] = array( 'type' => 'success', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('recipient_map_entry_saved', htmlspecialchars($old_dest)) ); break; case 'details': $mapdata = array(); $id = intval($_data); try { $stmt = $pdo->prepare("SELECT `id`, `old_dest` AS `recipient_map_old`, `new_dest` AS `recipient_map_new`, `active` AS `active_int`, CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`, `created`, `modified` FROM `recipient_maps` WHERE `id` = :id"); $stmt->execute(array(':id' => $id)); $mapdata = $stmt->fetch(PDO::FETCH_ASSOC); } catch(PDOException $e) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('mysql_error', $e) ); return false; } return $mapdata; break; case 'get': $mapdata = array(); $all_items = array(); $id = intval($_data); try { $stmt = $pdo->query("SELECT `id` FROM `recipient_maps`"); $all_items = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch(PDOException $e) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('mysql_error', $e) ); return false; } foreach ($all_items as $i) { $mapdata[] = $i['id']; } $all_items = null; return $mapdata; break; case 'delete': $ids = (array)$_data['id']; foreach ($ids as $id) { if (!is_numeric($id)) { return false; } try { $stmt = $pdo->prepare("DELETE FROM `recipient_maps` WHERE `id`= :id"); $stmt->execute(array(':id' => $id)); } catch (PDOException $e) { $_SESSION['return'] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $_action, $_data, $_attr), 'msg' => array('mysql_error', $e) ); return false; } } $_SESSION['return'] = array( 'type' => 'success', 'msg' => array('recipient_map_entry_deleted', htmlspecialchars($old_dest)) ); return true; break; } }